mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-29 12:47:47 -04:00
pNFS: Stricter ordering of layoutget and layoutreturn
If a layout return is in progress, we should wait for it to complete,
in case the layout segment we are picking up gets returned too.
Fixes: 30cb3ee299 ("pNFS: Handle NFS4ERR_OLD_STATEID on layoutreturn by bumping the state seqid")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
@@ -2018,6 +2018,27 @@ pnfs_update_layout(struct inode *ino,
|
|||||||
goto lookup_again;
|
goto lookup_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because we free lsegs when sending LAYOUTRETURN, we need to wait
|
||||||
|
* for LAYOUTRETURN.
|
||||||
|
*/
|
||||||
|
if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
|
||||||
|
spin_unlock(&ino->i_lock);
|
||||||
|
dprintk("%s wait for layoutreturn\n", __func__);
|
||||||
|
lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo));
|
||||||
|
if (!IS_ERR(lseg)) {
|
||||||
|
pnfs_put_layout_hdr(lo);
|
||||||
|
dprintk("%s retrying\n", __func__);
|
||||||
|
trace_pnfs_update_layout(ino, pos, count, iomode, lo,
|
||||||
|
lseg,
|
||||||
|
PNFS_UPDATE_LAYOUT_RETRY);
|
||||||
|
goto lookup_again;
|
||||||
|
}
|
||||||
|
trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
|
||||||
|
PNFS_UPDATE_LAYOUT_RETURN);
|
||||||
|
goto out_put_layout_hdr;
|
||||||
|
}
|
||||||
|
|
||||||
lseg = pnfs_find_lseg(lo, &arg, strict_iomode);
|
lseg = pnfs_find_lseg(lo, &arg, strict_iomode);
|
||||||
if (lseg) {
|
if (lseg) {
|
||||||
trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
|
trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
|
||||||
@@ -2070,28 +2091,6 @@ pnfs_update_layout(struct inode *ino,
|
|||||||
nfs4_stateid_copy(&stateid, &lo->plh_stateid);
|
nfs4_stateid_copy(&stateid, &lo->plh_stateid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Because we free lsegs before sending LAYOUTRETURN, we need to wait
|
|
||||||
* for LAYOUTRETURN even if first is true.
|
|
||||||
*/
|
|
||||||
if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
|
|
||||||
spin_unlock(&ino->i_lock);
|
|
||||||
dprintk("%s wait for layoutreturn\n", __func__);
|
|
||||||
lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo));
|
|
||||||
if (!IS_ERR(lseg)) {
|
|
||||||
if (first)
|
|
||||||
pnfs_clear_first_layoutget(lo);
|
|
||||||
pnfs_put_layout_hdr(lo);
|
|
||||||
dprintk("%s retrying\n", __func__);
|
|
||||||
trace_pnfs_update_layout(ino, pos, count, iomode, lo,
|
|
||||||
lseg, PNFS_UPDATE_LAYOUT_RETRY);
|
|
||||||
goto lookup_again;
|
|
||||||
}
|
|
||||||
trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
|
|
||||||
PNFS_UPDATE_LAYOUT_RETURN);
|
|
||||||
goto out_put_layout_hdr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pnfs_layoutgets_blocked(lo)) {
|
if (pnfs_layoutgets_blocked(lo)) {
|
||||||
trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
|
trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
|
||||||
PNFS_UPDATE_LAYOUT_BLOCKED);
|
PNFS_UPDATE_LAYOUT_BLOCKED);
|
||||||
|
|||||||
Reference in New Issue
Block a user