Commit 4f2e9dce authored by Jeff Layton's avatar Jeff Layton Committed by Trond Myklebust

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.
Signed-off-by: default avatarJeff Layton <jeff.layton@primarydata.com>
Cc: stable@vger.kernel.org # 3.18+
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent c812012f
...@@ -872,6 +872,12 @@ send_layoutget(struct pnfs_layout_hdr *lo, ...@@ -872,6 +872,12 @@ send_layoutget(struct pnfs_layout_hdr *lo,
dprintk("--> %s\n", __func__); dprintk("--> %s\n", __func__);
/*
* 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); lgp = kzalloc(sizeof(*lgp), gfp_flags);
if (lgp == NULL) if (lgp == NULL)
return NULL; return NULL;
...@@ -895,10 +901,9 @@ send_layoutget(struct pnfs_layout_hdr *lo, ...@@ -895,10 +901,9 @@ send_layoutget(struct pnfs_layout_hdr *lo,
lgp->gfp_flags = gfp_flags; lgp->gfp_flags = gfp_flags;
lgp->cred = lo->plh_lc_cred; lgp->cred = lo->plh_lc_cred;
/* Synchronously retrieve layout information from server and
* store in lseg.
*/
lseg = nfs4_proc_layoutget(lgp, gfp_flags); lseg = nfs4_proc_layoutget(lgp, gfp_flags);
} while (lseg == ERR_PTR(-EAGAIN));
if (IS_ERR(lseg)) { if (IS_ERR(lseg)) {
switch (PTR_ERR(lseg)) { switch (PTR_ERR(lseg)) {
case -ENOMEM: case -ENOMEM:
...@@ -1687,6 +1692,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1687,6 +1692,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
/* existing state ID, make sure the sequence number matches. */ /* existing state ID, make sure the sequence number matches. */
if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
dprintk("%s forget reply due to sequence\n", __func__); dprintk("%s forget reply due to sequence\n", __func__);
status = -EAGAIN;
goto out_forget_reply; goto out_forget_reply;
} }
pnfs_set_layout_stateid(lo, &res->stateid, false); pnfs_set_layout_stateid(lo, &res->stateid, false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment