FAILED: patch "[PATCH] nfs4: resend LAYOUTGET when there is a race that changes the" failed to apply to 4.2-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.2-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
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: [PATCH] nfs4: resend LAYOUTGET when there is a race that changes the
seqid
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 +31 -25
@@ -872,33 +872,38 @@ send_layoutget(struct pnfs_layout_hdr *lo,dprintk ("--> %s\n" , __func__); - lgp =kzalloc (sizeof (*lgp), gfp_flags); -if (lgp ==NULL ) -return NULL ; +/* +* 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; - i_size =i_size_read (ino); + lseg =nfs4_proc_layoutget (lgp, gfp_flags); + }while (lseg ==ERR_PTR (-EAGAIN )); - 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; - -/* 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_layoutget *lgp)/* 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);