Direct f_flags manipulation may be not suitable for some filesytems. Let's introduce new ->set_flags() callback for that purpose. This callback is responsible for flags check, so ->check_flags() no longer needed. Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx> --- fs/bad_inode.c | 4 ++-- fs/fcntl.c | 14 +++++++------- fs/nfs/file.c | 12 ++++++++---- include/linux/fs.h | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/fs/bad_inode.c b/fs/bad_inode.c index f024d8a..97933cd 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -120,7 +120,7 @@ static unsigned long bad_file_get_unmapped_area(struct file *file, return -EIO; } -static int bad_file_check_flags(int flags) +static int bad_file_set_flags(struct file *file, int flags) { return -EIO; } @@ -165,7 +165,7 @@ static const struct file_operations bad_file_ops = .lock = bad_file_lock, .sendpage = bad_file_sendpage, .get_unmapped_area = bad_file_get_unmapped_area, - .check_flags = bad_file_check_flags, + .set_flags = bad_file_set_flags, .flock = bad_file_flock, .splice_write = bad_file_splice_write, .splice_read = bad_file_splice_read, diff --git a/fs/fcntl.c b/fs/fcntl.c index f8cc34f..76b77ac 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -173,10 +173,6 @@ static int setfl(int fd, struct file * filp, unsigned long arg) return -EINVAL; } - if (filp->f_op && filp->f_op->check_flags) - error = filp->f_op->check_flags(arg); - if (error) - return error; /* * ->fasync() is responsible for setting the FASYNC bit. @@ -189,10 +185,14 @@ static int setfl(int fd, struct file * filp, unsigned long arg) if (error > 0) error = 0; } - spin_lock(&filp->f_lock); - filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); - spin_unlock(&filp->f_lock); + if (filp->f_op && filp->f_op->set_flags) + error = filp->f_op->set_flags(filp, arg); + else { + spin_lock(&filp->f_lock); + filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); + spin_unlock(&filp->f_lock); + } out: return error; } diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 05bf3c0..32ac63a 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -55,7 +55,7 @@ static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, unsigned long nr_segs, loff_t pos); static int nfs_file_flush(struct file *, fl_owner_t id); static int nfs_file_fsync(struct file *, int datasync); -static int nfs_check_flags(int flags); +static int nfs_set_flags(struct file *file, int flags); static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); static int nfs_setlease(struct file *file, long arg, struct file_lock **fl); @@ -77,7 +77,7 @@ const struct file_operations nfs_file_operations = { .flock = nfs_flock, .splice_read = nfs_file_splice_read, .splice_write = nfs_file_splice_write, - .check_flags = nfs_check_flags, + .set_flags = nfs_set_flags, .setlease = nfs_setlease, }; @@ -104,11 +104,15 @@ const struct inode_operations nfs3_file_inode_operations = { # define IS_SWAPFILE(inode) (0) #endif -static int nfs_check_flags(int flags) +#define NFS_FL_MASK (O_NONBLOCK | O_NDELAY | O_NOATIME) +static int nfs_set_flags(struct file * filp, int flags) { if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT)) return -EINVAL; + spin_lock(&filp->f_lock); + filp->f_flags = (flags & NFS_FL_MASK) | (filp->f_flags & ~NFS_FL_MASK); + spin_unlock(&filp->f_lock); return 0; } @@ -125,7 +129,7 @@ nfs_file_open(struct inode *inode, struct file *filp) filp->f_path.dentry->d_name.name); nfs_inc_stats(inode, NFSIOS_VFSOPEN); - res = nfs_check_flags(filp->f_flags); + res = nfs_set_flags(filp, filp->f_flags); if (res) return res; diff --git a/include/linux/fs.h b/include/linux/fs.h index 6708fef..b176d11 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1517,7 +1517,7 @@ struct file_operations { int (*lock) (struct file *, int, struct file_lock *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); - int (*check_flags)(int); + int (*set_flags)(struct file *, int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html