Commit 0b77f97a authored by Trond Myklebust's avatar Trond Myklebust

NFSv4/pnfs: Fix layoutget behaviour after invalidation

If the layout gets invalidated, we should wait for any outstanding
layoutget requests for that layout to complete, and we should resend
them only after re-establishing the layout stateid.

Fixes: d29b468d ("pNFS/NFSv4: Improve rejection of out-of-order layouts")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent aa95edf3
...@@ -2014,7 +2014,7 @@ pnfs_update_layout(struct inode *ino, ...@@ -2014,7 +2014,7 @@ pnfs_update_layout(struct inode *ino,
* If the layout segment list is empty, but there are outstanding * If the layout segment list is empty, but there are outstanding
* layoutget calls, then they might be subject to a layoutrecall. * layoutget calls, then they might be subject to a layoutrecall.
*/ */
if (list_empty(&lo->plh_segs) && if ((list_empty(&lo->plh_segs) || !pnfs_layout_is_valid(lo)) &&
atomic_read(&lo->plh_outstanding) != 0) { atomic_read(&lo->plh_outstanding) != 0) {
spin_unlock(&ino->i_lock); spin_unlock(&ino->i_lock);
lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding, lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding,
...@@ -2390,11 +2390,13 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -2390,11 +2390,13 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
goto out_forget; goto out_forget;
} }
if (!pnfs_layout_is_valid(lo) && !pnfs_is_first_layoutget(lo))
goto out_forget;
if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
/* 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)) {
if (!pnfs_layout_is_valid(lo) && if (!pnfs_layout_is_valid(lo))
pnfs_is_first_layoutget(lo))
lo->plh_barrier = 0; lo->plh_barrier = 0;
dprintk("%s forget reply due to sequence\n", __func__); dprintk("%s forget reply due to sequence\n", __func__);
goto out_forget; goto out_forget;
...@@ -2413,8 +2415,6 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -2413,8 +2415,6 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
goto out_forget; goto out_forget;
} else { } else {
/* We have a completely new layout */ /* We have a completely new layout */
if (!pnfs_is_first_layoutget(lo))
goto out_forget;
pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true); pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true);
} }
......
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