aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-09-20 07:23:45 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2019-09-20 15:48:35 -0400
commit30cb3ee299cbf343fe07419e9b0f8dc305979eb6 (patch)
treec3712b9e919e26632ea3fcaf7cbcd9c1e0eb1f47 /fs
parent922839570920c024baf740ef45dfa98009f0192e (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4proc.c2
-rw-r--r--fs/nfs/pnfs.c18
-rw-r--r--fs/nfs/pnfs.h4
3 files changed, 17 insertions, 7 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c0bff7ad0c9f..27964ea0b3b7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -9063,7 +9063,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
9063 server = NFS_SERVER(lrp->args.inode); 9063 server = NFS_SERVER(lrp->args.inode);
9064 switch (task->tk_status) { 9064 switch (task->tk_status) {
9065 case -NFS4ERR_OLD_STATEID: 9065 case -NFS4ERR_OLD_STATEID:
9066 if (nfs4_layoutreturn_refresh_stateid(&lrp->args.stateid, 9066 if (nfs4_layout_refresh_old_stateid(&lrp->args.stateid,
9067 &lrp->args.range, 9067 &lrp->args.range,
9068 lrp->args.inode)) 9068 lrp->args.inode))
9069 goto out_restart; 9069 goto out_restart;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index abc7188f1853..bb80034a7661 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -359,9 +359,10 @@ pnfs_clear_lseg_state(struct pnfs_layout_segment *lseg,
359} 359}
360 360
361/* 361/*
362 * Update the seqid of a layout stateid 362 * Update the seqid of a layout stateid after receiving
363 * NFS4ERR_OLD_STATEID
363 */ 364 */
364bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst, 365bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
365 struct pnfs_layout_range *dst_range, 366 struct pnfs_layout_range *dst_range,
366 struct inode *inode) 367 struct inode *inode)
367{ 368{
@@ -377,7 +378,15 @@ bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
377 378
378 spin_lock(&inode->i_lock); 379 spin_lock(&inode->i_lock);
379 lo = NFS_I(inode)->layout; 380 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 */
381 err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0); 390 err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0);
382 if (err != -EBUSY) { 391 if (err != -EBUSY) {
383 dst->seqid = lo->plh_stateid.seqid; 392 dst->seqid = lo->plh_stateid.seqid;
@@ -385,6 +394,7 @@ bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
385 ret = true; 394 ret = true;
386 } 395 }
387 } 396 }
397out:
388 spin_unlock(&inode->i_lock); 398 spin_unlock(&inode->i_lock);
389 pnfs_free_lseg_list(&head); 399 pnfs_free_lseg_list(&head);
390 return ret; 400 return ret;
@@ -1475,7 +1485,7 @@ int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
1475 *ret = -NFS4ERR_NOMATCHING_LAYOUT; 1485 *ret = -NFS4ERR_NOMATCHING_LAYOUT;
1476 return 0; 1486 return 0;
1477 case -NFS4ERR_OLD_STATEID: 1487 case -NFS4ERR_OLD_STATEID:
1478 if (!nfs4_layoutreturn_refresh_stateid(&arg->stateid, 1488 if (!nfs4_layout_refresh_old_stateid(&arg->stateid,
1479 &arg->range, inode)) 1489 &arg->range, inode))
1480 break; 1490 break;
1481 *ret = -NFS4ERR_NOMATCHING_LAYOUT; 1491 *ret = -NFS4ERR_NOMATCHING_LAYOUT;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 3ef3756d437c..f8a38065c7e4 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -261,7 +261,7 @@ int pnfs_destroy_layouts_byfsid(struct nfs_client *clp,
261 bool is_recall); 261 bool is_recall);
262int pnfs_destroy_layouts_byclid(struct nfs_client *clp, 262int pnfs_destroy_layouts_byclid(struct nfs_client *clp,
263 bool is_recall); 263 bool is_recall);
264bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst, 264bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
265 struct pnfs_layout_range *dst_range, 265 struct pnfs_layout_range *dst_range,
266 struct inode *inode); 266 struct inode *inode);
267void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo); 267void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
@@ -798,7 +798,7 @@ static inline void nfs4_pnfs_v3_ds_connect_unload(void)
798{ 798{
799} 799}
800 800
801static inline bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst, 801static inline bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
802 struct pnfs_layout_range *dst_range, 802 struct pnfs_layout_range *dst_range,
803 struct inode *inode) 803 struct inode *inode)
804{ 804{