From 00f5e61998dd17f5375d9dfc01331f104b83f841 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Mon, 24 Feb 2014 10:58:15 +1100 Subject: fs: Add new flag(FALLOC_FL_COLLAPSE_RANGE) for fallocate This patch is in response of the following post: http://lwn.net/Articles/556136/ "ext4: introduce two new ioctls" Dave chinner suggested that truncate_block_range (which was one of the ioctls name) should be a fallocate operation and not any fs specific ioctl, hence we add this functionality to new flags of fallocate. This new functionality of collapsing range could be used by media editing tools which does non linear editing to quickly purge and edit parts of a media file. This will immensely improve the performance of these operations. The limitation of fs block size aligned offsets can be easily handled by media codecs which are encapsulated in a conatiner as they have to just change the offset to next keyframe value to match the proper alignment. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/open.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'fs/open.c') diff --git a/fs/open.c b/fs/open.c index 4b3e1edf2fe4..4a923a547d10 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; -- cgit