btrfs-progs: make device discard process interruptible
authorDavid Sterba <dsterba@suse.cz>
Thu, 27 Mar 2014 15:19:37 +0000 (16:19 +0100)
committerChris Mason <clm@fb.com>
Sat, 5 Apr 2014 00:54:35 +0000 (17:54 -0700)
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>
utils.c

diff --git a/utils.c b/utils.c
index 013d74f..3e9c527 100644 (file)
--- a/utils.c
+++ b/utils.c
 #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,