aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:27 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:27 -0500
commit788e7a89a03e364855583c0ab4649b94925efbb9 (patch)
tree4434c93af133a92f550ba0ecc8d3254cb222e72d /fs/nfs/nfs4proc.c
parent7117bf3dfb10b534a017260d9fc643bc1d0afd2a (diff)
NFS: Cleanup of NFS write code in preparation for asynchronous o_direct
This patch inverts the callback hierarchy for NFS write calls. Instead of having the NFSv2/v3/v4-specific code set up the RPC callback ops, we allow the original caller to do so. This allows for more flexibility w.r.t. how to set up and tear down the nfs_write_data structure while still allowing the NFSv3/v4 code to perform error handling. The greater flexibility is needed by the asynchronous O_DIRECT code, which wants to be able to hold on to the original nfs_write_data structures after the WRITE RPC call has completed in order to be able to replay them if the COMMIT call determines that the server has rebooted. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c54
1 files changed, 13 insertions, 41 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f1ff4fa6cce5..ef4dc315ecc2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2388,32 +2388,23 @@ nfs4_proc_read_setup(struct nfs_read_data *data)
2388 rpc_call_setup(task, &msg, 0); 2388 rpc_call_setup(task, &msg, 0);
2389} 2389}
2390 2390
2391static void nfs4_write_done(struct rpc_task *task, void *calldata) 2391static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2392{ 2392{
2393 struct nfs_write_data *data = calldata;
2394 struct inode *inode = data->inode; 2393 struct inode *inode = data->inode;
2395 2394
2396 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2395 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
2397 rpc_restart_call(task); 2396 rpc_restart_call(task);
2398 return; 2397 return -EAGAIN;
2399 } 2398 }
2400 if (task->tk_status >= 0) { 2399 if (task->tk_status >= 0) {
2401 renew_lease(NFS_SERVER(inode), data->timestamp); 2400 renew_lease(NFS_SERVER(inode), data->timestamp);
2402 nfs_post_op_update_inode(inode, data->res.fattr); 2401 nfs_post_op_update_inode(inode, data->res.fattr);
2403 } 2402 }
2404 /* Call back common NFS writeback processing */ 2403 return 0;
2405 nfs_writeback_done(task, calldata);
2406} 2404}
2407 2405
2408static const struct rpc_call_ops nfs4_write_ops = { 2406static void nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2409 .rpc_call_done = nfs4_write_done,
2410 .rpc_release = nfs_writedata_release,
2411};
2412
2413static void
2414nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2415{ 2407{
2416 struct rpc_task *task = &data->task;
2417 struct rpc_message msg = { 2408 struct rpc_message msg = {
2418 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], 2409 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
2419 .rpc_argp = &data->args, 2410 .rpc_argp = &data->args,
@@ -2423,7 +2414,6 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2423 struct inode *inode = data->inode; 2414 struct inode *inode = data->inode;
2424 struct nfs_server *server = NFS_SERVER(inode); 2415 struct nfs_server *server = NFS_SERVER(inode);
2425 int stable; 2416 int stable;
2426 int flags;
2427 2417
2428 if (how & FLUSH_STABLE) { 2418 if (how & FLUSH_STABLE) {
2429 if (!NFS_I(inode)->ncommit) 2419 if (!NFS_I(inode)->ncommit)
@@ -2438,57 +2428,37 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2438 2428
2439 data->timestamp = jiffies; 2429 data->timestamp = jiffies;
2440 2430
2441 /* Set the initial flags for the task. */
2442 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
2443
2444 /* Finalize the task. */ 2431 /* Finalize the task. */
2445 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_write_ops, data); 2432 rpc_call_setup(&data->task, &msg, 0);
2446 rpc_call_setup(task, &msg, 0);
2447} 2433}
2448 2434
2449static void nfs4_commit_done(struct rpc_task *task, void *calldata) 2435static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
2450{ 2436{
2451 struct nfs_write_data *data = calldata;
2452 struct inode *inode = data->inode; 2437 struct inode *inode = data->inode;
2453 2438
2454 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2439 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
2455 rpc_restart_call(task); 2440 rpc_restart_call(task);
2456 return; 2441 return -EAGAIN;
2457 } 2442 }
2458 if (task->tk_status >= 0) 2443 if (task->tk_status >= 0)
2459 nfs_post_op_update_inode(inode, data->res.fattr); 2444 nfs_post_op_update_inode(inode, data->res.fattr);
2460 /* Call back common NFS writeback processing */ 2445 return 0;
2461 nfs_commit_done(task, calldata);
2462} 2446}
2463 2447
2464static const struct rpc_call_ops nfs4_commit_ops = { 2448static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2465 .rpc_call_done = nfs4_commit_done,
2466 .rpc_release = nfs_commit_release,
2467};
2468
2469static void
2470nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2471{ 2449{
2472 struct rpc_task *task = &data->task;
2473 struct rpc_message msg = { 2450 struct rpc_message msg = {
2474 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT], 2451 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
2475 .rpc_argp = &data->args, 2452 .rpc_argp = &data->args,
2476 .rpc_resp = &data->res, 2453 .rpc_resp = &data->res,
2477 .rpc_cred = data->cred, 2454 .rpc_cred = data->cred,
2478 }; 2455 };
2479 struct inode *inode = data->inode; 2456 struct nfs_server *server = NFS_SERVER(data->inode);
2480 struct nfs_server *server = NFS_SERVER(inode);
2481 int flags;
2482 2457
2483 data->args.bitmask = server->attr_bitmask; 2458 data->args.bitmask = server->attr_bitmask;
2484 data->res.server = server; 2459 data->res.server = server;
2485 2460
2486 /* Set the initial flags for the task. */ 2461 rpc_call_setup(&data->task, &msg, 0);
2487 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
2488
2489 /* Finalize the task. */
2490 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_commit_ops, data);
2491 rpc_call_setup(task, &msg, 0);
2492} 2462}
2493 2463
2494/* 2464/*
@@ -3648,7 +3618,9 @@ struct nfs_rpc_ops nfs_v4_clientops = {
3648 .decode_dirent = nfs4_decode_dirent, 3618 .decode_dirent = nfs4_decode_dirent,
3649 .read_setup = nfs4_proc_read_setup, 3619 .read_setup = nfs4_proc_read_setup,
3650 .write_setup = nfs4_proc_write_setup, 3620 .write_setup = nfs4_proc_write_setup,
3621 .write_done = nfs4_write_done,
3651 .commit_setup = nfs4_proc_commit_setup, 3622 .commit_setup = nfs4_proc_commit_setup,
3623 .commit_done = nfs4_commit_done,
3652 .file_open = nfs_open, 3624 .file_open = nfs_open,
3653 .file_release = nfs_release, 3625 .file_release = nfs_release,
3654 .lock = nfs4_proc_lock, 3626 .lock = nfs4_proc_lock,