Commit a0b0a6e3 authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent d19751e7
...@@ -6286,7 +6286,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = { ...@@ -6286,7 +6286,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
.rpc_release = nfs4_layoutget_release, .rpc_release = nfs4_layoutget_release,
}; };
void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) 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 nfs_server *server = NFS_SERVER(lgp->args.inode);
size_t max_pages = max_response_pages(server); 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,6 +6304,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
.callback_data = lgp, .callback_data = lgp,
.flags = RPC_TASK_ASYNC, .flags = RPC_TASK_ASYNC,
}; };
struct pnfs_layout_segment *lseg = NULL;
int status = 0; int status = 0;
dprintk("--> %s\n", __func__); dprintk("--> %s\n", __func__);
...@@ -6310,7 +6312,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) ...@@ -6310,7 +6312,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
if (!lgp->args.layout.pages) { if (!lgp->args.layout.pages) {
nfs4_layoutget_release(lgp); nfs4_layoutget_release(lgp);
return; return ERR_PTR(-ENOMEM);
} }
lgp->args.layout.pglen = max_pages * PAGE_SIZE; lgp->args.layout.pglen = max_pages * PAGE_SIZE;
...@@ -6319,15 +6321,17 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) ...@@ -6319,15 +6321,17 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
task = rpc_run_task(&task_setup_data); task = rpc_run_task(&task_setup_data);
if (IS_ERR(task)) if (IS_ERR(task))
return; return ERR_CAST(task);
status = nfs4_wait_for_completion_rpc_task(task); status = nfs4_wait_for_completion_rpc_task(task);
if (status == 0) if (status == 0)
status = task->tk_status; status = task->tk_status;
if (status == 0) if (status == 0)
status = pnfs_layout_process(lgp); lseg = pnfs_layout_process(lgp);
rpc_put_task(task); rpc_put_task(task);
dprintk("<-- %s status=%d\n", __func__, status); dprintk("<-- %s status=%d\n", __func__, status);
return; if (status)
return ERR_PTR(status);
return lseg;
} }
static void static void
......
...@@ -582,7 +582,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, ...@@ -582,7 +582,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
struct inode *ino = lo->plh_inode; struct inode *ino = lo->plh_inode;
struct nfs_server *server = NFS_SERVER(ino); struct nfs_server *server = NFS_SERVER(ino);
struct nfs4_layoutget *lgp; struct nfs4_layoutget *lgp;
struct pnfs_layout_segment *lseg = NULL; struct pnfs_layout_segment *lseg;
dprintk("--> %s\n", __func__); dprintk("--> %s\n", __func__);
...@@ -599,16 +599,22 @@ send_layoutget(struct pnfs_layout_hdr *lo, ...@@ -599,16 +599,22 @@ send_layoutget(struct pnfs_layout_hdr *lo,
lgp->args.type = server->pnfs_curr_ld->id; lgp->args.type = server->pnfs_curr_ld->id;
lgp->args.inode = ino; lgp->args.inode = ino;
lgp->args.ctx = get_nfs_open_context(ctx); lgp->args.ctx = get_nfs_open_context(ctx);
lgp->lsegpp = &lseg;
lgp->gfp_flags = gfp_flags; lgp->gfp_flags = gfp_flags;
/* Synchronously retrieve layout information from server and /* Synchronously retrieve layout information from server and
* store in lseg. * store in lseg.
*/ */
nfs4_proc_layoutget(lgp, gfp_flags); lseg = nfs4_proc_layoutget(lgp, gfp_flags);
if (!lseg) { if (IS_ERR(lseg)) {
/* remember that LAYOUTGET failed and suspend trying */ switch (PTR_ERR(lseg)) {
set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); case -ENOMEM:
case -ERESTARTSYS:
break;
default:
/* remember that LAYOUTGET failed and suspend trying */
set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
}
return NULL;
} }
return lseg; return lseg;
...@@ -1096,7 +1102,7 @@ pnfs_update_layout(struct inode *ino, ...@@ -1096,7 +1102,7 @@ pnfs_update_layout(struct inode *ino,
} }
EXPORT_SYMBOL_GPL(pnfs_update_layout); EXPORT_SYMBOL_GPL(pnfs_update_layout);
int struct pnfs_layout_segment *
pnfs_layout_process(struct nfs4_layoutget *lgp) pnfs_layout_process(struct nfs4_layoutget *lgp)
{ {
struct pnfs_layout_hdr *lo = NFS_I(lgp->args.inode)->layout; struct pnfs_layout_hdr *lo = NFS_I(lgp->args.inode)->layout;
...@@ -1129,7 +1135,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1129,7 +1135,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
} }
init_lseg(lo, lseg); init_lseg(lo, lseg);
lseg->pls_range = res->range; lseg->pls_range = res->range;
*lgp->lsegpp = get_lseg(lseg); get_lseg(lseg);
pnfs_insert_layout(lo, lseg); pnfs_insert_layout(lo, lseg);
if (res->return_on_close) { if (res->return_on_close) {
...@@ -1140,8 +1146,9 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1140,8 +1146,9 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
/* Done processing layoutget. Set the layout stateid */ /* Done processing layoutget. Set the layout stateid */
pnfs_set_layout_stateid(lo, &res->stateid, false); pnfs_set_layout_stateid(lo, &res->stateid, false);
spin_unlock(&ino->i_lock); spin_unlock(&ino->i_lock);
return lseg;
out: out:
return status; return ERR_PTR(status);
out_forget_reply: out_forget_reply:
spin_unlock(&ino->i_lock); spin_unlock(&ino->i_lock);
......
...@@ -172,7 +172,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server, ...@@ -172,7 +172,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server,
struct pnfs_devicelist *devlist); struct pnfs_devicelist *devlist);
extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
struct pnfs_device *dev); struct pnfs_device *dev);
extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags); extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
/* pnfs.c */ /* pnfs.c */
...@@ -192,7 +192,7 @@ void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page ...@@ -192,7 +192,7 @@ void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page
int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc); int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg); void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg);
int pnfs_layout_process(struct nfs4_layoutget *lgp); struct pnfs_layout_segment *pnfs_layout_process(struct nfs4_layoutget *lgp);
void pnfs_free_lseg_list(struct list_head *tmp_list); void pnfs_free_lseg_list(struct list_head *tmp_list);
void pnfs_destroy_layout(struct nfs_inode *); void pnfs_destroy_layout(struct nfs_inode *);
void pnfs_destroy_all_layouts(struct nfs_client *); void pnfs_destroy_all_layouts(struct nfs_client *);
......
...@@ -251,7 +251,6 @@ struct nfs4_layoutget_res { ...@@ -251,7 +251,6 @@ struct nfs4_layoutget_res {
struct nfs4_layoutget { struct nfs4_layoutget {
struct nfs4_layoutget_args args; struct nfs4_layoutget_args args;
struct nfs4_layoutget_res res; struct nfs4_layoutget_res res;
struct pnfs_layout_segment **lsegpp;
gfp_t gfp_flags; gfp_t gfp_flags;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment