diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-10-17 17:54:32 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-09 02:32:24 -0500 |
commit | 24b049fa0cd93e9e3e4166de8937b197b101a585 (patch) | |
tree | c90752302bc1e884eb4319ce62aee5bb46eed619 /fs | |
parent | b775b86a5fe8f45500ce027a60ca0f1e1f49a13e (diff) |
pNFS: On error, do not send LAYOUTGET until the LAYOUTRETURN has completed
commit 6604b203fb6394ed1f24c21bfa3c207e5ae8e461 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/pnfs.c | 6 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 1 |
2 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 259ef85f435a..d3eb4d7f0cbc 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -944,6 +944,7 @@ static void pnfs_clear_layoutcommit(struct inode *inode, | |||
944 | void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) | 944 | void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) |
945 | { | 945 | { |
946 | clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags); | 946 | clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags); |
947 | clear_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags); | ||
947 | smp_mb__after_atomic(); | 948 | smp_mb__after_atomic(); |
948 | wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN); | 949 | wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN); |
949 | rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq); | 950 | rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq); |
@@ -957,8 +958,9 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, | |||
957 | /* Serialise LAYOUTGET/LAYOUTRETURN */ | 958 | /* Serialise LAYOUTGET/LAYOUTRETURN */ |
958 | if (atomic_read(&lo->plh_outstanding) != 0) | 959 | if (atomic_read(&lo->plh_outstanding) != 0) |
959 | return false; | 960 | return false; |
960 | if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) | 961 | if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) |
961 | return false; | 962 | return false; |
963 | set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); | ||
962 | pnfs_get_layout_hdr(lo); | 964 | pnfs_get_layout_hdr(lo); |
963 | if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) { | 965 | if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) { |
964 | if (stateid != NULL) { | 966 | if (stateid != NULL) { |
@@ -1950,6 +1952,8 @@ void pnfs_error_mark_layout_for_return(struct inode *inode, | |||
1950 | 1952 | ||
1951 | spin_lock(&inode->i_lock); | 1953 | spin_lock(&inode->i_lock); |
1952 | pnfs_set_plh_return_info(lo, range.iomode, 0); | 1954 | pnfs_set_plh_return_info(lo, range.iomode, 0); |
1955 | /* Block LAYOUTGET */ | ||
1956 | set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); | ||
1953 | /* | 1957 | /* |
1954 | * mark all matching lsegs so that we are sure to have no live | 1958 | * mark all matching lsegs so that we are sure to have no live |
1955 | * segments at hand when sending layoutreturn. See pnfs_put_lseg() | 1959 | * segments at hand when sending layoutreturn. See pnfs_put_lseg() |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 5c295512c967..44cad8afda0e 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -96,6 +96,7 @@ enum { | |||
96 | NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ | 96 | NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ |
97 | NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ | 97 | NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ |
98 | NFS_LAYOUT_RETURN, /* layoutreturn in progress */ | 98 | NFS_LAYOUT_RETURN, /* layoutreturn in progress */ |
99 | NFS_LAYOUT_RETURN_LOCK, /* Serialise layoutreturn */ | ||
99 | NFS_LAYOUT_RETURN_REQUESTED, /* Return this layout ASAP */ | 100 | NFS_LAYOUT_RETURN_REQUESTED, /* Return this layout ASAP */ |
100 | NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ | 101 | NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ |
101 | NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ | 102 | NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ |