diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index eae83bf96c6d..b2671cb0f901 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -93,6 +93,8 @@ static int nfs4_map_errors(int err) | |||
93 | return err; | 93 | return err; |
94 | switch (err) { | 94 | switch (err) { |
95 | case -NFS4ERR_RESOURCE: | 95 | case -NFS4ERR_RESOURCE: |
96 | case -NFS4ERR_LAYOUTTRYLATER: | ||
97 | case -NFS4ERR_RECALLCONFLICT: | ||
96 | return -EREMOTEIO; | 98 | return -EREMOTEIO; |
97 | case -NFS4ERR_WRONGSEC: | 99 | case -NFS4ERR_WRONGSEC: |
98 | return -EPERM; | 100 | return -EPERM; |
@@ -1158,6 +1160,7 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) | |||
1158 | data->o_arg.fmode); | 1160 | data->o_arg.fmode); |
1159 | iput(inode); | 1161 | iput(inode); |
1160 | out: | 1162 | out: |
1163 | nfs_release_seqid(data->o_arg.seqid); | ||
1161 | return state; | 1164 | return state; |
1162 | err_put_inode: | 1165 | err_put_inode: |
1163 | iput(inode); | 1166 | iput(inode); |
@@ -6045,6 +6048,7 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) | |||
6045 | struct nfs_server *server = NFS_SERVER(inode); | 6048 | struct nfs_server *server = NFS_SERVER(inode); |
6046 | struct pnfs_layout_hdr *lo; | 6049 | struct pnfs_layout_hdr *lo; |
6047 | struct nfs4_state *state = NULL; | 6050 | struct nfs4_state *state = NULL; |
6051 | unsigned long timeo, giveup; | ||
6048 | 6052 | ||
6049 | dprintk("--> %s\n", __func__); | 6053 | dprintk("--> %s\n", __func__); |
6050 | 6054 | ||
@@ -6056,7 +6060,10 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) | |||
6056 | goto out; | 6060 | goto out; |
6057 | case -NFS4ERR_LAYOUTTRYLATER: | 6061 | case -NFS4ERR_LAYOUTTRYLATER: |
6058 | case -NFS4ERR_RECALLCONFLICT: | 6062 | case -NFS4ERR_RECALLCONFLICT: |
6059 | task->tk_status = -NFS4ERR_DELAY; | 6063 | timeo = rpc_get_timeout(task->tk_client); |
6064 | giveup = lgp->args.timestamp + timeo; | ||
6065 | if (time_after(giveup, jiffies)) | ||
6066 | task->tk_status = -NFS4ERR_DELAY; | ||
6060 | break; | 6067 | break; |
6061 | case -NFS4ERR_EXPIRED: | 6068 | case -NFS4ERR_EXPIRED: |
6062 | case -NFS4ERR_BAD_STATEID: | 6069 | case -NFS4ERR_BAD_STATEID: |
@@ -6129,11 +6136,13 @@ static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags) | |||
6129 | static void nfs4_layoutget_release(void *calldata) | 6136 | static void nfs4_layoutget_release(void *calldata) |
6130 | { | 6137 | { |
6131 | struct nfs4_layoutget *lgp = calldata; | 6138 | struct nfs4_layoutget *lgp = calldata; |
6132 | struct nfs_server *server = NFS_SERVER(lgp->args.inode); | 6139 | struct inode *inode = lgp->args.inode; |
6140 | struct nfs_server *server = NFS_SERVER(inode); | ||
6133 | size_t max_pages = max_response_pages(server); | 6141 | size_t max_pages = max_response_pages(server); |
6134 | 6142 | ||
6135 | dprintk("--> %s\n", __func__); | 6143 | dprintk("--> %s\n", __func__); |
6136 | nfs4_free_pages(lgp->args.layout.pages, max_pages); | 6144 | nfs4_free_pages(lgp->args.layout.pages, max_pages); |
6145 | pnfs_put_layout_hdr(NFS_I(inode)->layout); | ||
6137 | put_nfs_open_context(lgp->args.ctx); | 6146 | put_nfs_open_context(lgp->args.ctx); |
6138 | kfree(calldata); | 6147 | kfree(calldata); |
6139 | dprintk("<-- %s\n", __func__); | 6148 | dprintk("<-- %s\n", __func__); |
@@ -6148,7 +6157,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = { | |||
6148 | struct pnfs_layout_segment * | 6157 | struct pnfs_layout_segment * |
6149 | nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) | 6158 | nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) |
6150 | { | 6159 | { |
6151 | struct nfs_server *server = NFS_SERVER(lgp->args.inode); | 6160 | struct inode *inode = lgp->args.inode; |
6161 | struct nfs_server *server = NFS_SERVER(inode); | ||
6152 | size_t max_pages = max_response_pages(server); | 6162 | size_t max_pages = max_response_pages(server); |
6153 | struct rpc_task *task; | 6163 | struct rpc_task *task; |
6154 | struct rpc_message msg = { | 6164 | struct rpc_message msg = { |
@@ -6174,10 +6184,15 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) | |||
6174 | return ERR_PTR(-ENOMEM); | 6184 | return ERR_PTR(-ENOMEM); |
6175 | } | 6185 | } |
6176 | lgp->args.layout.pglen = max_pages * PAGE_SIZE; | 6186 | lgp->args.layout.pglen = max_pages * PAGE_SIZE; |
6187 | lgp->args.timestamp = jiffies; | ||
6177 | 6188 | ||
6178 | lgp->res.layoutp = &lgp->args.layout; | 6189 | lgp->res.layoutp = &lgp->args.layout; |
6179 | lgp->res.seq_res.sr_slot = NULL; | 6190 | lgp->res.seq_res.sr_slot = NULL; |
6180 | nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); | 6191 | nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); |
6192 | |||
6193 | /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ | ||
6194 | pnfs_get_layout_hdr(NFS_I(inode)->layout); | ||
6195 | |||
6181 | task = rpc_run_task(&task_setup_data); | 6196 | task = rpc_run_task(&task_setup_data); |
6182 | if (IS_ERR(task)) | 6197 | if (IS_ERR(task)) |
6183 | return ERR_CAST(task); | 6198 | return ERR_CAST(task); |