summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-12-05 17:33:07 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-12-05 22:52:01 -0500
commit362fb578a573adeb67aa4790d901d851b8f8c8f3 (patch)
tree2e25b7ea922b4f8ae2c88978d1fd37c877bc3415
parentd94cbf6c73324a008dfb8576f15d089d7f707f24 (diff)
downloadlinux-362fb578a573adeb67aa4790d901d851b8f8c8f3.tar.gz
linux-362fb578a573adeb67aa4790d901d851b8f8c8f3.tar.bz2
linux-362fb578a573adeb67aa4790d901d851b8f8c8f3.zip
pNFS: Release NFS_LAYOUT_RETURN when invalidating the layout stateid
Ensure we release the NFS_LAYOUT_RETURN lock when we invalidate the layout stateid, so that processes and RPC tasks that are waiting on the layout return can continue. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/pnfs.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 2a3431314c23..896df7bdf85f 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -327,6 +327,15 @@ pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo)
clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
}
+static void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
+{
+ clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags);
+ clear_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags);
+ smp_mb__after_atomic();
+ wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
+ rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
+}
+
static void
pnfs_clear_lseg_state(struct pnfs_layout_segment *lseg,
struct list_head *free_me)
@@ -362,6 +371,9 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
pnfs_clear_lseg_state(lseg, lseg_list);
pnfs_free_returned_lsegs(lo, lseg_list, &range, 0);
+ if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags) &&
+ !test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
+ pnfs_clear_layoutreturn_waitbit(lo);
return !list_empty(&lo->plh_segs);
}
@@ -984,15 +996,6 @@ static void pnfs_clear_layoutcommit(struct inode *inode,
}
}
-static void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
-{
- clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags);
- clear_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags);
- smp_mb__after_atomic();
- wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
- rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
-}
-
void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
const nfs4_stateid *arg_stateid,
const struct pnfs_layout_range *range,