Skip to content

Commit d29b468

Browse files
author
Trond Myklebust
committed
pNFS/NFSv4: Improve rejection of out-of-order layouts
If a layoutget ends up being reordered w.r.t. a layoutreturn, e.g. due to a layoutget-on-open not knowing a priori which file to lock, then we must assume the layout is no longer being considered valid state by the server. Incrementally improve our ability to reject such states by using the cached old stateid in conjunction with the plh_barrier to try to identify them. Signed-off-by: Trond Myklebust <[email protected]>
1 parent 1bcf34f commit d29b468

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

fs/nfs/pnfs.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo,
10001000
{
10011001
u32 seqid = be32_to_cpu(stateid->seqid);
10021002

1003-
return !pnfs_seqid_is_newer(seqid, lo->plh_barrier);
1003+
return !pnfs_seqid_is_newer(seqid, lo->plh_barrier) && lo->plh_barrier;
10041004
}
10051005

10061006
/* lget is set to 1 if called from inside send_layoutget call chain */
@@ -1912,6 +1912,11 @@ static void nfs_layoutget_end(struct pnfs_layout_hdr *lo)
19121912
wake_up_var(&lo->plh_outstanding);
19131913
}
19141914

1915+
static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo)
1916+
{
1917+
return test_bit(NFS_LAYOUT_FIRST_LAYOUTGET, &lo->plh_flags);
1918+
}
1919+
19151920
static void pnfs_clear_first_layoutget(struct pnfs_layout_hdr *lo)
19161921
{
19171922
unsigned long *bitlock = &lo->plh_flags;
@@ -2386,17 +2391,17 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
23862391
goto out_forget;
23872392
}
23882393

2389-
if (!pnfs_layout_is_valid(lo)) {
2390-
/* We have a completely new layout */
2391-
pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true);
2392-
} else if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
2394+
if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
23932395
/* existing state ID, make sure the sequence number matches. */
23942396
if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
2397+
if (!pnfs_layout_is_valid(lo) &&
2398+
pnfs_is_first_layoutget(lo))
2399+
lo->plh_barrier = 0;
23952400
dprintk("%s forget reply due to sequence\n", __func__);
23962401
goto out_forget;
23972402
}
23982403
pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, false);
2399-
} else {
2404+
} else if (pnfs_layout_is_valid(lo)) {
24002405
/*
24012406
* We got an entirely new state ID. Mark all segments for the
24022407
* inode invalid, and retry the layoutget
@@ -2409,6 +2414,11 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
24092414
pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs,
24102415
&range, 0);
24112416
goto out_forget;
2417+
} else {
2418+
/* We have a completely new layout */
2419+
if (!pnfs_is_first_layoutget(lo))
2420+
goto out_forget;
2421+
pnfs_set_layout_stateid(lo, &res->stateid, lgp->cred, true);
24122422
}
24132423

24142424
pnfs_get_lseg(lseg);

0 commit comments

Comments
 (0)