Patch "nfs4: resend LAYOUTGET when there is a race that changes the seqid" has been added to the 4.3-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
nfs4: resend LAYOUTGET when there is a race that changes the seqid
to the 4.3-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
nfs4-resend-layoutget-when-there-is-a-race-that-changes-the-seqid.patch
and it can be found in the queue-4.3 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
4f2e9dce0c6348a95eaa56ade9bab18572221088Mon Sep 17 00:00:00 2001
From: Jeff Layton <[email protected]>
Date: Wed, 25 Nov 2015 13:43:14 -0500
Subject: nfs4: resend LAYOUTGET when there is a race that changes the seqid
From: Jeff Layton <[email protected]>
commit 4f2e9dce0c6348a95eaa56ade9bab18572221088 upstream.
pnfs_layout_process will check the returned layout stateid against what the kernel has in-core. If it turns out that the stateid we received is older, then we should resend the LAYOUTGET instead of falling back to MDS I/O.
--- fs/nfs/pnfs.c | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-)
fs/nfs/pnfs.c +31 -25
@@ -872,33 +872,38 @@ send_layoutget(struct pnfs_layout_hdr *ldprintk ("--> %s\n" , __func__); - lgp =kzalloc (sizeof (*lgp), gfp_flags); -if (lgp ==NULL ) -return NULL ; - - i_size =i_size_read (ino); +/* +* Synchronously retrieve layout information from server and +* store in lseg. If we race with a concurrent seqid morphing +* op, then re-send the LAYOUTGET. +*/ +do { + lgp =kzalloc (sizeof (*lgp), gfp_flags); +if (lgp ==NULL ) +return NULL ; + + i_size =i_size_read (ino); + + lgp->args.minlength =PAGE_CACHE_SIZE ; +if (lgp->args.minlength > range->length) + lgp->args.minlength = range->length; +if (range->iomode ==IOMODE_READ ) { +if (range->offset >= i_size) + lgp->args.minlength =0 ; +else if (i_size - range->offset < lgp->args.minlength) + lgp->args.minlength = i_size - range->offset; + } + lgp->args.maxcount =PNFS_LAYOUT_MAXSIZE ; + lgp->args.range = *range; + lgp->args.type = server->pnfs_curr_ld->id; + lgp->args.inode = ino; + lgp->args.ctx =get_nfs_open_context (ctx); + lgp->gfp_flags = gfp_flags; + lgp->cred = lo->plh_lc_cred; - lgp->args.minlength =PAGE_CACHE_SIZE ; -if (lgp->args.minlength > range->length) - lgp->args.minlength = range->length; -if (range->iomode ==IOMODE_READ ) { -if (range->offset >= i_size) - lgp->args.minlength =0 ; -else if (i_size - range->offset < lgp->args.minlength) - lgp->args.minlength = i_size - range->offset; - } - lgp->args.maxcount =PNFS_LAYOUT_MAXSIZE ; - lgp->args.range = *range; - lgp->args.type = server->pnfs_curr_ld->id; - lgp->args.inode = ino; - lgp->args.ctx =get_nfs_open_context (ctx); - lgp->gfp_flags = gfp_flags; - lgp->cred = lo->plh_lc_cred; + lseg =nfs4_proc_layoutget (lgp, gfp_flags); + }while (lseg ==ERR_PTR (-EAGAIN )); -/* Synchronously retrieve layout information from server and -* store in lseg. -*/ - lseg =nfs4_proc_layoutget (lgp, gfp_flags);if (IS_ERR (lseg)) {switch (PTR_ERR (lseg)) {case -ENOMEM :
@@ -1687,6 +1692,7 @@ pnfs_layout_process(struct nfs4_layoutge/* existing state ID, make sure the sequence number matches. */ if (pnfs_layout_stateid_blocked (lo, &res->stateid)) {dprintk ("%s forget reply due to sequence\n" , __func__); + status = -EAGAIN ; goto out_forget_reply; }pnfs_set_layout_stateid (lo, &res->stateid, false);
Patches currently in stable-queue which might be from [email protected] are
queue-4.3/nfs-if-we-have-no-valid-attrs-then-don-t-declare-the-attribute-cache-valid.patch queue-4.3/nfsd-serialize-state-seqid-morphing-operations.patch queue-4.3/nfs4-resend-layoutget-when-there-is-a-race-that-changes-the-seqid.patch