| From 7f3b4b3fad5cf44959099bbce120269d9928c63d Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 2 Jul 2021 19:48:41 -0400 |
| Subject: NFSv4/pnfs: Fix layoutget behaviour after invalidation |
| |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| |
| [ Upstream commit 0b77f97a7e42adc72bd566ff8cb733ea426f74f6 ] |
| |
| 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: d29b468da4f9 ("pNFS/NFSv4: Improve rejection of out-of-order layouts") |
| Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/nfs/pnfs.c | 10 +++++----- |
| 1 file changed, 5 insertions(+), 5 deletions(-) |
| |
| diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c |
| index cd041ba6f0aa..2da35a31508c 100644 |
| --- a/fs/nfs/pnfs.c |
| +++ b/fs/nfs/pnfs.c |
| @@ -2014,7 +2014,7 @@ lookup_again: |
| * If the layout segment list is empty, but there are outstanding |
| * 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) { |
| spin_unlock(&ino->i_lock); |
| lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding, |
| @@ -2390,11 +2390,13 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) |
| 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)) { |
| /* existing state ID, make sure the sequence number matches. */ |
| if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { |
| - if (!pnfs_layout_is_valid(lo) && |
| - pnfs_is_first_layoutget(lo)) |
| + if (!pnfs_layout_is_valid(lo)) |
| lo->plh_barrier = 0; |
| dprintk("%s forget reply due to sequence\n", __func__); |
| goto out_forget; |
| @@ -2415,8 +2417,6 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) |
| goto out_forget; |
| } else { |
| /* 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); |
| } |
| |
| -- |
| 2.30.2 |
| |