All of lore.kernel.org
 help / color / mirror / Atom feed
* [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, anna.schumaker; +Cc: linux-nfs

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.