| From c13e8fcbd1737a9dee827d0afb2854a651d432fb Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 2 Jul 2021 16:37:15 -0400 |
| Subject: NFSv4/pnfs: Fix the layout barrier update |
| |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| |
| [ Upstream commit aa95edf309ef31e2df4a37ebf0e5c2ca2a6772ab ] |
| |
| If we have multiple outstanding layoutget requests, the current code to |
| update the layout barrier assumes that the outstanding layout stateids |
| are updated in order. That's not necessarily the case. |
| |
| Instead of using the value of lo->plh_outstanding as a guesstimate for |
| the window of values we need to accept, just wait to update the window |
| until we're processing the last one. The intention here is just to |
| ensure that we don't process 2^31 seqid updates without also updating |
| the barrier. |
| |
| Fixes: 1bcf34fdac5f ("pNFS/NFSv4: Update the layout barrier when we schedule a layoutreturn") |
| Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/nfs/pnfs.c | 30 +++++++++++++++--------------- |
| 1 file changed, 15 insertions(+), 15 deletions(-) |
| |
| diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c |
| index a5e3628a5273..cd041ba6f0aa 100644 |
| --- a/fs/nfs/pnfs.c |
| +++ b/fs/nfs/pnfs.c |
| @@ -966,10 +966,8 @@ void |
| pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, |
| const struct cred *cred, bool update_barrier) |
| { |
| - u32 oldseq, newseq, new_barrier = 0; |
| - |
| - oldseq = be32_to_cpu(lo->plh_stateid.seqid); |
| - newseq = be32_to_cpu(new->seqid); |
| + u32 oldseq = be32_to_cpu(lo->plh_stateid.seqid); |
| + u32 newseq = be32_to_cpu(new->seqid); |
| |
| if (!pnfs_layout_is_valid(lo)) { |
| pnfs_set_layout_cred(lo, cred); |
| @@ -979,19 +977,21 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, |
| clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); |
| return; |
| } |
| - if (pnfs_seqid_is_newer(newseq, oldseq)) { |
| + |
| + if (pnfs_seqid_is_newer(newseq, oldseq)) |
| nfs4_stateid_copy(&lo->plh_stateid, new); |
| - /* |
| - * Because of wraparound, we want to keep the barrier |
| - * "close" to the current seqids. |
| - */ |
| - new_barrier = newseq - atomic_read(&lo->plh_outstanding); |
| - } |
| - if (update_barrier) |
| - new_barrier = be32_to_cpu(new->seqid); |
| - else if (new_barrier == 0) |
| + |
| + if (update_barrier) { |
| + pnfs_barrier_update(lo, newseq); |
| return; |
| - pnfs_barrier_update(lo, new_barrier); |
| + } |
| + /* |
| + * Because of wraparound, we want to keep the barrier |
| + * "close" to the current seqids. We really only want to |
| + * get here from a layoutget call. |
| + */ |
| + if (atomic_read(&lo->plh_outstanding) == 1) |
| + pnfs_barrier_update(lo, be32_to_cpu(lo->plh_stateid.seqid)); |
| } |
| |
| static bool |
| -- |
| 2.30.2 |
| |