* [PATCH 0/3] Add a mount option to support eager writes @ 2021-02-12 21:49 trondmy 2021-02-12 21:49 ` [PATCH 1/3] NFS: 'flags' field should be unsigned in struct nfs_server trondmy 2021-02-13 14:19 ` [PATCH 0/3] Add a mount option to support " Steve Dickson 0 siblings, 2 replies; 6+ messages in thread From: trondmy @ 2021-02-12 21:49 UTC (permalink / raw) To: Anna Schumaker; +Cc: linux-nfs From: Trond Myklebust <trond.myklebust@hammerspace.com> The following patch series sets up a new mount option 'writes=lazy/eager/wait'. The mount option basically controls how the write() system call works. - writes=lazy is the default, and keeps the current behaviour - writes=eager means we send off the write immediately as an unstable write to the server. - writes=wait means we send off the write as an unstable write, and then wait for the reply. The main motivator for this behaviour is that some applications expect write() to return ENOSPC. Setting writes=wait should satisfy those applications without taking the full overhead of a synchronous write. writes=eager, on the other hand, can be useful for applications such as re-exporting NFS, since it would allow knfsd on the proxying server to immediately forward the writes to the original server. Trond Myklebust (3): NFS: 'flags' field should be unsigned in struct nfs_server NFS: Add support for eager writes NFS: Add mount options supporting eager writes fs/nfs/file.c | 19 +++++++++++++++++-- fs/nfs/fs_context.c | 33 +++++++++++++++++++++++++++++++++ fs/nfs/write.c | 17 ++++++++++++----- include/linux/nfs_fs_sb.h | 4 +++- 4 files changed, 65 insertions(+), 8 deletions(-) -- 2.29.2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] NFS: 'flags' field should be unsigned in struct nfs_server 2021-02-12 21:49 [PATCH 0/3] Add a mount option to support eager writes trondmy @ 2021-02-12 21:49 ` trondmy 2021-02-12 21:49 ` [PATCH 2/3] NFS: Add support for eager writes trondmy 2021-02-13 14:19 ` [PATCH 0/3] Add a mount option to support " Steve Dickson 1 sibling, 1 reply; 6+ messages in thread From: trondmy @ 2021-02-12 21:49 UTC (permalink / raw) To: Anna Schumaker; +Cc: linux-nfs From: Trond Myklebust <trond.myklebust@hammerspace.com> The mount flags are all unsigned integers, so we should not be storing them in a signed field. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> --- include/linux/nfs_fs_sb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 38e60ec742df..962e8313f007 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -142,7 +142,7 @@ struct nfs_server { struct nlm_host *nlm_host; /* NLM client handle */ struct nfs_iostats __percpu *io_stats; /* I/O statistics */ atomic_long_t writeback; /* number of writeback pages */ - int flags; /* various flags */ + unsigned int flags; /* various flags */ /* The following are for internal use only. Also see uapi/linux/nfs_mount.h */ #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000 -- 2.29.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] NFS: Add support for eager writes 2021-02-12 21:49 ` [PATCH 1/3] NFS: 'flags' field should be unsigned in struct nfs_server trondmy @ 2021-02-12 21:49 ` trondmy 2021-02-12 21:49 ` [PATCH 3/3] NFS: Add mount options supporting " trondmy 0 siblings, 1 reply; 6+ messages in thread From: trondmy @ 2021-02-12 21:49 UTC (permalink / raw) To: Anna Schumaker; +Cc: linux-nfs From: Trond Myklebust <trond.myklebust@hammerspace.com> Support eager writing to the server, meaning that we write the data to cache on the server, and wait for that to complete. This ensures that we see ENOSPC errors immediately. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> --- fs/nfs/file.c | 19 +++++++++++++++++-- fs/nfs/write.c | 17 ++++++++++++----- include/linux/nfs_fs_sb.h | 2 ++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 03fd1dcc96bd..16ad5050e046 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -606,8 +606,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - unsigned long written = 0; - ssize_t result; + unsigned int mntflags = NFS_SERVER(inode)->flags; + ssize_t result, written; errseq_t since; int error; @@ -648,6 +648,21 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) written = result; iocb->ki_pos += written; + + if (mntflags & NFS_MOUNT_WRITE_EAGER) { + result = filemap_fdatawrite_range(file->f_mapping, + iocb->ki_pos - written, + iocb->ki_pos - 1); + if (result < 0) + goto out; + } + if (mntflags & NFS_MOUNT_WRITE_WAIT) { + result = filemap_fdatawait_range(file->f_mapping, + iocb->ki_pos - written, + iocb->ki_pos - 1); + if (result < 0) + goto out; + } result = generic_write_sync(iocb, written); if (result < 0) goto out; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 6193350356a8..82bdcb982186 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -712,16 +712,23 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) { struct inode *inode = mapping->host; struct nfs_pageio_descriptor pgio; - struct nfs_io_completion *ioc; + struct nfs_io_completion *ioc = NULL; + unsigned int mntflags = NFS_SERVER(inode)->flags; + int priority = 0; int err; nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES); - ioc = nfs_io_completion_alloc(GFP_KERNEL); - if (ioc) - nfs_io_completion_init(ioc, nfs_io_completion_commit, inode); + if (!(mntflags & NFS_MOUNT_WRITE_EAGER) || wbc->for_kupdate || + wbc->for_background || wbc->for_sync || wbc->for_reclaim) { + ioc = nfs_io_completion_alloc(GFP_KERNEL); + if (ioc) + nfs_io_completion_init(ioc, nfs_io_completion_commit, + inode); + priority = wb_priority(wbc); + } - nfs_pageio_init_write(&pgio, inode, wb_priority(wbc), false, + nfs_pageio_init_write(&pgio, inode, priority, false, &nfs_async_write_completion_ops); pgio.pg_io_completion = ioc; err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 962e8313f007..6f76b32a0238 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -153,6 +153,8 @@ struct nfs_server { #define NFS_MOUNT_LOCAL_FCNTL 0x200000 #define NFS_MOUNT_SOFTERR 0x400000 #define NFS_MOUNT_SOFTREVAL 0x800000 +#define NFS_MOUNT_WRITE_EAGER 0x01000000 +#define NFS_MOUNT_WRITE_WAIT 0x02000000 unsigned int caps; /* server capabilities */ unsigned int rsize; /* read size */ -- 2.29.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] NFS: Add mount options supporting eager writes 2021-02-12 21:49 ` [PATCH 2/3] NFS: Add support for eager writes trondmy @ 2021-02-12 21:49 ` trondmy 0 siblings, 0 replies; 6+ messages in thread From: trondmy @ 2021-02-12 21:49 UTC (permalink / raw) To: Anna Schumaker; +Cc: linux-nfs From: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> --- fs/nfs/fs_context.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 06894bcdea2d..b6be02aa79f0 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -82,6 +82,7 @@ enum nfs_param { Opt_v, Opt_vers, Opt_wsize, + Opt_write, }; enum { @@ -113,6 +114,19 @@ static const struct constant_table nfs_param_enums_lookupcache[] = { {} }; +enum { + Opt_write_lazy, + Opt_write_eager, + Opt_write_wait, +}; + +static const struct constant_table nfs_param_enums_write[] = { + { "lazy", Opt_write_lazy }, + { "eager", Opt_write_eager }, + { "wait", Opt_write_wait }, + {} +}; + static const struct fs_parameter_spec nfs_fs_parameters[] = { fsparam_flag_no("ac", Opt_ac), fsparam_u32 ("acdirmax", Opt_acdirmax), @@ -171,6 +185,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = { fsparam_flag ("v4.1", Opt_v), fsparam_flag ("v4.2", Opt_v), fsparam_string("vers", Opt_vers), + fsparam_enum ("write", Opt_write, nfs_param_enums_write), fsparam_u32 ("wsize", Opt_wsize), {} }; @@ -770,6 +785,24 @@ static int nfs_fs_context_parse_param(struct fs_context *fc, goto out_invalid_value; } break; + case Opt_write: + switch (result.uint_32) { + case Opt_write_lazy: + ctx->flags &= + ~(NFS_MOUNT_WRITE_EAGER | NFS_MOUNT_WRITE_WAIT); + break; + case Opt_write_eager: + ctx->flags |= NFS_MOUNT_WRITE_EAGER; + ctx->flags &= ~NFS_MOUNT_WRITE_WAIT; + break; + case Opt_write_wait: + ctx->flags |= + NFS_MOUNT_WRITE_EAGER | NFS_MOUNT_WRITE_WAIT; + break; + default: + goto out_invalid_value; + } + break; /* * Special options -- 2.29.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] Add a mount option to support eager writes 2021-02-12 21:49 [PATCH 0/3] Add a mount option to support eager writes trondmy 2021-02-12 21:49 ` [PATCH 1/3] NFS: 'flags' field should be unsigned in struct nfs_server trondmy @ 2021-02-13 14:19 ` Steve Dickson 2021-02-13 14:20 ` Trond Myklebust 1 sibling, 1 reply; 6+ messages in thread From: Steve Dickson @ 2021-02-13 14:19 UTC (permalink / raw) To: trondmy, Anna Schumaker; +Cc: linux-nfs Hey! On 2/12/21 4:49 PM, trondmy@kernel.org wrote: > From: Trond Myklebust <trond.myklebust@hammerspace.com> > > The following patch series sets up a new mount option > 'writes=lazy/eager/wait'. The mount option basically controls how the > write() system call works. > - writes=lazy is the default, and keeps the current behaviour > - writes=eager means we send off the write immediately as an unstable > write to the server. > - writes=wait means we send off the write as an unstable write, and then > wait for the reply. > > The main motivator for this behaviour is that some applications expect > write() to return ENOSPC. Setting writes=wait should satisfy those > applications without taking the full overhead of a synchronous write. > > writes=eager, on the other hand, can be useful for applications such as > re-exporting NFS, since it would allow knfsd on the proxying server to > immediately forward the writes to the original server. > > Trond Myklebust (3): > NFS: 'flags' field should be unsigned in struct nfs_server > NFS: Add support for eager writes > NFS: Add mount options supporting eager writes > > fs/nfs/file.c | 19 +++++++++++++++++-- > fs/nfs/fs_context.c | 33 +++++++++++++++++++++++++++++++++ > fs/nfs/write.c | 17 ++++++++++++----- > include/linux/nfs_fs_sb.h | 4 +++- > 4 files changed, 65 insertions(+), 8 deletions(-) > Shouldn't something be added to the nfs(5) man page as well as blurb added to /etc/nfsmount.conf file? steved. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] Add a mount option to support eager writes 2021-02-13 14:19 ` [PATCH 0/3] Add a mount option to support " Steve Dickson @ 2021-02-13 14:20 ` Trond Myklebust 0 siblings, 0 replies; 6+ messages in thread From: Trond Myklebust @ 2021-02-13 14:20 UTC (permalink / raw) To: SteveD@RedHat.com, anna.schumaker@netapp.com; +Cc: linux-nfs@vger.kernel.org On Sat, 2021-02-13 at 09:19 -0500, Steve Dickson wrote: > Hey! > > On 2/12/21 4:49 PM, trondmy@kernel.org wrote: > > From: Trond Myklebust <trond.myklebust@hammerspace.com> > > > > The following patch series sets up a new mount option > > 'writes=lazy/eager/wait'. The mount option basically controls how > > the > > write() system call works. > > - writes=lazy is the default, and keeps the current behaviour > > - writes=eager means we send off the write immediately as an > > unstable > > write to the server. > > - writes=wait means we send off the write as an unstable write, and > > then > > wait for the reply. > > > > The main motivator for this behaviour is that some applications > > expect > > write() to return ENOSPC. Setting writes=wait should satisfy those > > applications without taking the full overhead of a synchronous > > write. > > > > writes=eager, on the other hand, can be useful for applications > > such as > > re-exporting NFS, since it would allow knfsd on the proxying server > > to > > immediately forward the writes to the original server. > > > > Trond Myklebust (3): > > NFS: 'flags' field should be unsigned in struct nfs_server > > NFS: Add support for eager writes > > NFS: Add mount options supporting eager writes > > > > fs/nfs/file.c | 19 +++++++++++++++++-- > > fs/nfs/fs_context.c | 33 +++++++++++++++++++++++++++++++++ > > fs/nfs/write.c | 17 ++++++++++++----- > > include/linux/nfs_fs_sb.h | 4 +++- > > 4 files changed, 65 insertions(+), 8 deletions(-) > > > Shouldn't something be added to the nfs(5) man page > as well as blurb added to /etc/nfsmount.conf file? > Sure, but I'd like comments/consensus on the kernel bits first. 🙂 Cheers Trond -- Trond Myklebust Linux NFS client maintainer, Hammerspace trond.myklebust@hammerspace.com ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-02-13 14:21 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-02-12 21:49 [PATCH 0/3] Add a mount option to support eager writes trondmy 2021-02-12 21:49 ` [PATCH 1/3] NFS: 'flags' field should be unsigned in struct nfs_server trondmy 2021-02-12 21:49 ` [PATCH 2/3] NFS: Add support for eager writes trondmy 2021-02-12 21:49 ` [PATCH 3/3] NFS: Add mount options supporting " trondmy 2021-02-13 14:19 ` [PATCH 0/3] Add a mount option to support " Steve Dickson 2021-02-13 14:20 ` Trond Myklebust
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox