diff options
author | David Sterba <dsterba@suse.cz> | 2014-03-27 16:19:37 +0100 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-04-04 17:54:35 -0700 |
commit | 4724d7b07553ad27429bb2d61de1c5e8d4d7613d (patch) | |
tree | e55de6cbcab159a46419e5a51e3963b2fc9dceca | |
parent | a062ffd74de0b6ad74ea2c9750da94e2964856a1 (diff) |
btrfs-progs: make device discard process interruptible
The ioctl for the whole range is not interruptible, which can be
annoying when the discard is not wanted but user forgets to use the -K
option.
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r-- | utils.c | 26 |
1 files changed, 24 insertions, 2 deletions
@@ -52,8 +52,10 @@ #define BLKDISCARD _IO(0x12,119) #endif -static int -discard_blocks(int fd, u64 start, u64 len) +/* + * Discard the given range in one go + */ +static int discard_range(int fd, u64 start, u64 len) { u64 range[2] = { start, len }; @@ -62,6 +64,26 @@ discard_blocks(int fd, u64 start, u64 len) return 0; } +/* + * Discard blocks in the given range in 1G chunks, the process is interruptible + */ +static int discard_blocks(int fd, u64 start, u64 len) +{ + while (len > 0) { + /* 1G granularity */ + u64 chunk_size = min_t(u64, len, 1*1024*1024*1024); + int ret; + + ret = discard_range(fd, start, chunk_size); + if (ret) + return ret; + len -= chunk_size; + start += chunk_size; + } + + return 0; +} + static u64 reference_root_table[] = { [1] = BTRFS_ROOT_TREE_OBJECTID, [2] = BTRFS_EXTENT_TREE_OBJECTID, |