pNFS: Release NFS_LAYOUT_RETURN when invalidating the layout stateid
authorTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 5 Dec 2016 22:33:07 +0000 (17:33 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 6 Dec 2016 03:52:01 +0000 (22:52 -0500)
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>
fs/nfs/pnfs.c

index 2a3431314c236b2939cbae1f55feb914a61607f2..896df7bdf85f6c5a92b1c206cb799afea454c1e9 100644 (file)
@@ -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,