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

2013-09-02 Thread Namjae Jeon
From: Namjae Jeon 

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

Signed-off-by: Namjae Jeon 
Signed-off-by: Ashish Sangwan 
---
 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_SIZE0x01 /* default is extend size */
 #define FALLOC_FL_PUNCH_HOLE   0x02 /* de-allocates range */
 #define FALLOC_FL_NO_HIDE_STALE0x04 /* 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2013-09-02 Thread Namjae Jeon
From: Namjae Jeon namjae.j...@samsung.com

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

Signed-off-by: Namjae Jeon namjae.j...@samsung.com
Signed-off-by: Ashish Sangwan a.sang...@samsung.com
---
 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_SIZE0x01 /* default is extend size */
 #define FALLOC_FL_PUNCH_HOLE   0x02 /* de-allocates range */
 #define FALLOC_FL_NO_HIDE_STALE0x04 /* 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

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/