Skip to content

Commit 30cb3ee

Browse files
trondmyamschuma-ntap
authored andcommitted
pNFS: Handle NFS4ERR_OLD_STATEID on layoutreturn by bumping the state seqid
If a LAYOUTRETURN receives a reply of NFS4ERR_OLD_STATEID then assume we've missed an update, and just bump the stateid. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 9228395 commit 30cb3ee

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

fs/nfs/nfs4proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9063,7 +9063,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
90639063
server = NFS_SERVER(lrp->args.inode);
90649064
switch (task->tk_status) {
90659065
case -NFS4ERR_OLD_STATEID:
9066-
if (nfs4_layoutreturn_refresh_stateid(&lrp->args.stateid,
9066+
if (nfs4_layout_refresh_old_stateid(&lrp->args.stateid,
90679067
&lrp->args.range,
90689068
lrp->args.inode))
90699069
goto out_restart;

fs/nfs/pnfs.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,10 @@ pnfs_clear_lseg_state(struct pnfs_layout_segment *lseg,
359359
}
360360

361361
/*
362-
* Update the seqid of a layout stateid
362+
* Update the seqid of a layout stateid after receiving
363+
* NFS4ERR_OLD_STATEID
363364
*/
364-
bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
365+
bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
365366
struct pnfs_layout_range *dst_range,
366367
struct inode *inode)
367368
{
@@ -377,14 +378,23 @@ bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
377378

378379
spin_lock(&inode->i_lock);
379380
lo = NFS_I(inode)->layout;
380-
if (lo && nfs4_stateid_match_other(dst, &lo->plh_stateid)) {
381+
if (lo && pnfs_layout_is_valid(lo) &&
382+
nfs4_stateid_match_other(dst, &lo->plh_stateid)) {
383+
/* Is our call using the most recent seqid? If so, bump it */
384+
if (!nfs4_stateid_is_newer(&lo->plh_stateid, dst)) {
385+
nfs4_stateid_seqid_inc(dst);
386+
ret = true;
387+
goto out;
388+
}
389+
/* Try to update the seqid to the most recent */
381390
err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0);
382391
if (err != -EBUSY) {
383392
dst->seqid = lo->plh_stateid.seqid;
384393
*dst_range = range;
385394
ret = true;
386395
}
387396
}
397+
out:
388398
spin_unlock(&inode->i_lock);
389399
pnfs_free_lseg_list(&head);
390400
return ret;
@@ -1475,7 +1485,7 @@ int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
14751485
*ret = -NFS4ERR_NOMATCHING_LAYOUT;
14761486
return 0;
14771487
case -NFS4ERR_OLD_STATEID:
1478-
if (!nfs4_layoutreturn_refresh_stateid(&arg->stateid,
1488+
if (!nfs4_layout_refresh_old_stateid(&arg->stateid,
14791489
&arg->range, inode))
14801490
break;
14811491
*ret = -NFS4ERR_NOMATCHING_LAYOUT;

fs/nfs/pnfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ int pnfs_destroy_layouts_byfsid(struct nfs_client *clp,
261261
bool is_recall);
262262
int pnfs_destroy_layouts_byclid(struct nfs_client *clp,
263263
bool is_recall);
264-
bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
264+
bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
265265
struct pnfs_layout_range *dst_range,
266266
struct inode *inode);
267267
void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
@@ -798,7 +798,7 @@ static inline void nfs4_pnfs_v3_ds_connect_unload(void)
798798
{
799799
}
800800

801-
static inline bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
801+
static inline bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
802802
struct pnfs_layout_range *dst_range,
803803
struct inode *inode)
804804
{

0 commit comments

Comments
 (0)