| From d474f96104bd4377573526ebae2ee212205a6839 Mon Sep 17 00:00:00 2001 |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Date: Wed, 5 Aug 2020 09:03:56 -0400 |
| Subject: NFS: Don't return layout segments that are in use |
| |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| |
| commit d474f96104bd4377573526ebae2ee212205a6839 upstream. |
| |
| If the NFS_LAYOUT_RETURN_REQUESTED flag is set, we want to return the |
| layout as soon as possible, meaning that the affected layout segments |
| should be marked as invalid, and should no longer be in use for I/O. |
| |
| Fixes: f0b429819b5f ("pNFS: Ignore non-recalled layouts in pnfs_layout_need_return()") |
| Cc: stable@vger.kernel.org # v4.19+ |
| Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/nfs/pnfs.c | 34 +++++++++++++++------------------- |
| 1 file changed, 15 insertions(+), 19 deletions(-) |
| |
| --- a/fs/nfs/pnfs.c |
| +++ b/fs/nfs/pnfs.c |
| @@ -1226,31 +1226,27 @@ out: |
| return status; |
| } |
| |
| +static bool |
| +pnfs_layout_segments_returnable(struct pnfs_layout_hdr *lo, |
| + enum pnfs_iomode iomode, |
| + u32 seq) |
| +{ |
| + struct pnfs_layout_range recall_range = { |
| + .length = NFS4_MAX_UINT64, |
| + .iomode = iomode, |
| + }; |
| + return pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, |
| + &recall_range, seq) != -EBUSY; |
| +} |
| + |
| /* Return true if layoutreturn is needed */ |
| static bool |
| pnfs_layout_need_return(struct pnfs_layout_hdr *lo) |
| { |
| - struct pnfs_layout_segment *s; |
| - enum pnfs_iomode iomode; |
| - u32 seq; |
| - |
| if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) |
| return false; |
| - |
| - seq = lo->plh_return_seq; |
| - iomode = lo->plh_return_iomode; |
| - |
| - /* Defer layoutreturn until all recalled lsegs are done */ |
| - list_for_each_entry(s, &lo->plh_segs, pls_list) { |
| - if (seq && pnfs_seqid_is_newer(s->pls_seq, seq)) |
| - continue; |
| - if (iomode != IOMODE_ANY && s->pls_range.iomode != iomode) |
| - continue; |
| - if (test_bit(NFS_LSEG_LAYOUTRETURN, &s->pls_flags)) |
| - return false; |
| - } |
| - |
| - return true; |
| + return pnfs_layout_segments_returnable(lo, lo->plh_return_iomode, |
| + lo->plh_return_seq); |
| } |
| |
| static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo) |