Skip to content

Commit

Permalink
pnfs: don't check sequence on new stateids in layoutget
Browse files Browse the repository at this point in the history
When layoutget returns an entirely new layout stateid it should not
check the generation counter as the new stateid will start with a new
counter entirely unrelated to old one.

The current behavior causes constant layoutget failures against a block
server which allocates a new stateid after an recall that removed all
outstanding layouts.

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 1013df6 commit 362f747
Showing 1 changed file with 19 additions and 17 deletions.
36 changes: 19 additions & 17 deletions fs/nfs/pnfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,17 +682,6 @@ static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
return (s32)(s1 - s2) > 0;
}

static void
pnfs_verify_layout_stateid(struct pnfs_layout_hdr *lo,
const nfs4_stateid *new,
struct list_head *free_me_list)
{
if (nfs4_stateid_match_other(&lo->plh_stateid, new))
return;
/* Layout is new! Kill existing layout segments */
pnfs_mark_matching_lsegs_invalid(lo, free_me_list, NULL);
}

/* update lo->plh_stateid with new if is more recent */
void
pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
Expand Down Expand Up @@ -1367,16 +1356,29 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
goto out_forget_reply;
}

if (pnfs_layoutgets_blocked(lo, 1) ||
pnfs_layout_stateid_blocked(lo, &res->stateid)) {
if (pnfs_layoutgets_blocked(lo, 1)) {
dprintk("%s forget reply due to state\n", __func__);
goto out_forget_reply;
}

/* Check that the new stateid matches the old stateid */
pnfs_verify_layout_stateid(lo, &res->stateid, &free_me);
/* Done processing layoutget. Set the layout stateid */
pnfs_set_layout_stateid(lo, &res->stateid, false);
if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
/* existing state ID, make sure the sequence number matches. */
if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
dprintk("%s forget reply due to sequence\n", __func__);
goto out_forget_reply;
}
pnfs_set_layout_stateid(lo, &res->stateid, false);
} else {
/*
* We got an entirely new state ID. Mark all segments for the
* inode invalid, and don't bother validating the stateid
* sequence number.
*/
pnfs_mark_matching_lsegs_invalid(lo, &free_me, NULL);

nfs4_stateid_copy(&lo->plh_stateid, &res->stateid);
lo->plh_barrier = be32_to_cpu(res->stateid.seqid);
}

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

0 comments on commit 362f747

Please sign in to comment.