summaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-10-17 17:54:32 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-12-01 17:21:40 -0500
commit6604b203fb6394ed1f24c21bfa3c207e5ae8e461 (patch)
treeaf5022c5b4bb52bb69626dbfb13bc020d7bcae2a /fs/nfs/pnfs.c
parent9888d837f3cf6b1f38f7717ab58236f94123ca19 (diff)
pNFS: On error, do not send LAYOUTGET until the LAYOUTRETURN has completed
If there is an I/O error, we should not call LAYOUTGET until the LAYOUTRETURN that reports the error is complete. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Cc: stable@vger.kernel.org # v4.8+
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 9b7e88b7edfc..06bfcd277006 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -947,6 +947,7 @@ static void pnfs_clear_layoutcommit(struct inode *inode,
947void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) 947void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
948{ 948{
949 clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags); 949 clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags);
950 clear_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags);
950 smp_mb__after_atomic(); 951 smp_mb__after_atomic();
951 wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN); 952 wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
952 rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq); 953 rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
@@ -960,8 +961,9 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
960 /* Serialise LAYOUTGET/LAYOUTRETURN */ 961 /* Serialise LAYOUTGET/LAYOUTRETURN */
961 if (atomic_read(&lo->plh_outstanding) != 0) 962 if (atomic_read(&lo->plh_outstanding) != 0)
962 return false; 963 return false;
963 if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) 964 if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
964 return false; 965 return false;
966 set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
965 pnfs_get_layout_hdr(lo); 967 pnfs_get_layout_hdr(lo);
966 if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) { 968 if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) {
967 if (stateid != NULL) { 969 if (stateid != NULL) {
@@ -1954,6 +1956,8 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
1954 1956
1955 spin_lock(&inode->i_lock); 1957 spin_lock(&inode->i_lock);
1956 pnfs_set_plh_return_info(lo, range.iomode, 0); 1958 pnfs_set_plh_return_info(lo, range.iomode, 0);
1959 /* Block LAYOUTGET */
1960 set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
1957 /* 1961 /*
1958 * mark all matching lsegs so that we are sure to have no live 1962 * mark all matching lsegs so that we are sure to have no live
1959 * segments at hand when sending layoutreturn. See pnfs_put_lseg() 1963 * segments at hand when sending layoutreturn. See pnfs_put_lseg()