From: Enke Chen <enkechen@cisco.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
Jeff Layton <jlayton@poochiereds.net>,
"J. Bruce Fields" <bfields@fieldses.org>,
Trond Myklebust <trond.myklebust@primarydata.com>,
Anna Schumaker <anna.schumaker@netapp.com>
Cc: linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org,
Enke Chen <enkechen@cisco.com>
Subject: [PATCH] VFS: pass the flag setting by fcntl() to vfs
Date: Thu, 5 May 2016 11:26:11 -0700 [thread overview]
Message-ID: <c6b1075a-2eb5-a065-96ac-fc06ec04ea0f@cisco.com> (raw)
In-Reply-To: <ebf888a1-ee45-a79b-6f72-43a8744e0196@cisco.com>
VFS: pass the flag setting by fcntl() to vfs
Several flags such as O_NONBLOCK are set using the fcntl() system call.
Currently the flags are validated in setfl() by the vfs using the
"check_flags" operation, but the eventual setting is not passed to the
vfs.
We have an application that uses the vfs/fuse and the flag O_NONBLOCK
is critical for the application.
This patch extends the "check_flags" function so that the flags are
passed to the vfs layer for setting in addition to validating. More
specifically:
o add additional parameters to "check_flags", one for the file pointer,
and one for setting. Also change the "flags" parameter from "int" to
"unsigned int" to make it consistent with "filp->f_flags".
o in setfl() pass the flags to vfs for setting once the flags are
set correctly in the kernel.
o use the "check_flags" operation in ioctl_fionbio() also for
ioctl(fd, FIONOIO, &on).
o make necessary adjustments to several files in fs/nfs (NFS is the
only module using "check_flags").
Signed-off-by: Enke Chen <enkechen@cisco.com>
Version: 4.6.0_rc6_next_20160503
Documentation/filesystems/Locking | 2 +-
Documentation/filesystems/vfs.txt | 2 +-
fs/fcntl.c | 10 +++++++++-
fs/ioctl.c | 9 +++++++++
fs/nfs/dir.c | 2 +-
fs/nfs/file.c | 7 +++++--
fs/nfs/internal.h | 2 +-
fs/nfs/nfs4file.c | 2 +-
include/linux/fs.h | 2 +-
9 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 75eea7c..c1cf807 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -452,7 +452,7 @@ prototypes:
loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
- int (*check_flags)(int);
+ int (*check_flags)(unsigned int, 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);
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index c61a223..193ee19 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -822,7 +822,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 (*check_flags)(unsigned int, 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);
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 350a2c8..5582dc8 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -32,6 +32,7 @@
static int setfl(int fd, struct file * filp, unsigned long arg)
{
struct inode * inode = file_inode(filp);
+ unsigned int flags;
int error = 0;
/*
@@ -59,7 +60,7 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
}
if (filp->f_op->check_flags)
- error = filp->f_op->check_flags(arg);
+ error = filp->f_op->check_flags(arg, filp, 0);
if (error)
return error;
@@ -75,8 +76,15 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
}
spin_lock(&filp->f_lock);
filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
+ flags = filp->f_flags;
spin_unlock(&filp->f_lock);
+ /*
+ * Pass the flags to VFS for setting.
+ */
+ if (filp->f_op->check_flags)
+ error = filp->f_op->check_flags(flags, filp, 1);
+
out:
return error;
}
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 116a333..de06d93 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -496,6 +496,7 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
static int ioctl_fionbio(struct file *filp, int __user *argp)
{
unsigned int flag;
+ unsigned int setfl;
int on, error;
error = get_user(on, argp);
@@ -512,7 +513,15 @@ static int ioctl_fionbio(struct file *filp, int __user *argp)
filp->f_flags |= flag;
else
filp->f_flags &= ~flag;
+ setfl = filp->f_flags;
spin_unlock(&filp->f_lock);
+
+ /*
+ * Do the same as in fcntl().
+ */
+ if (filp->f_op->check_flags)
+ error = filp->f_op->check_flags(setfl, filp, 1);
+
return error;
}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index aaf7bd0..e16de49 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1495,7 +1495,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
dfprintk(VFS, "NFS: atomic_open(%s/%lu), %pd\n",
dir->i_sb->s_id, dir->i_ino, dentry);
- err = nfs_check_flags(open_flags);
+ err = nfs_check_flags(open_flags, file, 0);
if (err)
return err;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 717a8d6..d049929 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -48,8 +48,11 @@ static const struct vm_operations_struct nfs_file_vm_ops;
# define IS_SWAPFILE(inode) (0)
#endif
-int nfs_check_flags(int flags)
+int nfs_check_flags(unsigned int flags, struct file *filp, int setting)
{
+ if (setting)
+ return 0;
+
if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT))
return -EINVAL;
@@ -68,7 +71,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
dprintk("NFS: open file(%pD2)\n", filp);
nfs_inc_stats(inode, NFSIOS_VFSOPEN);
- res = nfs_check_flags(filp->f_flags);
+ res = nfs_check_flags(filp->f_flags, filp, 0);
if (res)
return res;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index f1d1d2c..0916d99 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -368,7 +368,7 @@ ssize_t nfs_file_write(struct kiocb *, struct iov_iter *);
int nfs_file_release(struct inode *, struct file *);
int nfs_lock(struct file *, int, struct file_lock *);
int nfs_flock(struct file *, int, struct file_lock *);
-int nfs_check_flags(int);
+int nfs_check_flags(unsigned int, struct file *, int);
/* inode.c */
extern struct workqueue_struct *nfsiod_workqueue;
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index d039051..7ae0d15 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -44,7 +44,7 @@ nfs4_file_open(struct inode *inode, struct file *filp)
dprintk("NFS: open file(%pd2)\n", dentry);
- err = nfs_check_flags(openflags);
+ err = nfs_check_flags(openflags, filp, 0);
if (err)
return err;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d61cd08..fdc9cc9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1717,7 +1717,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 (*check_flags)(unsigned int, 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);
next parent reply other threads:[~2016-05-05 18:35 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <ebf888a1-ee45-a79b-6f72-43a8744e0196@cisco.com>
2016-05-05 18:26 ` Enke Chen [this message]
2016-05-08 10:40 ` [PATCH] VFS: pass the flag setting by fcntl() to vfs Christoph Hellwig
2016-05-09 0:50 ` Enke Chen
2016-05-09 7:02 ` Christoph Hellwig
2016-05-09 18:39 ` Enke Chen
2016-05-25 19:03 ` [PATCH RESEND] vfs: " Enke Chen
2016-05-25 19:52 ` Al Viro
2016-05-25 21:16 ` Enke Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c6b1075a-2eb5-a065-96ac-fc06ec04ea0f@cisco.com \
--to=enkechen@cisco.com \
--cc=anna.schumaker@netapp.com \
--cc=bfields@fieldses.org \
--cc=jlayton@poochiereds.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@primarydata.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).