Commit 47abadef authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Trond Myklebust

pnfs: avoid using stale stateids after layoutreturn

After we issued a layoutreturn operations the may free the layout stateid
and will thus cause bad stateid error when the client uses it again.

We currently try to avoid this case by chosing the open stateid if not
lsegs are present for this inode.  But various places can hold refererence
on lsegs and thus cause the list not to be empty shortly after a layout
return.  Add an explicit flag to mark the current layout stateid invalid
and force usage of the openstateid after we did a full file layoutreturn.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent defb8460
...@@ -738,7 +738,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, ...@@ -738,7 +738,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
status = -EAGAIN; status = -EAGAIN;
} else if (!nfs4_valid_open_stateid(open_state)) { } else if (!nfs4_valid_open_stateid(open_state)) {
status = -EBADF; status = -EBADF;
} else if (list_empty(&lo->plh_segs)) { } else if (list_empty(&lo->plh_segs) ||
test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags)) {
int seq; int seq;
do { do {
...@@ -860,6 +861,8 @@ _pnfs_return_layout(struct inode *ino) ...@@ -860,6 +861,8 @@ _pnfs_return_layout(struct inode *ino)
dprintk("NFS: %s no layout segments to return\n", __func__); dprintk("NFS: %s no layout segments to return\n", __func__);
goto out; goto out;
} }
set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
lo->plh_block_lgets++; lo->plh_block_lgets++;
spin_unlock(&ino->i_lock); spin_unlock(&ino->i_lock);
pnfs_free_lseg_list(&tmp_list); pnfs_free_lseg_list(&tmp_list);
...@@ -1380,6 +1383,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1380,6 +1383,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
lo->plh_barrier = be32_to_cpu(res->stateid.seqid); lo->plh_barrier = be32_to_cpu(res->stateid.seqid);
} }
clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
pnfs_get_lseg(lseg); pnfs_get_lseg(lseg);
pnfs_layout_insert_lseg(lo, lseg); pnfs_layout_insert_lseg(lo, lseg);
......
...@@ -65,6 +65,7 @@ enum { ...@@ -65,6 +65,7 @@ enum {
NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */
NFS_LAYOUT_ROC, /* some lseg had roc bit set */ NFS_LAYOUT_ROC, /* some lseg had roc bit set */
NFS_LAYOUT_RETURN, /* Return this layout ASAP */ NFS_LAYOUT_RETURN, /* Return this layout ASAP */
NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
}; };
enum layoutdriver_policy_flags { enum layoutdriver_policy_flags {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment