pNFS: Always update the layout barrier seqid on LAYOUTGET
Currently, pnfs_set_layout_stateid() will update the layout sequence id barrier only if the stateid itself is newer than the current layout stateid. However in a situation where multiple LAYOUTGET calls and a LAYOUTRETURN raced, it is entirely possible for one of the LAYOUTGET to set the current stateid to something newer than the LAYOUTRETURN that needs to set the barrier. The fix is to allow the "update_barrier" flag to force a check as to whether or not the barrier needs to be updated. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
13bede18de
commit
ecebb80bf3
1 changed files with 14 additions and 13 deletions
|
@ -761,24 +761,25 @@ void
|
|||
pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
|
||||
bool update_barrier)
|
||||
{
|
||||
u32 oldseq, newseq, new_barrier;
|
||||
bool empty = !pnfs_layout_is_valid(lo);
|
||||
u32 oldseq, newseq, new_barrier = 0;
|
||||
bool invalid = !pnfs_layout_is_valid(lo);
|
||||
|
||||
oldseq = be32_to_cpu(lo->plh_stateid.seqid);
|
||||
newseq = be32_to_cpu(new->seqid);
|
||||
if (empty || pnfs_seqid_is_newer(newseq, oldseq)) {
|
||||
if (invalid || pnfs_seqid_is_newer(newseq, oldseq)) {
|
||||
nfs4_stateid_copy(&lo->plh_stateid, new);
|
||||
if (update_barrier) {
|
||||
new_barrier = be32_to_cpu(new->seqid);
|
||||
} else {
|
||||
/* Because of wraparound, we want to keep the barrier
|
||||
* "close" to the current seqids.
|
||||
*/
|
||||
new_barrier = newseq - atomic_read(&lo->plh_outstanding);
|
||||
}
|
||||
if (empty || pnfs_seqid_is_newer(new_barrier, lo->plh_barrier))
|
||||
lo->plh_barrier = new_barrier;
|
||||
/*
|
||||
* Because of wraparound, we want to keep the barrier
|
||||
* "close" to the current seqids.
|
||||
*/
|
||||
new_barrier = newseq - atomic_read(&lo->plh_outstanding);
|
||||
}
|
||||
if (update_barrier)
|
||||
new_barrier = be32_to_cpu(new->seqid);
|
||||
else if (new_barrier == 0)
|
||||
return;
|
||||
if (invalid || pnfs_seqid_is_newer(new_barrier, lo->plh_barrier))
|
||||
lo->plh_barrier = new_barrier;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
Loading…
Reference in a new issue