|
@@ -93,6 +93,8 @@ static int nfs4_map_errors(int err)
|
|
|
return err;
|
|
|
switch (err) {
|
|
|
case -NFS4ERR_RESOURCE:
|
|
|
+ case -NFS4ERR_LAYOUTTRYLATER:
|
|
|
+ case -NFS4ERR_RECALLCONFLICT:
|
|
|
return -EREMOTEIO;
|
|
|
case -NFS4ERR_WRONGSEC:
|
|
|
return -EPERM;
|
|
@@ -1158,6 +1160,7 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
|
|
|
data->o_arg.fmode);
|
|
|
iput(inode);
|
|
|
out:
|
|
|
+ nfs_release_seqid(data->o_arg.seqid);
|
|
|
return state;
|
|
|
err_put_inode:
|
|
|
iput(inode);
|
|
@@ -6045,6 +6048,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
|
|
|
struct nfs_server *server = NFS_SERVER(inode);
|
|
|
struct pnfs_layout_hdr *lo;
|
|
|
struct nfs4_state *state = NULL;
|
|
|
+ unsigned long timeo, giveup;
|
|
|
|
|
|
dprintk("--> %s\n", __func__);
|
|
|
|
|
@@ -6056,7 +6060,10 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
|
|
|
goto out;
|
|
|
case -NFS4ERR_LAYOUTTRYLATER:
|
|
|
case -NFS4ERR_RECALLCONFLICT:
|
|
|
- task->tk_status = -NFS4ERR_DELAY;
|
|
|
+ timeo = rpc_get_timeout(task->tk_client);
|
|
|
+ giveup = lgp->args.timestamp + timeo;
|
|
|
+ if (time_after(giveup, jiffies))
|
|
|
+ task->tk_status = -NFS4ERR_DELAY;
|
|
|
break;
|
|
|
case -NFS4ERR_EXPIRED:
|
|
|
case -NFS4ERR_BAD_STATEID:
|
|
@@ -6129,11 +6136,13 @@ static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
|
|
|
static void nfs4_layoutget_release(void *calldata)
|
|
|
{
|
|
|
struct nfs4_layoutget *lgp = calldata;
|
|
|
- struct nfs_server *server = NFS_SERVER(lgp->args.inode);
|
|
|
+ struct inode *inode = lgp->args.inode;
|
|
|
+ struct nfs_server *server = NFS_SERVER(inode);
|
|
|
size_t max_pages = max_response_pages(server);
|
|
|
|
|
|
dprintk("--> %s\n", __func__);
|
|
|
nfs4_free_pages(lgp->args.layout.pages, max_pages);
|
|
|
+ pnfs_put_layout_hdr(NFS_I(inode)->layout);
|
|
|
put_nfs_open_context(lgp->args.ctx);
|
|
|
kfree(calldata);
|
|
|
dprintk("<-- %s\n", __func__);
|
|
@@ -6148,7 +6157,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
|
|
|
struct pnfs_layout_segment *
|
|
|
nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
|
|
|
{
|
|
|
- struct nfs_server *server = NFS_SERVER(lgp->args.inode);
|
|
|
+ struct inode *inode = lgp->args.inode;
|
|
|
+ struct nfs_server *server = NFS_SERVER(inode);
|
|
|
size_t max_pages = max_response_pages(server);
|
|
|
struct rpc_task *task;
|
|
|
struct rpc_message msg = {
|
|
@@ -6174,10 +6184,15 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
}
|
|
|
lgp->args.layout.pglen = max_pages * PAGE_SIZE;
|
|
|
+ lgp->args.timestamp = jiffies;
|
|
|
|
|
|
lgp->res.layoutp = &lgp->args.layout;
|
|
|
lgp->res.seq_res.sr_slot = NULL;
|
|
|
nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
|
|
|
+
|
|
|
+ /* nfs4_layoutget_release calls pnfs_put_layout_hdr */
|
|
|
+ pnfs_get_layout_hdr(NFS_I(inode)->layout);
|
|
|
+
|
|
|
task = rpc_run_task(&task_setup_data);
|
|
|
if (IS_ERR(task))
|
|
|
return ERR_CAST(task);
|