pnfs: Fix handling of NFS4ERR_OLD_STATEID replies to layoutreturn
If the server tells us that out layoutreturn raced with another layout update, then we must ensure that the new layout segments are not in use before we resend with an updated layout stateid. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
committed by
Anna Schumaker
parent
8d4fb8ff42
commit
c16467dc03
@ -361,18 +361,29 @@ pnfs_clear_lseg_state(struct pnfs_layout_segment *lseg,
|
||||
/*
|
||||
* Update the seqid of a layout stateid
|
||||
*/
|
||||
bool nfs4_refresh_layout_stateid(nfs4_stateid *dst, struct inode *inode)
|
||||
bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst, struct inode *inode)
|
||||
{
|
||||
struct pnfs_layout_hdr *lo;
|
||||
struct pnfs_layout_range range = {
|
||||
.iomode = IOMODE_ANY,
|
||||
.offset = 0,
|
||||
.length = NFS4_MAX_UINT64,
|
||||
};
|
||||
bool ret = false;
|
||||
LIST_HEAD(head);
|
||||
int err;
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
lo = NFS_I(inode)->layout;
|
||||
if (lo && nfs4_stateid_match_other(dst, &lo->plh_stateid)) {
|
||||
dst->seqid = lo->plh_stateid.seqid;
|
||||
ret = true;
|
||||
err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0);
|
||||
if (err != -EBUSY) {
|
||||
dst->seqid = lo->plh_stateid.seqid;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
pnfs_free_lseg_list(&head);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user