diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-10-17 17:54:32 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-12-01 17:21:40 -0500 |
commit | 6604b203fb6394ed1f24c21bfa3c207e5ae8e461 (patch) | |
tree | af5022c5b4bb52bb69626dbfb13bc020d7bcae2a /fs/nfs/pnfs.c | |
parent | 9888d837f3cf6b1f38f7717ab58236f94123ca19 (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.c | 6 |
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, | |||
947 | void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) | 947 | void 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() |