NFSv4/pNFS: Retry the layout return later in case of a timeout or reboot
If the layout return failed due to a timeout or reboot, then leave the layout segments on the list so that the layout return gets replayed later. The exception would be if we're freeing the inode. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
committed by
Anna Schumaker
parent
50379c9f09
commit
bbbff6d5ed
+20
-1
@@ -9973,6 +9973,11 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
|
|||||||
if (!nfs41_sequence_process(task, &lrp->res.seq_res))
|
if (!nfs41_sequence_process(task, &lrp->res.seq_res))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (task->tk_rpc_status == -ETIMEDOUT) {
|
||||||
|
lrp->rpc_status = -EAGAIN;
|
||||||
|
lrp->res.lrs_present = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Was there an RPC level error? Assume the call succeeded,
|
* Was there an RPC level error? Assume the call succeeded,
|
||||||
* and that we need to release the layout
|
* and that we need to release the layout
|
||||||
@@ -9995,6 +10000,15 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
|
|||||||
fallthrough;
|
fallthrough;
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
|
case -NFS4ERR_BADSESSION:
|
||||||
|
case -NFS4ERR_DEADSESSION:
|
||||||
|
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
|
||||||
|
nfs4_schedule_session_recovery(server->nfs_client->cl_session,
|
||||||
|
task->tk_status);
|
||||||
|
lrp->res.lrs_present = 0;
|
||||||
|
lrp->rpc_status = -EAGAIN;
|
||||||
|
task->tk_status = 0;
|
||||||
|
break;
|
||||||
case -NFS4ERR_DELAY:
|
case -NFS4ERR_DELAY:
|
||||||
if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN)
|
if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN)
|
||||||
break;
|
break;
|
||||||
@@ -10012,8 +10026,13 @@ static void nfs4_layoutreturn_release(void *calldata)
|
|||||||
struct nfs4_layoutreturn *lrp = calldata;
|
struct nfs4_layoutreturn *lrp = calldata;
|
||||||
struct pnfs_layout_hdr *lo = lrp->args.layout;
|
struct pnfs_layout_hdr *lo = lrp->args.layout;
|
||||||
|
|
||||||
pnfs_layoutreturn_free_lsegs(lo, &lrp->args.stateid, &lrp->args.range,
|
if (lrp->rpc_status == 0 || !lrp->inode)
|
||||||
|
pnfs_layoutreturn_free_lsegs(
|
||||||
|
lo, &lrp->args.stateid, &lrp->args.range,
|
||||||
lrp->res.lrs_present ? &lrp->res.stateid : NULL);
|
lrp->res.lrs_present ? &lrp->res.stateid : NULL);
|
||||||
|
else
|
||||||
|
pnfs_layoutreturn_retry_later(lo, &lrp->args.stateid,
|
||||||
|
&lrp->args.range);
|
||||||
nfs4_sequence_free_slot(&lrp->res.seq_res);
|
nfs4_sequence_free_slot(&lrp->res.seq_res);
|
||||||
if (lrp->ld_private.ops && lrp->ld_private.ops->free)
|
if (lrp->ld_private.ops && lrp->ld_private.ops->free)
|
||||||
lrp->ld_private.ops->free(&lrp->ld_private);
|
lrp->ld_private.ops->free(&lrp->ld_private);
|
||||||
|
|||||||
@@ -1191,6 +1191,18 @@ pnfs_layoutreturn_retry_later_locked(struct pnfs_layout_hdr *lo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pnfs_layoutreturn_retry_later(struct pnfs_layout_hdr *lo,
|
||||||
|
const nfs4_stateid *arg_stateid,
|
||||||
|
const struct pnfs_layout_range *range)
|
||||||
|
{
|
||||||
|
struct inode *inode = lo->plh_inode;
|
||||||
|
|
||||||
|
spin_lock(&inode->i_lock);
|
||||||
|
pnfs_layoutreturn_retry_later_locked(lo, arg_stateid, range);
|
||||||
|
pnfs_clear_layoutreturn_waitbit(lo);
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
|
}
|
||||||
|
|
||||||
void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
|
void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
|
||||||
const nfs4_stateid *arg_stateid,
|
const nfs4_stateid *arg_stateid,
|
||||||
const struct pnfs_layout_range *range,
|
const struct pnfs_layout_range *range,
|
||||||
|
|||||||
@@ -328,6 +328,9 @@ struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
|
|||||||
enum pnfs_iomode iomode,
|
enum pnfs_iomode iomode,
|
||||||
bool strict_iomode,
|
bool strict_iomode,
|
||||||
gfp_t gfp_flags);
|
gfp_t gfp_flags);
|
||||||
|
void pnfs_layoutreturn_retry_later(struct pnfs_layout_hdr *lo,
|
||||||
|
const nfs4_stateid *arg_stateid,
|
||||||
|
const struct pnfs_layout_range *range);
|
||||||
void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
|
void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
|
||||||
const nfs4_stateid *arg_stateid,
|
const nfs4_stateid *arg_stateid,
|
||||||
const struct pnfs_layout_range *range,
|
const struct pnfs_layout_range *range,
|
||||||
|
|||||||
Reference in New Issue
Block a user