xfs
[Top] [All Lists]

[PATCH v3 1/7] fs: add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate

To: viro@xxxxxxxxxxxxxxxxxx, mtk.manpages@xxxxxxxxx, tytso@xxxxxxx, adilger.kernel@xxxxxxxxx, bpm@xxxxxxx, elder@xxxxxxxxxx, hch@xxxxxxxxxxxxx, david@xxxxxxxxxxxxx
Subject: [PATCH v3 1/7] fs: add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate
From: Namjae Jeon <linkinjeon@xxxxxxxxx>
Date: Sun, 8 Sep 2013 22:41:35 +0900
Cc: linux-fsdevel@xxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, linux-ext4@xxxxxxxxxxxxxxx, xfs@xxxxxxxxxxx, a.sangwan@xxxxxxxxxxx, Namjae Jeon <linkinjeon@xxxxxxxxx>, Namjae Jeon <namjae.jeon@xxxxxxxxxxx>
Delivered-to: xfs@xxxxxxxxxxx
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=JvlyyQyT6WMoP/IQN1oMKt5Njlu4RqYeZ4VCisIpGiM=; b=e4rAtF6Jeq6dp/I5AwT3dNGDkiVW+GcMmq1xXd+CXd5nC7+3q8KAg0el4mnLeKn3Y6 l+s3uPUEvxPC3V8N7VVzuFdE3slF502qqGavPv/PIAXazzJ3vx3hKMJ0GZE7gGCW4hh5 rXbnzZNkjV+9552HoOnp8WaC4vDEwoyx6XAWMhD5KDrZcoanB20It+FLkAbI2YWOIA70 DBSO6JzpfvgpqvDwUUMiHsz4tpZE2/o/r5ZN9VARXyIJUbPyKwe0teG/Q7q3fWM8WbzC 30PZQhHv61IDaq1YTRVNW4dm6pTTAaWsvr04Fkk+CMQDh1i77rFWyUy5B0D105+7LmES UA5A==
From: Namjae Jeon <namjae.jeon@xxxxxxxxxxx>

Add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate.
updated detailed semantics in comments.

Signed-off-by: Namjae Jeon <namjae.jeon@xxxxxxxxxxx>
Signed-off-by: Ashish Sangwan <a.sangwan@xxxxxxxxxxx>
---
 fs/open.c                   |   24 +++++++++++++++++++++---
 include/uapi/linux/falloc.h |   17 +++++++++++++++++
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 7931f76..85d243a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -225,12 +225,14 @@ int do_fallocate(struct file *file, int mode, loff_t 
offset, loff_t len)
 {
        struct inode *inode = file_inode(file);
        long ret;
+       unsigned blksize_mask = (1 << inode->i_blkbits) - 1;
 
        if (offset < 0 || len <= 0)
                return -EINVAL;
 
        /* Return error if mode is not supported */
-       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+                    FALLOC_FL_COLLAPSE_RANGE))
                return -EOPNOTSUPP;
 
        /* Punch hole must have keep size set */
@@ -241,8 +243,12 @@ int do_fallocate(struct file *file, int mode, loff_t 
offset, loff_t len)
        if (!(file->f_mode & FMODE_WRITE))
                return -EBADF;
 
-       /* It's not possible punch hole on append only file */
-       if (mode & FALLOC_FL_PUNCH_HOLE && IS_APPEND(inode))
+       /*
+        * It's not possible to punch hole or perform collapse range
+        * on append only file
+        */
+       if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE)
+           && IS_APPEND(inode))
                return -EPERM;
 
        if (IS_IMMUTABLE(inode))
@@ -270,6 +276,18 @@ int do_fallocate(struct file *file, int mode, loff_t 
offset, loff_t len)
        if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
                return -EFBIG;
 
+       /*
+        * Collapse range works only on fs block size aligned offsets.
+        * Check if collapse range is contained within (aligned)i_size.
+        * Collapse range can only be used exclusively.
+        */
+       if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
+           (offset & blksize_mask || len & blksize_mask ||
+            mode & ~FALLOC_FL_COLLAPSE_RANGE ||
+            (offset + len >
+             round_up(i_size_read(inode), (blksize_mask + 1)))))
+               return -EINVAL;
+
        if (!file->f_op->fallocate)
                return -EOPNOTSUPP;
 
diff --git a/include/uapi/linux/falloc.h b/include/uapi/linux/falloc.h
index 990c4cc..9614b72 100644
--- a/include/uapi/linux/falloc.h
+++ b/include/uapi/linux/falloc.h
@@ -4,6 +4,23 @@
 #define FALLOC_FL_KEEP_SIZE    0x01 /* default is extend size */
 #define FALLOC_FL_PUNCH_HOLE   0x02 /* de-allocates range */
 #define FALLOC_FL_NO_HIDE_STALE        0x04 /* reserved codepoint */
+/*
+ * FALLOC_FL_COLLAPSE_RANGE:
+ * This flag works in 2 steps.
+ * Firstly, it deallocates any data blocks present between [offset, offset+len)
+ * This step is same as punch hole and leaves a hole in the place from where
+ * the blocks are removed.
+ * Next, it eliminates the hole created by moving data blocks into it.
+ * For extent based file systems, we achieve this functionality simply by
+ * updating the starting logical offset of each extent which appears beyond
+ * the hole. As this flag works on blocks of filesystem, the offset and len
+ * provided to fallocate should be aligned with block size of filesystem.
+ * The semantics of this flag are:
+ * 1) It should be used exclusively. No other fallocate flag in combination.
+ * 2) Offset and len supplied to fallocate should be aligned with block size.
+ * 3) (offset + len) could not be greater than file size.
+ */
+#define FALLOC_FL_COLLAPSE_RANGE       0x08 /* it does not leave a hole */
 
 
 #endif /* _UAPI_FALLOC_H_ */
-- 
1.7.9.5

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH v3 1/7] fs: add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate, Namjae Jeon <=