[haiku-commits] BRANCH axeld-github.trim [1c6edcd] src/add-ons/kernel/file_systems/bfs src/bin headers/private/fs_shell headers/os/drivers build/jam

  • From: axeld-github.trim <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 5 Aug 2013 00:30:33 +0200 (CEST)

added 3 changesets to branch 'refs/remotes/axeld-github/trim'
old head: 0000000000000000000000000000000000000000
new head: 1c6edcdcdc8ab0b4a9ed79d2c0464e73ac8e0745
overview: https://github.com/axeld/haiku/compare/1c6edcd

----------------------------------------------------------------------------

78f3143: Added B_TRIM_DEVICE ioctl.

be4f73b: Added fstrim command.
  
  Later, there should be a service that runs this from time to time for all
  devices that support it.

1c6edcd: Added B_TRIM_DEVICE support to BFS.
  
  * It currently ignores the offset/size, though, and always trims everything.
  * Now only SCSI support is missing.

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

9 files changed, 213 insertions(+), 12 deletions(-)
build/jam/HaikuImage                             |  6 +-
headers/os/drivers/Drivers.h                     | 11 ++-
headers/private/fs_shell/fssh_api_wrapper.h      |  5 ++
headers/private/fs_shell/fssh_drivers.h          | 21 +++--
.../kernel/file_systems/bfs/BlockAllocator.cpp   | 78 ++++++++++++++++++-
.../kernel/file_systems/bfs/BlockAllocator.h     |  6 +-
.../kernel/file_systems/bfs/kernel_interface.cpp | 16 +++-
src/bin/Jamfile                                  |  1 +
src/bin/fstrim.cpp                               | 81 ++++++++++++++++++++

############################################################################

Commit:      78f3143ad9c76dda9305ce7fa5dcb339dbdb550d
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Sun Aug  4 21:19:43 2013 UTC

Added B_TRIM_DEVICE ioctl.

----------------------------------------------------------------------------

diff --git a/headers/os/drivers/Drivers.h b/headers/os/drivers/Drivers.h
index 3484dbf..ff4e1e0 100644
--- a/headers/os/drivers/Drivers.h
+++ b/headers/os/drivers/Drivers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2011, Haiku Inc. All Rights Reserved.
+ * Copyright 2002-2013, Haiku Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef _DRIVERS_DRIVERS_H
@@ -106,6 +106,7 @@ enum {
        B_GET_ICON_NAME,                                /* get an icon name 
identifier */
        B_GET_VECTOR_ICON,                              /* retrieves the 
device's vector icon */
        B_GET_DEVICE_NAME,                              /* get name, string 
buffer */
+       B_TRIM_DEVICE,                                  /* trims blocks, see 
fs_trim_data */
 
        B_GET_NEXT_OPEN_DEVICE = 1000,  /* obsolete, will be removed */
        B_ADD_FIXED_DRIVER,                             /* obsolete, will be 
removed */
@@ -169,6 +170,14 @@ typedef struct {
 } device_icon;
 
 
+/* B_TRIM_DEVICE data structure */
+typedef struct {
+       off_t   offset;                                 /* offset (in bytes) */
+       off_t   size;
+       off_t   trimmed_size;                   /* filled on return */
+} fs_trim_data;
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/headers/private/fs_shell/fssh_api_wrapper.h 
b/headers/private/fs_shell/fssh_api_wrapper.h
index edb40a9..b0d9a3d 100644
--- a/headers/private/fs_shell/fssh_api_wrapper.h
+++ b/headers/private/fs_shell/fssh_api_wrapper.h
@@ -435,6 +435,10 @@
 #define B_SET_INTERRUPTABLE_IO         FSSH_B_SET_INTERRUPTABLE_IO
 #define B_FLUSH_DRIVE_CACHE                    FSSH_B_FLUSH_DRIVE_CACHE
 #define B_GET_PATH_FOR_DEVICE          FSSH_B_GET_PATH_FOR_DEVICE
+#define B_GET_ICON_NAME                                FSSH_B_GET_ICON_NAME
+#define B_GET_VECTOR_ICON                      FSSH_B_GET_VECTOR_ICON
+#define B_GET_DEVICE_NAME                      FSSH_B_GET_DEVICE_NAME
+#define B_TRIM_DEVICE                          FSSH_B_TRIM_DEVICE
 #define B_GET_NEXT_OPEN_DEVICE         FSSH_B_GET_NEXT_OPEN_DEVICE
 #define B_ADD_FIXED_DRIVER                     FSSH_B_ADD_FIXED_DRIVER
 #define B_REMOVE_FIXED_DRIVER          FSSH_B_REMOVE_FIXED_DRIVER
@@ -462,6 +466,7 @@
 #define driver_path                            fssh_driver_path
 #define open_device_iterator   fssh_open_device_iterator
 #define device_icon                            fssh_device_icon
+#define fs_trim_data                   fssh_fs_trim_data
 
 
 
////////////////////////////////////////////////////////////////////////////////
diff --git a/headers/private/fs_shell/fssh_drivers.h 
b/headers/private/fs_shell/fssh_drivers.h
index a4d25bb..aa63da3 100644
--- a/headers/private/fs_shell/fssh_drivers.h
+++ b/headers/private/fs_shell/fssh_drivers.h
@@ -60,7 +60,7 @@ fssh_status_t         fssh_init_hardware(void);
 const char               **fssh_publish_devices(void);
 fssh_device_hooks      *fssh_find_device(const char *name);
 fssh_status_t          fssh_init_driver(void);
-void                           fssh_uninit_driver(void);       
+void                           fssh_uninit_driver(void);
 
 extern int32_t fssh_api_version;
 
@@ -111,17 +111,20 @@ enum {
                                                                                
/* B_DEV_MEDIA_CHANGE_REQUESTED: user */
                                                                                
/*  pressed button on drive */
                                                                                
/* B_DEV_DOOR_OPEN: door open */
-       
+
        FSSH_B_LOAD_MEDIA,                                      /* load the 
media if supported */
-       
+
        FSSH_B_GET_BIOS_DRIVE_ID,                       /* get bios id for this 
device */
 
        FSSH_B_SET_UNINTERRUPTABLE_IO,          /* prevent cntl-C from 
interrupting i/o */
        FSSH_B_SET_INTERRUPTABLE_IO,            /* allow cntl-C to interrupt 
i/o */
 
        FSSH_B_FLUSH_DRIVE_CACHE,                       /* flush drive cache */
-
        FSSH_B_GET_PATH_FOR_DEVICE,                     /* get the absolute 
path of the device */
+       FSSH_B_GET_ICON_NAME,                           /* get an icon name 
identifier */
+       FSSH_B_GET_VECTOR_ICON,                         /* retrieves the 
device's vector icon */
+       FSSH_B_GET_DEVICE_NAME,                         /* get name, string 
buffer */
+       FSSH_B_TRIM_DEVICE,                                     /* trims 
blocks, see fs_trim_data */
 
        FSSH_B_GET_NEXT_OPEN_DEVICE = 1000,     /* iterate through open devices 
*/
        FSSH_B_ADD_FIXED_DRIVER,                        /* private */
@@ -196,7 +199,7 @@ typedef char        fssh_driver_path[256];
 
 typedef struct {
        uint32_t        cookie;                 /* must be set to 0 before 
iterating */
-       char            device[256];    /* device path */       
+       char            device[256];    /* device path */
 } fssh_open_device_iterator;
 
 
@@ -210,6 +213,14 @@ typedef struct {
 } fssh_device_icon;
 
 
+/* B_TRIM_DEVICE data structure */
+typedef struct {
+       fssh_off_t      offset;                                 /* offset (in 
bytes) */
+       fssh_off_t      size;
+       fssh_off_t      trimmed_size;                   /* filled on return */
+} fssh_fs_trim_data;
+
+
 #ifdef __cplusplus
 }
 #endif

############################################################################

Commit:      be4f73bb1549364bef63eb1ee94d4fa308be6d16
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Sun Aug  4 22:14:52 2013 UTC

Added fstrim command.

Later, there should be a service that runs this from time to time for all
devices that support it.

----------------------------------------------------------------------------

diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage
index 640e9cf..baea3e3 100644
--- a/build/jam/HaikuImage
+++ b/build/jam/HaikuImage
@@ -13,7 +13,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
        diskimage draggers driveinfo dstcheck du dumpcatalog
        echo eject env error expand expr
        factor false fdinfo ffm filepanel find finddir FirstBootPrompt fmt fold
-       fortune frcode ftp ftpd funzip fwcontrol
+       fortune frcode fstrim ftp ftpd funzip fwcontrol
        gawk gdb@x86 getlimits groups gzip gzexe
        hd head hey hostname
        id ident ifconfig <bin>install installsound iroster isvolume
@@ -46,7 +46,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
 
 SYSTEM_APPS = [ FFilterByBuildFeatures
        AboutSystem ActivityMonitor BootManager@x86 CDPlayer CharacterMap
-       CodyCam Debugger DeskCalc Devices DiskProbe DiskUsage DriveSetup  
+       CodyCam Debugger DeskCalc Devices DiskProbe DiskUsage DriveSetup
        Expander GLInfo@x86 Icon-O-Matic Installer LaunchBox Magnify Mail
        MediaConverter MediaPlayer MidiPlayer NetworkStatus PackageInstaller 
People
        PoorMan PowerStatus ProcessController Screenshot ShowImage SoundRecorder
@@ -103,7 +103,7 @@ SYSTEM_ADD_ONS_ACCELERANTS = [ FFilterByBuildFeatures
        x86 @{
                3dfx.accelerant ati.accelerant matrox.accelerant 
neomagic.accelerant
                nvidia.accelerant intel_810.accelerant intel_extreme.accelerant
-               radeon.accelerant radeon_hd.accelerant s3.accelerant 
+               radeon.accelerant radeon_hd.accelerant s3.accelerant
                #via.accelerant vmware.accelerant
        }@ # x86
 ] ;
diff --git a/src/bin/Jamfile b/src/bin/Jamfile
index c4c932b..f8644b9 100644
--- a/src/bin/Jamfile
+++ b/src/bin/Jamfile
@@ -35,6 +35,7 @@ StdBinCommands
        error.c
        fortune.c
        finddir.c
+       fstrim.cpp
        hd.c
        idestatus.c
        listarea.c
diff --git a/src/bin/fstrim.cpp b/src/bin/fstrim.cpp
new file mode 100644
index 0000000..d5dda26
--- /dev/null
+++ b/src/bin/fstrim.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT license.
+ */
+
+
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <Drivers.h>
+
+#include <AutoDeleter.h>
+
+
+static struct option const kLongOptions[] = {
+       {"help", no_argument, 0, 'h'},
+       {NULL}
+};
+
+
+extern const char *__progname;
+static const char *kProgramName = __progname;
+
+
+void
+usage(int returnValue)
+{
+       fprintf(stderr, "Usage: %s <path-to-mounted-file-system>\n", 
kProgramName);
+       exit(returnValue);
+}
+
+
+int
+main(int argc, char** argv)
+{
+       int c;
+       while ((c = getopt_long(argc, argv, "h", kLongOptions, NULL)) != -1) {
+               switch (c) {
+                       case 0:
+                               break;
+                       case 'h':
+                               usage(0);
+                               break;
+                       default:
+                               usage(1);
+                               break;
+               }
+       }
+
+       if (argc - optind < 1)
+               usage(1);
+       const char* path = argv[optind++];
+
+       int fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr, "%s: Could not access path: %s\n", kProgramName,
+                       strerror(errno));
+               return EXIT_FAILURE;
+       }
+
+       FileDescriptorCloser closer(fd);
+
+       fs_trim_data trimData;
+       trimData.offset = 0;
+       trimData.size = OFF_MAX;
+       trimData.trimmed_size = 0;
+
+       if (ioctl(fd, B_TRIM_DEVICE, &trimData, sizeof(fs_trim_data)) != 0) {
+               fprintf(stderr, "%s: Trimming failed: %s\n", kProgramName,
+                       strerror(errno));
+               return EXIT_FAILURE;
+       }
+
+       printf("Trimmed %lld bytes from device.\n", trimData.trimmed_size);
+       return EXIT_SUCCESS;
+}

############################################################################

Commit:      1c6edcdcdc8ab0b4a9ed79d2c0464e73ac8e0745
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Sun Aug  4 22:16:54 2013 UTC

Added B_TRIM_DEVICE support to BFS.

* It currently ignores the offset/size, though, and always trims everything.
* Now only SCSI support is missing.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp 
b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp
index a6aceca..432df6c 100644
--- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2001-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * This file may be used under the terms of the MIT License.
  */
 
@@ -1190,6 +1190,62 @@ BlockAllocator::_CheckGroup(int32 groupIndex) const
 #endif // DEBUG_ALLOCATION_GROUPS
 
 
+status_t
+BlockAllocator::Trim(off_t offset, off_t size, off_t& trimmedSize)
+{
+       RecursiveLocker locker(fLock);
+
+       // TODO: take given offset and size into account!
+       int32 lastGroup = fNumGroups - 1;
+       uint32 firstBlock = 0;
+       uint32 firstBit = 0;
+       off_t currentBlock = 0;
+       uint32 blockShift = fVolume->BlockShift();
+
+       off_t firstFree = -1;
+       size_t freeLength = 0;
+       trimmedSize = 0;
+
+       AllocationBlock cached(fVolume);
+       for (int32 groupIndex = 0; groupIndex <= lastGroup; groupIndex++) {
+               AllocationGroup& group = fGroups[groupIndex];
+
+               for (uint32 block = firstBlock; block < group.NumBlocks(); 
block++) {
+                       cached.SetTo(group, block);
+
+                       for (uint32 i = firstBit; i < cached.NumBlockBits(); 
i++) {
+                               if (cached.IsUsed(i)) {
+                                       // Block is in use
+                                       if (freeLength > 0) {
+                                               status_t status = 
_TrimNext(firstFree << blockShift,
+                                                       freeLength << 
blockShift, trimmedSize);
+                                               if (status != B_OK)
+                                                       return status;
+
+                                               freeLength = 0;
+                                       }
+                               } else if (freeLength++ == 0) {
+                                       // Block is free, start new free range
+                                       firstFree = currentBlock;
+                               }
+
+                               currentBlock++;
+                       }
+               }
+
+               firstBlock = 0;
+               firstBit = 0;
+       }
+
+       if (freeLength > 0) {
+               return _TrimNext(firstFree << blockShift, freeLength << 
blockShift,
+                       trimmedSize);
+       }
+
+       return B_OK;
+}
+
+
 //     #pragma mark - Bitmap validity checking
 
 // TODO: implement new FS checking API
@@ -2124,6 +2180,26 @@ BlockAllocator::_AddInodeToIndex(Inode* inode)
 }
 
 
+status_t
+BlockAllocator::_TrimNext(off_t offset, off_t size, off_t& trimmedSize)
+{
+       PRINT(("_TrimNext(offset %lld, size %lld)\n", offset, size));
+
+       fs_trim_data trimData;
+       trimData.offset = offset;
+       trimData.size = size;
+       trimData.trimmed_size = 0;
+
+       if (ioctl(fVolume->Device(), B_TRIM_DEVICE, &trimData,
+                       sizeof(fs_trim_data)) != 0) {
+               return errno;
+       }
+
+       trimmedSize += trimData.trimmed_size;
+       return B_OK;
+}
+
+
 //     #pragma mark - debugger commands
 
 
diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h 
b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h
index ba490ba..88b9d52 100644
--- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h
+++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2001-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * This file may be used under the terms of the MIT License.
  */
 #ifndef BLOCK_ALLOCATOR_H
@@ -46,6 +46,8 @@ public:
                                                                int32 group, 
uint16 start, uint16 numBlocks,
                                                                uint16 minimum, 
block_run& run);
 
+                       status_t                Trim(off_t offset, off_t size, 
off_t& trimmedSize);
+
                        status_t                StartChecking(const 
check_control* control);
                        status_t                StopChecking(check_control* 
control);
                        status_t                CheckNextNode(check_control* 
control);
@@ -81,6 +83,8 @@ private:
                        void                    _FreeIndices();
                        status_t                _AddInodeToIndex(Inode* inode);
                        status_t                _WriteBackCheckBitmap();
+                       status_t                _TrimNext(off_t offset, off_t 
size,
+                                                               off_t& 
trimmedSize);
 
        static  status_t                _Initialize(BlockAllocator* self);
 
diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp 
b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
index 6504c99..1140003 100644
--- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2001-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * This file may be used under the terms of the MIT License.
  */
 
@@ -623,6 +623,20 @@ bfs_ioctl(fs_volume* _volume, fs_vnode* _node, void* 
_cookie, uint32 cmd,
        Volume* volume = (Volume*)_volume->private_volume;
 
        switch (cmd) {
+               case B_TRIM_DEVICE:
+               {
+                       fs_trim_data trimData;
+                       if (user_memcpy(&trimData, buffer, 
sizeof(fs_trim_data)) != B_OK)
+                               return B_BAD_ADDRESS;
+
+                       status_t status = 
volume->Allocator().Trim(trimData.offset,
+                               trimData.size, trimData.trimmed_size);
+                       if (status != B_OK)
+                               return status;
+
+                       return user_memcpy(buffer, &trimData, 
sizeof(fs_trim_data));
+               }
+
                case BFS_IOCTL_VERSION:
                {
                        uint32 version = 0x10000;


Other related posts: