aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-09-17 17:12:15 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-09-28 16:03:06 -0400
commita0b0a6e39bd1bb4a0922086feee73627cbd53ba4 (patch)
tree51921888aee9b74c3d6ad62b3546c858434f8925
parentd19751e7b9bd8a01d00372325439589886674f79 (diff)
NFS: Clean up the pNFS layoutget interface
Ensure that we do return errors from nfs4_proc_layoutget() and that we don't mark the layout as having failed if the error was due to a signal or resource problem on the client side. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c14
-rw-r--r--fs/nfs/pnfs.c25
-rw-r--r--fs/nfs/pnfs.h4
-rw-r--r--include/linux/nfs_xdr.h1
4 files changed, 27 insertions, 17 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cf2fd5d0c1b..1c8656f8745 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6286,7 +6286,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
6286 .rpc_release = nfs4_layoutget_release, 6286 .rpc_release = nfs4_layoutget_release,
6287}; 6287};
6288 6288
6289void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) 6289struct pnfs_layout_segment *
6290nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6290{ 6291{
6291 struct nfs_server *server = NFS_SERVER(lgp->args.inode); 6292 struct nfs_server *server = NFS_SERVER(lgp->args.inode);
6292 size_t max_pages = max_response_pages(server); 6293 size_t max_pages = max_response_pages(server);
@@ -6303,6 +6304,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6303 .callback_data = lgp, 6304 .callback_data = lgp,
6304 .flags = RPC_TASK_ASYNC, 6305 .flags = RPC_TASK_ASYNC,
6305 }; 6306 };
6307 struct pnfs_layout_segment *lseg = NULL;
6306 int status = 0; 6308 int status = 0;
6307 6309
6308 dprintk("--> %s\n", __func__); 6310 dprintk("--> %s\n", __func__);
@@ -6310,7 +6312,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6310 lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); 6312 lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
6311 if (!lgp->args.layout.pages) { 6313 if (!lgp->args.layout.pages) {
6312 nfs4_layoutget_release(lgp); 6314 nfs4_layoutget_release(lgp);
6313 return; 6315 return ERR_PTR(-ENOMEM);
6314 } 6316 }
6315 lgp->args.layout.pglen = max_pages * PAGE_SIZE; 6317 lgp->args.layout.pglen = max_pages * PAGE_SIZE;
6316 6318
@@ -6319,15 +6321,17 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6319 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); 6321 nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
6320 task = rpc_run_task(&task_setup_data); 6322 task = rpc_run_task(&task_setup_data);
6321 if (IS_ERR(task)) 6323 if (IS_ERR(task))
6322 return; 6324 return ERR_CAST(task);
6323 status = nfs4_wait_for_completion_rpc_task(task); 6325 status = nfs4_wait_for_completion_rpc_task(task);
6324 if (status == 0) 6326 if (status == 0)
6325 status = task->tk_status; 6327 status = task->tk_status;
6326 if (status == 0) 6328 if (status == 0)
6327 status = pnfs_layout_process(lgp); 6329 lseg = pnfs_layout_process(lgp);
6328 rpc_put_task(task); 6330 rpc_put_task(task);
6329 dprintk("<-- %s status=%d\n", __func__, status); 6331 dprintk("<-- %s status=%d\n", __func__, status);
6330 return; 6332 if (status)
6333 return ERR_PTR(status);
6334 return lseg;
6331} 6335}
6332 6336
6333static void 6337static void
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 2e00feacd4b..3a7ac97020d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -582,7 +582,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
582 struct inode *ino = lo->plh_inode; 582 struct inode *ino = lo->plh_inode;
583 struct nfs_server *server = NFS_SERVER(ino); 583 struct nfs_server *server = NFS_SERVER(ino);
584 struct nfs4_layoutget *lgp; 584 struct nfs4_layoutget *lgp;
585 struct pnfs_layout_segment *lseg = NULL; 585 struct pnfs_layout_segment *lseg;
586 586
587 dprintk("--> %s\n", __func__); 587 dprintk("--> %s\n", __func__);
588 588
@@ -599,16 +599,22 @@ send_layoutget(struct pnfs_layout_hdr *lo,
599 lgp->args.type = server->pnfs_curr_ld->id; 599 lgp->args.type = server->pnfs_curr_ld->id;
600 lgp->args.inode = ino; 600 lgp->args.inode = ino;
601 lgp->args.ctx = get_nfs_open_context(ctx); 601 lgp->args.ctx = get_nfs_open_context(ctx);
602 lgp->lsegpp = &lseg;
603 lgp->gfp_flags = gfp_flags; 602 lgp->gfp_flags = gfp_flags;
604 603
605 /* Synchronously retrieve layout information from server and 604 /* Synchronously retrieve layout information from server and
606 * store in lseg. 605 * store in lseg.
607 */ 606 */
608 nfs4_proc_layoutget(lgp, gfp_flags); 607 lseg = nfs4_proc_layoutget(lgp, gfp_flags);
609 if (!lseg) { 608 if (IS_ERR(lseg)) {
610 /* remember that LAYOUTGET failed and suspend trying */ 609 switch (PTR_ERR(lseg)) {
611 set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); 610 case -ENOMEM:
611 case -ERESTARTSYS:
612 break;
613 default:
614 /* remember that LAYOUTGET failed and suspend trying */
615 set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
616 }
617 return NULL;
612 } 618 }
613 619
614 return lseg; 620 return lseg;
@@ -1096,7 +1102,7 @@ out_unlock:
1096} 1102}
1097EXPORT_SYMBOL_GPL(pnfs_update_layout); 1103EXPORT_SYMBOL_GPL(pnfs_update_layout);
1098 1104
1099int 1105struct pnfs_layout_segment *
1100pnfs_layout_process(struct nfs4_layoutget *lgp) 1106pnfs_layout_process(struct nfs4_layoutget *lgp)
1101{ 1107{
1102 struct pnfs_layout_hdr *lo = NFS_I(lgp->args.inode)->layout; 1108 struct pnfs_layout_hdr *lo = NFS_I(lgp->args.inode)->layout;
@@ -1129,7 +1135,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
1129 } 1135 }
1130 init_lseg(lo, lseg); 1136 init_lseg(lo, lseg);
1131 lseg->pls_range = res->range; 1137 lseg->pls_range = res->range;
1132 *lgp->lsegpp = get_lseg(lseg); 1138 get_lseg(lseg);
1133 pnfs_insert_layout(lo, lseg); 1139 pnfs_insert_layout(lo, lseg);
1134 1140
1135 if (res->return_on_close) { 1141 if (res->return_on_close) {
@@ -1140,8 +1146,9 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
1140 /* Done processing layoutget. Set the layout stateid */ 1146 /* Done processing layoutget. Set the layout stateid */
1141 pnfs_set_layout_stateid(lo, &res->stateid, false); 1147 pnfs_set_layout_stateid(lo, &res->stateid, false);
1142 spin_unlock(&ino->i_lock); 1148 spin_unlock(&ino->i_lock);
1149 return lseg;
1143out: 1150out:
1144 return status; 1151 return ERR_PTR(status);
1145 1152
1146out_forget_reply: 1153out_forget_reply:
1147 spin_unlock(&ino->i_lock); 1154 spin_unlock(&ino->i_lock);
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 745aa1b39e7..d51ef888e71 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -172,7 +172,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server,
172 struct pnfs_devicelist *devlist); 172 struct pnfs_devicelist *devlist);
173extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, 173extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
174 struct pnfs_device *dev); 174 struct pnfs_device *dev);
175extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags); 175extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
176extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); 176extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
177 177
178/* pnfs.c */ 178/* pnfs.c */
@@ -192,7 +192,7 @@ void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page
192int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc); 192int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
193bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); 193bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
194void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg); 194void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg);
195int pnfs_layout_process(struct nfs4_layoutget *lgp); 195struct pnfs_layout_segment *pnfs_layout_process(struct nfs4_layoutget *lgp);
196void pnfs_free_lseg_list(struct list_head *tmp_list); 196void pnfs_free_lseg_list(struct list_head *tmp_list);
197void pnfs_destroy_layout(struct nfs_inode *); 197void pnfs_destroy_layout(struct nfs_inode *);
198void pnfs_destroy_all_layouts(struct nfs_client *); 198void pnfs_destroy_all_layouts(struct nfs_client *);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index be9cf3c7e79..5da789fdf25 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -251,7 +251,6 @@ struct nfs4_layoutget_res {
251struct nfs4_layoutget { 251struct nfs4_layoutget {
252 struct nfs4_layoutget_args args; 252 struct nfs4_layoutget_args args;
253 struct nfs4_layoutget_res res; 253 struct nfs4_layoutget_res res;
254 struct pnfs_layout_segment **lsegpp;
255 gfp_t gfp_flags; 254 gfp_t gfp_flags;
256}; 255};
257 256