aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2018-06-23 16:55:37 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-07-26 16:25:25 -0400
commitf0b429819b5fbcedd1be15da7277292a0431ddd0 (patch)
treeb4d7f32117d3f714a397b59dff8cbea623fcd60a /fs
parentpNFS: Don't update the stateid when replying NFS4ERR_DELAY to a layout recall (diff)
downloadlinux-dev-f0b429819b5fbcedd1be15da7277292a0431ddd0.tar.xz
linux-dev-f0b429819b5fbcedd1be15da7277292a0431ddd0.zip
pNFS: Ignore non-recalled layouts in pnfs_layout_need_return()
If a layout has been recalled, then we should fire off a layoutreturn as soon as all the layout segments that match the recall have been retired. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/pnfs.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 17776ef734d7..bf7f0b21066d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1160,12 +1160,21 @@ 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;
- /* Defer layoutreturn until all lsegs are done */
+ 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;
}