Skip to content

Commit

Permalink
pnfs: avoid using stale stateids after layoutreturn
Browse files Browse the repository at this point in the history
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: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
  • Loading branch information
Christoph Hellwig authored and Trond Myklebust committed Sep 10, 2014
1 parent defb846 commit 47abade
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
7 changes: 6 additions & 1 deletion fs/nfs/pnfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
status = -EAGAIN;
} else if (!nfs4_valid_open_stateid(open_state)) {
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;

do {
Expand Down Expand Up @@ -860,6 +861,8 @@ _pnfs_return_layout(struct inode *ino)
dprintk("NFS: %s no layout segments to return\n", __func__);
goto out;
}

set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
lo->plh_block_lgets++;
spin_unlock(&ino->i_lock);
pnfs_free_lseg_list(&tmp_list);
Expand Down Expand Up @@ -1380,6 +1383,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
lo->plh_barrier = be32_to_cpu(res->stateid.seqid);
}

clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);

pnfs_get_lseg(lseg);
pnfs_layout_insert_lseg(lo, lseg);

Expand Down
1 change: 1 addition & 0 deletions fs/nfs/pnfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ enum {
NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */
NFS_LAYOUT_ROC, /* some lseg had roc bit set */
NFS_LAYOUT_RETURN, /* Return this layout ASAP */
NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
};

enum layoutdriver_policy_flags {
Expand Down

0 comments on commit 47abade

Please sign in to comment.