aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-10-17 17:54:32 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-09 02:32:24 -0500
commit24b049fa0cd93e9e3e4166de8937b197b101a585 (patch)
treec90752302bc1e884eb4319ce62aee5bb46eed619 /fs
parentb775b86a5fe8f45500ce027a60ca0f1e1f49a13e (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.c6
-rw-r--r--fs/nfs/pnfs.h1
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,
944void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) 944void 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 */