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;