|
|
@@ -947,6 +947,7 @@ static void pnfs_clear_layoutcommit(struct inode *inode,
|
|
|
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);
|
|
|
@@ -960,8 +961,9 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
|
|
|
/* 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) {
|
|
|
@@ -1954,6 +1956,8 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
|
|
|
|
|
|
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()
|