* [PATCH v2 1/2] vfs: pass 'struct file *' as parameter to ->check_flags() methods @ 2011-07-27 10:56 Anand Avati [not found] ` <1311764179-20326-1-git-send-email-avati-+FkPdpiNhgJBDgjK7y7TUQ@public.gmane.org> 0 siblings, 1 reply; 6+ messages in thread From: Anand Avati @ 2011-07-27 10:56 UTC (permalink / raw) To: miklos-sUDqSbJrdHQHWmgEVkV9KA Cc: fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, linux-nfs-u79uwXL29TY76Z2rM5mHXA, Anand Avati FUSE needs to selectively permit ->check_flags() on a per-file basis as it does not support setting/unsetting O_DIRECT flag on an open file. Hence passing 'struct file *' as a parameter to ->check_flags() is necessary to inspect and compare file->f_flags with the new flags. Signed-off-by: Anand Avati <avati-+FkPdpiNhgJBDgjK7y7TUQ@public.gmane.org> --- Documentation/filesystems/Locking | 2 +- Documentation/filesystems/vfs.txt | 2 +- fs/bad_inode.c | 2 +- fs/fcntl.c | 2 +- fs/nfs/file.c | 6 +++--- include/linux/fs.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 57d827d..9619841 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -426,7 +426,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)(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 88b9f55..442aefb 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -764,7 +764,7 @@ struct file_operations { ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *); 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)(struct file *, int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); diff --git a/fs/bad_inode.c b/fs/bad_inode.c index bfcb18f..c7eef18 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_check_flags(struct file *filp, int flags) { return -EIO; } diff --git a/fs/fcntl.c b/fs/fcntl.c index 22764c7..1a2a6d3 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -174,7 +174,7 @@ static int setfl(int fd, struct file * filp, unsigned long arg) } if (filp->f_op && filp->f_op->check_flags) - error = filp->f_op->check_flags(arg); + error = filp->f_op->check_flags(filp, arg); if (error) return error; diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 2f093ed..9f96a8b 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -56,7 +56,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_check_flags(struct 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); @@ -105,7 +105,7 @@ const struct inode_operations nfs3_file_inode_operations = { # define IS_SWAPFILE(inode) (0) #endif -static int nfs_check_flags(int flags) +static int nfs_check_flags(struct file *filp, int flags) { if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT)) return -EINVAL; @@ -126,7 +126,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_check_flags(filp, filp->f_flags); if (res) return res; diff --git a/include/linux/fs.h b/include/linux/fs.h index b5b9792..98ce7c7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1564,7 +1564,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)(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.4.4 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 6+ messages in thread
[parent not found: <1311764179-20326-1-git-send-email-avati-+FkPdpiNhgJBDgjK7y7TUQ@public.gmane.org>]
* [PATCH v2 2/2] fuse: permit O_DIRECT flag in open() [not found] ` <1311764179-20326-1-git-send-email-avati-+FkPdpiNhgJBDgjK7y7TUQ@public.gmane.org> @ 2011-07-27 10:56 ` Anand Avati 2011-07-27 21:05 ` Christoph Hellwig 0 siblings, 1 reply; 6+ messages in thread From: Anand Avati @ 2011-07-27 10:56 UTC (permalink / raw) To: miklos-sUDqSbJrdHQHWmgEVkV9KA Cc: fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, linux-nfs-u79uwXL29TY76Z2rM5mHXA, Anand Avati FUSE currently disallows O_DIRECT flag in open(). It is tricky dealing with setting/unsetting of O_DIRECT flag on an open file. There are applications (primarily VMs and databases) which open files with O_DIRECT flag. These applications do not work on FUSE due to this limitation. The approach with this patch is to permit opens with O_DIRECT, but instead disable setting/unsetting of the O_DIRECT flag no matter how the file was opened. This limitation is for more practical than disallowing O_DIRECT altogether. Signed-off-by: Anand Avati <avati-+FkPdpiNhgJBDgjK7y7TUQ@public.gmane.org> --- fs/fuse/file.c | 36 ++++++++++++++++++++++++++++++++---- 1 files changed, 32 insertions(+), 4 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 82a6646..355c30f 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -154,6 +154,27 @@ int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, return err; } + if (file->f_flags & O_DIRECT) { + if (!(outarg.open_flags & FOPEN_DIRECT_IO)) { + /* filesystem process did not acknowledge the O_DIRECT + flag with FOPEN_DIRECT_IO bit in ourarg. Hence + we fail the open(). + + Notify the filesystem process about the failed + open with fuse_sync_release right here itself as + file->private_data is not yet set up for release + notification. + */ + fuse_sync_release(ff, file->f_flags); + return -EINVAL; + } + + /* make VFS believe we don't support O_DIRECT till we + implement a_ops->direct_IO + */ + file->f_flags &= ~O_DIRECT; + } + if (isdir) outarg.open_flags &= ~FOPEN_DIRECT_IO; @@ -193,10 +214,6 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) struct fuse_conn *fc = get_fuse_conn(inode); int err; - /* VFS checks this, but only _after_ ->open() */ - if (file->f_flags & O_DIRECT) - return -EINVAL; - err = generic_file_open(inode, file); if (err) return err; @@ -2132,6 +2149,15 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc, return 0; } + +static int fuse_check_flags(struct file *filp, int flags) +{ + if ((filp->f_flags ^ flags) & O_DIRECT) + return -EINVAL; + return 0; +} + + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -2149,6 +2175,7 @@ static const struct file_operations fuse_file_operations = { .unlocked_ioctl = fuse_file_ioctl, .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, + .check_flags = fuse_check_flags, }; static const struct file_operations fuse_direct_io_file_operations = { @@ -2165,6 +2192,7 @@ static const struct file_operations fuse_direct_io_file_operations = { .unlocked_ioctl = fuse_file_ioctl, .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, + .check_flags = fuse_check_flags, /* no splice_read */ }; -- 1.7.4.4 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] fuse: permit O_DIRECT flag in open() 2011-07-27 10:56 ` [PATCH v2 2/2] fuse: permit O_DIRECT flag in open() Anand Avati @ 2011-07-27 21:05 ` Christoph Hellwig 2011-07-28 8:14 ` Anand Avati 0 siblings, 1 reply; 6+ messages in thread From: Christoph Hellwig @ 2011-07-27 21:05 UTC (permalink / raw) To: Anand Avati; +Cc: miklos, fuse-devel, linux-fsdevel, linux-nfs On Wed, Jul 27, 2011 at 03:56:19AM -0700, Anand Avati wrote: > FUSE currently disallows O_DIRECT flag in open(). It is tricky dealing with > setting/unsetting of O_DIRECT flag on an open file. There are applications > (primarily VMs and databases) which open files with O_DIRECT flag. These > applications do not work on FUSE due to this limitation. > > The approach with this patch is to permit opens with O_DIRECT, but instead > disable setting/unsetting of the O_DIRECT flag no matter how the file was > opened. This limitation is for more practical than disallowing O_DIRECT > altogether. But it's also entirely incorrect. Fix your userspace to have a proper fallback if O_DIRECT opens fail. It's a feature only supported by a few filesystems, and very few operating systems. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] fuse: permit O_DIRECT flag in open() 2011-07-27 21:05 ` Christoph Hellwig @ 2011-07-28 8:14 ` Anand Avati 2011-07-28 11:49 ` Christoph Hellwig 0 siblings, 1 reply; 6+ messages in thread From: Anand Avati @ 2011-07-28 8:14 UTC (permalink / raw) To: Christoph Hellwig; +Cc: miklos, fuse-devel, linux-fsdevel On Thu, Jul 28, 2011 at 2:35 AM, Christoph Hellwig <hch@infradead.org> wrote: > On Wed, Jul 27, 2011 at 03:56:19AM -0700, Anand Avati wrote: >> FUSE currently disallows O_DIRECT flag in open(). It is tricky dealing with >> setting/unsetting of O_DIRECT flag on an open file. There are applications >> (primarily VMs and databases) which open files with O_DIRECT flag. These >> applications do not work on FUSE due to this limitation. >> >> The approach with this patch is to permit opens with O_DIRECT, but instead >> disable setting/unsetting of the O_DIRECT flag no matter how the file was >> opened. This limitation is for more practical than disallowing O_DIRECT >> altogether. > > But it's also entirely incorrect. Fix your userspace to have a proper > fallback if O_DIRECT opens fail. It's a feature only supported by a few > filesystems, and very few operating systems. FUSE already has a direct IO implementation (struct file_operations fuse_direct_io_file_operation) but is currently set as a file's f_ops only based on flags returned from the filesystem server (in the reply of an open() call). This patch just lets the filesystem server know a userspace application's intention to open a file with O_DIRECT and leaves it with the decision to pick direct IO mode on the file (just the way it already does before the patch.) There is already a framework for direct IO operations and this patch only bridges O_DIRECT flag with that framework. Do you still think this is entirely incorrect? Avati -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] fuse: permit O_DIRECT flag in open() 2011-07-28 8:14 ` Anand Avati @ 2011-07-28 11:49 ` Christoph Hellwig 2011-07-28 18:12 ` Anand Avati 0 siblings, 1 reply; 6+ messages in thread From: Christoph Hellwig @ 2011-07-28 11:49 UTC (permalink / raw) To: Anand Avati; +Cc: Christoph Hellwig, miklos, fuse-devel, linux-fsdevel On Thu, Jul 28, 2011 at 01:44:08PM +0530, Anand Avati wrote: > FUSE already has a direct IO implementation (struct file_operations > fuse_direct_io_file_operation) but is currently set as a file's f_ops > only based on flags returned from the filesystem server (in the reply > of an open() call). This patch just lets the filesystem server know a > userspace application's intention to open a file with O_DIRECT and > leaves it with the decision to pick direct IO mode on the file (just > the way it already does before the patch.) There is already a > framework for direct IO operations and this patch only bridges > O_DIRECT flag with that framework. Do you still think this is entirely > incorrect? Your clearing of the O_DIRECT flag is. The current handling of O_DIRECT in the VFS is a bit nasty, but if you have an issue with that fix it up properly instead of piling more hacks on top of it. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] fuse: permit O_DIRECT flag in open() 2011-07-28 11:49 ` Christoph Hellwig @ 2011-07-28 18:12 ` Anand Avati 0 siblings, 0 replies; 6+ messages in thread From: Anand Avati @ 2011-07-28 18:12 UTC (permalink / raw) To: Christoph Hellwig; +Cc: miklos, fuse-devel, linux-fsdevel On Thu, Jul 28, 2011 at 5:19 PM, Christoph Hellwig <hch@infradead.org> wrote: > > Your clearing of the O_DIRECT flag is. The current handling of O_DIRECT > in the VFS is a bit nasty, but if you have an issue with that fix it up > properly instead of piling more hacks on top of it. > Hmm, I thought that the fact VFS checked for O_DIRECT after ->open() was intentionally giving an opportunity to the filesystem to clear it. But looking backwards now, I think it was my misunderstanding of the intention. I will look deeper into a cleaner implementation of O_DIRECT support. Avati -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-07-28 18:12 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-07-27 10:56 [PATCH v2 1/2] vfs: pass 'struct file *' as parameter to ->check_flags() methods Anand Avati [not found] ` <1311764179-20326-1-git-send-email-avati-+FkPdpiNhgJBDgjK7y7TUQ@public.gmane.org> 2011-07-27 10:56 ` [PATCH v2 2/2] fuse: permit O_DIRECT flag in open() Anand Avati 2011-07-27 21:05 ` Christoph Hellwig 2011-07-28 8:14 ` Anand Avati 2011-07-28 11:49 ` Christoph Hellwig 2011-07-28 18:12 ` Anand Avati
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).