xfs
[Top] [All Lists]

[PATCH v4 1/10] fs: Add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate

To: viro@xxxxxxxxxxxxxxxxxx, david@xxxxxxxxxxxxx, bpm@xxxxxxx, tytso@xxxxxxx, adilger.kernel@xxxxxxxxx, jack@xxxxxxx
Subject: [PATCH v4 1/10] fs: Add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate
From: Namjae Jeon <linkinjeon@xxxxxxxxx>
Date: Sun, 8 Dec 2013 23:05:44 +0900
Cc: linux-fsdevel@xxxxxxxxxxxxxxx, xfs@xxxxxxxxxxx, linux-ext4@xxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, Namjae Jeon <linkinjeon@xxxxxxxxx>, Namjae Jeon <namjae.jeon@xxxxxxxxxxx>, Ashish Sangwan <a.sangwan@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=0ytFP5BqLl9cItOBNE3kWDILCwGZaGzbI+dEx3r4Wm8=; b=Ly2+6G6YBVhYED7mEviJL3uPgEl4YuGJgP4DVOefsHl3xfjULMFnfeI1sBOfa9NLrC ZtG4zMSCkW8UcajXI9yazDM7jG/CJGU6OIe9mY7stYpXY1tPoi+tM43PuD17T3IwlG8X QZnSbWMyteAkDZAcK4K/N0b9VjeVTgQamH6xV6sx+kreezf8cbc5KkUEMB/5owpG+xH5 IJKNmT4Ym/wHDbs6ZfhJsrlPbWDWgdGbsGEW96G/3UrkM51peQBf5uof/Ng4R5AlQ+Bm 1vr1H3svTxbXQccNAvpRlrn3drOZaMkiGe1cvrJZaAQOmo6UK+9VSe1C3BHqEq3aFvkQ gAYQ==
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 |   21 +++++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 4b3e1ed..4a923a5 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -231,7 +231,8 @@ int do_fallocate(struct file *file, int mode, loff_t 
offset, loff_t len)
                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 */
@@ -239,11 +240,20 @@ int do_fallocate(struct file *file, int mode, loff_t 
offset, loff_t len)
            !(mode & FALLOC_FL_KEEP_SIZE))
                return -EOPNOTSUPP;
 
+       /* Collapse range should only be used exclusively. */
+       if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
+           (mode & ~FALLOC_FL_COLLAPSE_RANGE))
+               return -EINVAL;
+
        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))
@@ -271,6 +281,14 @@ 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;
 
+       /*
+        * There is no need to overlap collapse range with EOF, in which case
+        * it is effectively a truncate operation
+        */
+       if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
+           (offset + len >= i_size_read(inode)))
+               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..5b214cc 100644
--- a/include/uapi/linux/falloc.h
+++ b/include/uapi/linux/falloc.h
@@ -5,5 +5,26 @@
 #define FALLOC_FL_PUNCH_HOLE   0x02 /* de-allocates range */
 #define FALLOC_FL_NO_HIDE_STALE        0x04 /* reserved codepoint */
 
+/*
+ * FALLOC_FL_COLLAPSE_RANGE is used to remove a range of a file
+ * without leaving a hole in the file. The contents of the file beyond
+ * the range being removed is appended to the start offset of the range
+ * being removed (i.e. the hole that was punched is "collapsed"),
+ * resulting in a file layout that looks like the range that was
+ * removed never existed. As such collapsing a range of a file changes
+ * the size of the file, reducing it by the same length of the range
+ * that has been removed by the operation.
+ *
+ * Different filesystems may implement different limitations on the
+ * granularity of the operation. Most will limit operations to
+ * filesystem block size boundaries, but this boundary may be larger or
+ * smaller depending on the filesystem and/or the configuration of the
+ * filesystem or file.
+ *
+ * Attempting to collapse a range that crosses the end of the file is
+ * considered an illegal operation - just use ftruncate(2) if you need
+ * to collapse a range that crosses EOF.
+ */
+#define FALLOC_FL_COLLAPSE_RANGE       0x08
 
 #endif /* _UAPI_FALLOC_H_ */
-- 
1.7.9.5

<Prev in Thread] Current Thread [Next in Thread>