summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2014-03-27 16:19:37 +0100
committerChris Mason <clm@fb.com>2014-04-04 17:54:35 -0700
commit4724d7b07553ad27429bb2d61de1c5e8d4d7613d (patch)
treee55de6cbcab159a46419e5a51e3963b2fc9dceca
parenta062ffd74de0b6ad74ea2c9750da94e2964856a1 (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.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/utils.c b/utils.c
index 013d74f9..3e9c527a 100644
--- a/utils.c
+++ b/utils.c
@@ -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,