xfs
[Top] [All Lists]

[PATCH 1/3] fs: Introduce new flag FALLOC_FL_COLLAPSE_RANGE

To: tytso@xxxxxxx, adilger.kernel@xxxxxxxxx, bpm@xxxxxxx, elder@xxxxxxxxxx, hch@xxxxxxxxxxxxx, david@xxxxxxxxxxxxx
Subject: [PATCH 1/3] fs: Introduce new flag FALLOC_FL_COLLAPSE_RANGE
From: Namjae Jeon <linkinjeon@xxxxxxxxx>
Date: Wed, 31 Jul 2013 23:42:00 +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:x-mailer; bh=TWcWNVtvB0v/gjHEAHAn3KVNM76RFm1c+GideL0zi40=; b=TxadNtRJ/K0oArlf71scqQiBWQQ9gnk0iFAcW310le56iRKR0sLpYAvuZPfJ9sU9N0 bp/ChH7nHpSltD1NtvJdzfLdm44Ezo2+qGVNFRay9DctVkRVWbgtE3YqXs5ry1zlbBEm nL+xAvx2FBY7XeIr5F5VHGVK8LdBfdex17qXzY/MGUNlW+VMvv9Mbs8I2hV5rbAHaERn A83yHbdc4MQVaJ8zMay7463IaTH5TGePns6bYAnlCxSMm1OslfUBgjE22tM5CG/O0sXc +8VJpTtsVPUT/1lX+A0NqNoHcR9lFu6VAX5xXRkozBFERftlUGCWmDkIZZpU39STD/R0 YRKw==
From: Namjae Jeon <namjae.jeon@xxxxxxxxxxx>

Fallocate now supports new FALLOC_FL_COLLAPSE_RANGE flag.
The semantics of this flag are following:
1) It collapses the range lying between offset and length by removing any data
   blocks which are present in this range and than updates all the logical
   offsets of extents beyond "offset + len" to nullify the hole created by
   removing blocks. In short, it does not leave a hole.
1) It should be used exclusively. No other fallocate flag in combination.
2) Offset and length supplied to fallocate should be fs block size aligned.
3) It wokrs beyond "EOF", so the extents which are pre-allocated beyond "EOF"
   are also updated.
4) It reduces the i_size of inode by the amount of collapse range which lies
   within i_size. So, if offset >= i_size, i_size won't be changed at all.

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

diff --git a/fs/open.c b/fs/open.c
index d53e298..e076390 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -225,12 +225,15 @@ int do_fallocate(struct file *file, int mode, loff_t 
offset, loff_t len)
 {
        struct inode *inode = file_inode(file);
        long ret;
+       unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits);
+       unsigned blksize_mask = (1 << 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 +244,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 +277,12 @@ 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 */
+       if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
+           (offset & blksize_mask || len & blksize_mask ||
+            mode & ~FALLOC_FL_COLLAPSE_RANGE))
+                       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..7567c8c 100644
--- a/include/uapi/linux/falloc.h
+++ b/include/uapi/linux/falloc.h
@@ -1,9 +1,10 @@
 #ifndef _UAPI_FALLOC_H_
 #define _UAPI_FALLOC_H_
 
-#define FALLOC_FL_KEEP_SIZE    0x01 /* default is extend size */
-#define FALLOC_FL_PUNCH_HOLE   0x02 /* de-allocates range */
+#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 */
+#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>