| From 6604b203fb6394ed1f24c21bfa3c207e5ae8e461 Mon Sep 17 00:00:00 2001 |
| From: Trond Myklebust <trond.myklebust@primarydata.com> |
| Date: Mon, 17 Oct 2016 17:54:32 -0400 |
| Subject: pNFS: On error, do not send LAYOUTGET until the LAYOUTRETURN has completed |
| |
| From: Trond Myklebust <trond.myklebust@primarydata.com> |
| |
| 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> |
| |
| --- |
| fs/nfs/pnfs.c | 6 +++++- |
| fs/nfs/pnfs.h | 1 + |
| 2 files changed, 6 insertions(+), 1 deletion(-) |
| |
| --- a/fs/nfs/pnfs.c |
| +++ b/fs/nfs/pnfs.c |
| @@ -897,6 +897,7 @@ static void pnfs_clear_layoutcommit(stru |
| 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); |
| @@ -910,8 +911,9 @@ pnfs_prepare_layoutreturn(struct pnfs_la |
| /* Serialise LAYOUTGET/LAYOUTRETURN */ |
| if (atomic_read(&lo->plh_outstanding) != 0) |
| return false; |
| - if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) |
| + if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) |
| return false; |
| + set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); |
| pnfs_get_layout_hdr(lo); |
| if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) { |
| if (stateid != NULL) { |
| @@ -1903,6 +1905,8 @@ void pnfs_error_mark_layout_for_return(s |
| |
| spin_lock(&inode->i_lock); |
| pnfs_set_plh_return_info(lo, range.iomode, 0); |
| + /* Block LAYOUTGET */ |
| + set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); |
| /* |
| * mark all matching lsegs so that we are sure to have no live |
| * segments at hand when sending layoutreturn. See pnfs_put_lseg() |
| --- a/fs/nfs/pnfs.h |
| +++ b/fs/nfs/pnfs.h |
| @@ -96,6 +96,7 @@ enum { |
| NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ |
| NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ |
| NFS_LAYOUT_RETURN, /* layoutreturn in progress */ |
| + NFS_LAYOUT_RETURN_LOCK, /* Serialise layoutreturn */ |
| NFS_LAYOUT_RETURN_REQUESTED, /* Return this layout ASAP */ |
| NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ |
| NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ |