linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit
@ 2025-07-15 15:32 Sergey Bashirov
  2025-07-15 15:32 ` [PATCH v2 1/3] NFSD: Minor cleanup in layoutcommit processing Sergey Bashirov
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Sergey Bashirov @ 2025-07-15 15:32 UTC (permalink / raw)
  To: Chuck Lever, Christoph Hellwig, Jeff Layton, NeilBrown,
	Olga Kornievskaia, Dai Ngo, Tom Talpey
  Cc: linux-nfs, linux-kernel, Konstantin Evtushenko, Sergey Bashirov

These patches correct the behavior of the pNFS server when the client
sends a layoutcommit without a new file size and with zero number of
block/scsi extents.

Tested manually for the pNFS block layout setup.

Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com>
---
Changes in v2:
 - The first cleanup patch is unchanged
 - Reworked main patch to guard entire new_size check, improved description
 - Added cleanup patch to decode lc_newoffset as bool

Sergey Bashirov (3):
  NFSD: Minor cleanup in layoutcommit processing
  NFSD: Fix last write offset handling in layoutcommit
  NFSD: Minor cleanup in layoutcommit decoding

 fs/nfsd/blocklayout.c |  5 ++---
 fs/nfsd/nfs4proc.c    | 34 ++++++++++++++--------------------
 fs/nfsd/nfs4xdr.c     |  2 +-
 3 files changed, 17 insertions(+), 24 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/3] NFSD: Minor cleanup in layoutcommit processing
  2025-07-15 15:32 [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
@ 2025-07-15 15:32 ` Sergey Bashirov
  2025-07-15 15:32 ` [PATCH v2 2/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Sergey Bashirov @ 2025-07-15 15:32 UTC (permalink / raw)
  To: Chuck Lever, Christoph Hellwig, Jeff Layton, NeilBrown,
	Olga Kornievskaia, Dai Ngo, Tom Talpey
  Cc: linux-nfs, linux-kernel, Konstantin Evtushenko, Sergey Bashirov,
	Christoph Hellwig

Remove dprintk in nfsd4_layoutcommit. These are not needed
in day to day usage, and the information is also available
in Wireshark when capturing NFS traffic.

Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/nfsd/nfs4proc.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 85ee486ce0caa..656b2e7d88407 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -2492,18 +2492,12 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
 	inode = d_inode(current_fh->fh_dentry);
 
 	nfserr = nfserr_inval;
-	if (new_size <= seg->offset) {
-		dprintk("pnfsd: last write before layout segment\n");
+	if (new_size <= seg->offset)
 		goto out;
-	}
-	if (new_size > seg->offset + seg->length) {
-		dprintk("pnfsd: last write beyond layout segment\n");
+	if (new_size > seg->offset + seg->length)
 		goto out;
-	}
-	if (!lcp->lc_newoffset && new_size > i_size_read(inode)) {
-		dprintk("pnfsd: layoutcommit beyond EOF\n");
+	if (!lcp->lc_newoffset && new_size > i_size_read(inode))
 		goto out;
-	}
 
 	nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lcp->lc_sid,
 						false, lcp->lc_layout_type,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/3] NFSD: Fix last write offset handling in layoutcommit
  2025-07-15 15:32 [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
  2025-07-15 15:32 ` [PATCH v2 1/3] NFSD: Minor cleanup in layoutcommit processing Sergey Bashirov
@ 2025-07-15 15:32 ` Sergey Bashirov
  2025-07-16 11:16   ` Christoph Hellwig
  2025-07-15 15:32 ` [PATCH v2 3/3] NFSD: Minor cleanup in layoutcommit decoding Sergey Bashirov
  2025-07-15 16:11 ` [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Chuck Lever
  3 siblings, 1 reply; 7+ messages in thread
From: Sergey Bashirov @ 2025-07-15 15:32 UTC (permalink / raw)
  To: Chuck Lever, Christoph Hellwig, Jeff Layton, NeilBrown,
	Olga Kornievskaia, Dai Ngo, Tom Talpey
  Cc: linux-nfs, linux-kernel, Konstantin Evtushenko, Sergey Bashirov

The data type of loca_last_write_offset is newoffset4 and is switched
on a boolean value, no_newoffset, that indicates if a previous write
occurred or not. If no_newoffset is FALSE, an offset is not given.
This means that client does not try to update the file size. Thus,
server should not try to calculate new file size and check if it fits
into the segment range. See RFC 8881, section 12.5.4.2.

Sometimes the current incorrect logic may cause clients to hang when
trying to sync an inode. If layoutcommit fails, the client marks the
inode as dirty again.

Fixes: 9cf514ccfacb ("nfsd: implement pNFS operations")

Co-developed-by: Konstantin Evtushenko <koevtushenko@yandex.com>
Signed-off-by: Konstantin Evtushenko <koevtushenko@yandex.com>
Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com>
---
 fs/nfsd/blocklayout.c |  5 ++---
 fs/nfsd/nfs4proc.c    | 30 +++++++++++++++---------------
 2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index 4c936132eb440..0822d8a119c6f 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -118,7 +118,6 @@ nfsd4_block_commit_blocks(struct inode *inode, struct nfsd4_layoutcommit *lcp,
 		struct iomap *iomaps, int nr_iomaps)
 {
 	struct timespec64 mtime = inode_get_mtime(inode);
-	loff_t new_size = lcp->lc_last_wr + 1;
 	struct iattr iattr = { .ia_valid = 0 };
 	int error;
 
@@ -128,9 +127,9 @@ nfsd4_block_commit_blocks(struct inode *inode, struct nfsd4_layoutcommit *lcp,
 	iattr.ia_valid |= ATTR_ATIME | ATTR_CTIME | ATTR_MTIME;
 	iattr.ia_atime = iattr.ia_ctime = iattr.ia_mtime = lcp->lc_mtime;
 
-	if (new_size > i_size_read(inode)) {
+	if (lcp->lc_size_chg) {
 		iattr.ia_valid |= ATTR_SIZE;
-		iattr.ia_size = new_size;
+		iattr.ia_size = lcp->lc_newsize;
 	}
 
 	error = inode->i_sb->s_export_op->commit_blocks(inode, iomaps,
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 656b2e7d88407..7043fc475458d 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -2475,7 +2475,6 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
 	const struct nfsd4_layout_seg *seg = &lcp->lc_seg;
 	struct svc_fh *current_fh = &cstate->current_fh;
 	const struct nfsd4_layout_ops *ops;
-	loff_t new_size = lcp->lc_last_wr + 1;
 	struct inode *inode;
 	struct nfs4_layout_stateid *ls;
 	__be32 nfserr;
@@ -2491,13 +2490,21 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
 		goto out;
 	inode = d_inode(current_fh->fh_dentry);
 
-	nfserr = nfserr_inval;
-	if (new_size <= seg->offset)
-		goto out;
-	if (new_size > seg->offset + seg->length)
-		goto out;
-	if (!lcp->lc_newoffset && new_size > i_size_read(inode))
-		goto out;
+	lcp->lc_size_chg = false;
+	if (lcp->lc_newoffset) {
+		loff_t new_size = lcp->lc_last_wr + 1;
+
+		nfserr = nfserr_inval;
+		if (new_size <= seg->offset)
+			goto out;
+		if (new_size > seg->offset + seg->length)
+			goto out;
+
+		if (new_size > i_size_read(inode)) {
+			lcp->lc_size_chg = true;
+			lcp->lc_newsize = new_size;
+		}
+	}
 
 	nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lcp->lc_sid,
 						false, lcp->lc_layout_type,
@@ -2513,13 +2520,6 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
 	/* LAYOUTCOMMIT does not require any serialization */
 	mutex_unlock(&ls->ls_mutex);
 
-	if (new_size > i_size_read(inode)) {
-		lcp->lc_size_chg = true;
-		lcp->lc_newsize = new_size;
-	} else {
-		lcp->lc_size_chg = false;
-	}
-
 	nfserr = ops->proc_layoutcommit(inode, rqstp, lcp);
 	nfs4_put_stid(&ls->ls_stid);
 out:
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/3] NFSD: Minor cleanup in layoutcommit decoding
  2025-07-15 15:32 [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
  2025-07-15 15:32 ` [PATCH v2 1/3] NFSD: Minor cleanup in layoutcommit processing Sergey Bashirov
  2025-07-15 15:32 ` [PATCH v2 2/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
@ 2025-07-15 15:32 ` Sergey Bashirov
  2025-07-16 11:16   ` Christoph Hellwig
  2025-07-15 16:11 ` [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Chuck Lever
  3 siblings, 1 reply; 7+ messages in thread
From: Sergey Bashirov @ 2025-07-15 15:32 UTC (permalink / raw)
  To: Chuck Lever, Christoph Hellwig, Jeff Layton, NeilBrown,
	Olga Kornievskaia, Dai Ngo, Tom Talpey
  Cc: linux-nfs, linux-kernel, Konstantin Evtushenko, Sergey Bashirov

Use the appropriate xdr function to decode the lc_newoffset field,
which is a boolean value. See RFC 8881, section 18.42.1.

Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com>
---
 fs/nfsd/nfs4xdr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 6479c1e3b7741..ca9e3321b6691 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1813,7 +1813,7 @@ nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
 	status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
 	if (status)
 		return status;
-	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_newoffset) < 0)
+	if (xdr_stream_decode_bool(argp->xdr, &lcp->lc_newoffset) < 0)
 		return nfserr_bad_xdr;
 	if (lcp->lc_newoffset) {
 		if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_last_wr) < 0)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit
  2025-07-15 15:32 [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
                   ` (2 preceding siblings ...)
  2025-07-15 15:32 ` [PATCH v2 3/3] NFSD: Minor cleanup in layoutcommit decoding Sergey Bashirov
@ 2025-07-15 16:11 ` Chuck Lever
  3 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2025-07-15 16:11 UTC (permalink / raw)
  To: Christoph Hellwig, Jeff Layton, NeilBrown, Olga Kornievskaia,
	Dai Ngo, Tom Talpey, Sergey Bashirov
  Cc: Chuck Lever, linux-nfs, linux-kernel, Konstantin Evtushenko

From: Chuck Lever <chuck.lever@oracle.com>

On Tue, 15 Jul 2025 18:32:17 +0300, Sergey Bashirov wrote:
> These patches correct the behavior of the pNFS server when the client
> sends a layoutcommit without a new file size and with zero number of
> block/scsi extents.
> 
> Tested manually for the pNFS block layout setup.
> 
> 
> [...]

Applied to nfsd-testing, thanks!

[1/3] NFSD: Minor cleanup in layoutcommit processing
      commit: 2c704299249eb847d0973e8f70e8e8002b805474
[2/3] NFSD: Fix last write offset handling in layoutcommit
      commit: c2c45de297adf669b306f41b0ea11ca7493b63af
[3/3] NFSD: Minor cleanup in layoutcommit decoding
      commit: d3f1ec60bc13851e19876205158a0107d998258d

--
Chuck Lever


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] NFSD: Fix last write offset handling in layoutcommit
  2025-07-15 15:32 ` [PATCH v2 2/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
@ 2025-07-16 11:16   ` Christoph Hellwig
  0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2025-07-16 11:16 UTC (permalink / raw)
  To: Sergey Bashirov
  Cc: Chuck Lever, Christoph Hellwig, Jeff Layton, NeilBrown,
	Olga Kornievskaia, Dai Ngo, Tom Talpey, linux-nfs, linux-kernel,
	Konstantin Evtushenko

On Tue, Jul 15, 2025 at 06:32:19PM +0300, Sergey Bashirov wrote:
> The data type of loca_last_write_offset is newoffset4 and is switched
> on a boolean value, no_newoffset, that indicates if a previous write
> occurred or not. If no_newoffset is FALSE, an offset is not given.
> This means that client does not try to update the file size. Thus,
> server should not try to calculate new file size and check if it fits
> into the segment range. See RFC 8881, section 12.5.4.2.
> 
> Sometimes the current incorrect logic may cause clients to hang when
> trying to sync an inode. If layoutcommit fails, the client marks the
> inode as dirty again.
> 
> Fixes: 9cf514ccfacb ("nfsd: implement pNFS operations")
> 
> Co-developed-by: Konstantin Evtushenko <koevtushenko@yandex.com>

Nit: The tag should directly follow the Fixes line without whitespaces.

Otherwise looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 3/3] NFSD: Minor cleanup in layoutcommit decoding
  2025-07-15 15:32 ` [PATCH v2 3/3] NFSD: Minor cleanup in layoutcommit decoding Sergey Bashirov
@ 2025-07-16 11:16   ` Christoph Hellwig
  0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2025-07-16 11:16 UTC (permalink / raw)
  To: Sergey Bashirov
  Cc: Chuck Lever, Christoph Hellwig, Jeff Layton, NeilBrown,
	Olga Kornievskaia, Dai Ngo, Tom Talpey, linux-nfs, linux-kernel,
	Konstantin Evtushenko

On Tue, Jul 15, 2025 at 06:32:20PM +0300, Sergey Bashirov wrote:
> Use the appropriate xdr function to decode the lc_newoffset field,
> which is a boolean value. See RFC 8881, section 18.42.1.

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-07-16 11:16 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-15 15:32 [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
2025-07-15 15:32 ` [PATCH v2 1/3] NFSD: Minor cleanup in layoutcommit processing Sergey Bashirov
2025-07-15 15:32 ` [PATCH v2 2/3] NFSD: Fix last write offset handling in layoutcommit Sergey Bashirov
2025-07-16 11:16   ` Christoph Hellwig
2025-07-15 15:32 ` [PATCH v2 3/3] NFSD: Minor cleanup in layoutcommit decoding Sergey Bashirov
2025-07-16 11:16   ` Christoph Hellwig
2025-07-15 16:11 ` [PATCH v2 0/3] NFSD: Fix last write offset handling in layoutcommit Chuck Lever

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).