diff options
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 288 |
1 files changed, 137 insertions, 151 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 9e2e1c7291db..5c189bd57eb2 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -210,7 +210,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) | |||
210 | spin_lock(&dir->i_lock); | 210 | spin_lock(&dir->i_lock); |
211 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA; | 211 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA; |
212 | if (!cinfo->atomic || cinfo->before != nfsi->change_attr) | 212 | if (!cinfo->atomic || cinfo->before != nfsi->change_attr) |
213 | nfsi->cache_change_attribute = jiffies; | 213 | nfs_force_lookup_revalidate(dir); |
214 | nfsi->change_attr = cinfo->after; | 214 | nfsi->change_attr = cinfo->after; |
215 | spin_unlock(&dir->i_lock); | 215 | spin_unlock(&dir->i_lock); |
216 | } | 216 | } |
@@ -718,19 +718,6 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state | |||
718 | return err; | 718 | return err; |
719 | } | 719 | } |
720 | 720 | ||
721 | static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata) | ||
722 | { | ||
723 | struct nfs4_opendata *data = calldata; | ||
724 | struct rpc_message msg = { | ||
725 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM], | ||
726 | .rpc_argp = &data->c_arg, | ||
727 | .rpc_resp = &data->c_res, | ||
728 | .rpc_cred = data->owner->so_cred, | ||
729 | }; | ||
730 | data->timestamp = jiffies; | ||
731 | rpc_call_setup(task, &msg, 0); | ||
732 | } | ||
733 | |||
734 | static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) | 721 | static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) |
735 | { | 722 | { |
736 | struct nfs4_opendata *data = calldata; | 723 | struct nfs4_opendata *data = calldata; |
@@ -767,7 +754,6 @@ out_free: | |||
767 | } | 754 | } |
768 | 755 | ||
769 | static const struct rpc_call_ops nfs4_open_confirm_ops = { | 756 | static const struct rpc_call_ops nfs4_open_confirm_ops = { |
770 | .rpc_call_prepare = nfs4_open_confirm_prepare, | ||
771 | .rpc_call_done = nfs4_open_confirm_done, | 757 | .rpc_call_done = nfs4_open_confirm_done, |
772 | .rpc_release = nfs4_open_confirm_release, | 758 | .rpc_release = nfs4_open_confirm_release, |
773 | }; | 759 | }; |
@@ -779,12 +765,26 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) | |||
779 | { | 765 | { |
780 | struct nfs_server *server = NFS_SERVER(data->dir->d_inode); | 766 | struct nfs_server *server = NFS_SERVER(data->dir->d_inode); |
781 | struct rpc_task *task; | 767 | struct rpc_task *task; |
768 | struct rpc_message msg = { | ||
769 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM], | ||
770 | .rpc_argp = &data->c_arg, | ||
771 | .rpc_resp = &data->c_res, | ||
772 | .rpc_cred = data->owner->so_cred, | ||
773 | }; | ||
774 | struct rpc_task_setup task_setup_data = { | ||
775 | .rpc_client = server->client, | ||
776 | .rpc_message = &msg, | ||
777 | .callback_ops = &nfs4_open_confirm_ops, | ||
778 | .callback_data = data, | ||
779 | .flags = RPC_TASK_ASYNC, | ||
780 | }; | ||
782 | int status; | 781 | int status; |
783 | 782 | ||
784 | kref_get(&data->kref); | 783 | kref_get(&data->kref); |
785 | data->rpc_done = 0; | 784 | data->rpc_done = 0; |
786 | data->rpc_status = 0; | 785 | data->rpc_status = 0; |
787 | task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_confirm_ops, data); | 786 | data->timestamp = jiffies; |
787 | task = rpc_run_task(&task_setup_data); | ||
788 | if (IS_ERR(task)) | 788 | if (IS_ERR(task)) |
789 | return PTR_ERR(task); | 789 | return PTR_ERR(task); |
790 | status = nfs4_wait_for_completion_rpc_task(task); | 790 | status = nfs4_wait_for_completion_rpc_task(task); |
@@ -801,13 +801,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) | |||
801 | { | 801 | { |
802 | struct nfs4_opendata *data = calldata; | 802 | struct nfs4_opendata *data = calldata; |
803 | struct nfs4_state_owner *sp = data->owner; | 803 | struct nfs4_state_owner *sp = data->owner; |
804 | struct rpc_message msg = { | 804 | |
805 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN], | ||
806 | .rpc_argp = &data->o_arg, | ||
807 | .rpc_resp = &data->o_res, | ||
808 | .rpc_cred = sp->so_cred, | ||
809 | }; | ||
810 | |||
811 | if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) | 805 | if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) |
812 | return; | 806 | return; |
813 | /* | 807 | /* |
@@ -832,11 +826,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) | |||
832 | data->o_arg.id = sp->so_owner_id.id; | 826 | data->o_arg.id = sp->so_owner_id.id; |
833 | data->o_arg.clientid = sp->so_client->cl_clientid; | 827 | data->o_arg.clientid = sp->so_client->cl_clientid; |
834 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { | 828 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { |
835 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; | 829 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; |
836 | nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); | 830 | nfs_copy_fh(&data->o_res.fh, data->o_arg.fh); |
837 | } | 831 | } |
838 | data->timestamp = jiffies; | 832 | data->timestamp = jiffies; |
839 | rpc_call_setup(task, &msg, 0); | 833 | rpc_call_start(task); |
840 | return; | 834 | return; |
841 | out_no_action: | 835 | out_no_action: |
842 | task->tk_action = NULL; | 836 | task->tk_action = NULL; |
@@ -908,13 +902,26 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
908 | struct nfs_openargs *o_arg = &data->o_arg; | 902 | struct nfs_openargs *o_arg = &data->o_arg; |
909 | struct nfs_openres *o_res = &data->o_res; | 903 | struct nfs_openres *o_res = &data->o_res; |
910 | struct rpc_task *task; | 904 | struct rpc_task *task; |
905 | struct rpc_message msg = { | ||
906 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN], | ||
907 | .rpc_argp = o_arg, | ||
908 | .rpc_resp = o_res, | ||
909 | .rpc_cred = data->owner->so_cred, | ||
910 | }; | ||
911 | struct rpc_task_setup task_setup_data = { | ||
912 | .rpc_client = server->client, | ||
913 | .rpc_message = &msg, | ||
914 | .callback_ops = &nfs4_open_ops, | ||
915 | .callback_data = data, | ||
916 | .flags = RPC_TASK_ASYNC, | ||
917 | }; | ||
911 | int status; | 918 | int status; |
912 | 919 | ||
913 | kref_get(&data->kref); | 920 | kref_get(&data->kref); |
914 | data->rpc_done = 0; | 921 | data->rpc_done = 0; |
915 | data->rpc_status = 0; | 922 | data->rpc_status = 0; |
916 | data->cancelled = 0; | 923 | data->cancelled = 0; |
917 | task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_ops, data); | 924 | task = rpc_run_task(&task_setup_data); |
918 | if (IS_ERR(task)) | 925 | if (IS_ERR(task)) |
919 | return PTR_ERR(task); | 926 | return PTR_ERR(task); |
920 | status = nfs4_wait_for_completion_rpc_task(task); | 927 | status = nfs4_wait_for_completion_rpc_task(task); |
@@ -1244,12 +1251,6 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
1244 | { | 1251 | { |
1245 | struct nfs4_closedata *calldata = data; | 1252 | struct nfs4_closedata *calldata = data; |
1246 | struct nfs4_state *state = calldata->state; | 1253 | struct nfs4_state *state = calldata->state; |
1247 | struct rpc_message msg = { | ||
1248 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE], | ||
1249 | .rpc_argp = &calldata->arg, | ||
1250 | .rpc_resp = &calldata->res, | ||
1251 | .rpc_cred = state->owner->so_cred, | ||
1252 | }; | ||
1253 | int clear_rd, clear_wr, clear_rdwr; | 1254 | int clear_rd, clear_wr, clear_rdwr; |
1254 | 1255 | ||
1255 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) | 1256 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) |
@@ -1276,14 +1277,14 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
1276 | } | 1277 | } |
1277 | nfs_fattr_init(calldata->res.fattr); | 1278 | nfs_fattr_init(calldata->res.fattr); |
1278 | if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) { | 1279 | if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) { |
1279 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; | 1280 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; |
1280 | calldata->arg.open_flags = FMODE_READ; | 1281 | calldata->arg.open_flags = FMODE_READ; |
1281 | } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) { | 1282 | } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) { |
1282 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; | 1283 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; |
1283 | calldata->arg.open_flags = FMODE_WRITE; | 1284 | calldata->arg.open_flags = FMODE_WRITE; |
1284 | } | 1285 | } |
1285 | calldata->timestamp = jiffies; | 1286 | calldata->timestamp = jiffies; |
1286 | rpc_call_setup(task, &msg, 0); | 1287 | rpc_call_start(task); |
1287 | } | 1288 | } |
1288 | 1289 | ||
1289 | static const struct rpc_call_ops nfs4_close_ops = { | 1290 | static const struct rpc_call_ops nfs4_close_ops = { |
@@ -1309,6 +1310,16 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) | |||
1309 | struct nfs4_closedata *calldata; | 1310 | struct nfs4_closedata *calldata; |
1310 | struct nfs4_state_owner *sp = state->owner; | 1311 | struct nfs4_state_owner *sp = state->owner; |
1311 | struct rpc_task *task; | 1312 | struct rpc_task *task; |
1313 | struct rpc_message msg = { | ||
1314 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE], | ||
1315 | .rpc_cred = state->owner->so_cred, | ||
1316 | }; | ||
1317 | struct rpc_task_setup task_setup_data = { | ||
1318 | .rpc_client = server->client, | ||
1319 | .rpc_message = &msg, | ||
1320 | .callback_ops = &nfs4_close_ops, | ||
1321 | .flags = RPC_TASK_ASYNC, | ||
1322 | }; | ||
1312 | int status = -ENOMEM; | 1323 | int status = -ENOMEM; |
1313 | 1324 | ||
1314 | calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); | 1325 | calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); |
@@ -1328,7 +1339,10 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) | |||
1328 | calldata->path.mnt = mntget(path->mnt); | 1339 | calldata->path.mnt = mntget(path->mnt); |
1329 | calldata->path.dentry = dget(path->dentry); | 1340 | calldata->path.dentry = dget(path->dentry); |
1330 | 1341 | ||
1331 | task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata); | 1342 | msg.rpc_argp = &calldata->arg, |
1343 | msg.rpc_resp = &calldata->res, | ||
1344 | task_setup_data.callback_data = calldata; | ||
1345 | task = rpc_run_task(&task_setup_data); | ||
1332 | if (IS_ERR(task)) | 1346 | if (IS_ERR(task)) |
1333 | return PTR_ERR(task); | 1347 | return PTR_ERR(task); |
1334 | status = 0; | 1348 | status = 0; |
@@ -2414,18 +2428,10 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) | |||
2414 | return 0; | 2428 | return 0; |
2415 | } | 2429 | } |
2416 | 2430 | ||
2417 | static void nfs4_proc_read_setup(struct nfs_read_data *data) | 2431 | static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) |
2418 | { | 2432 | { |
2419 | struct rpc_message msg = { | ||
2420 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ], | ||
2421 | .rpc_argp = &data->args, | ||
2422 | .rpc_resp = &data->res, | ||
2423 | .rpc_cred = data->cred, | ||
2424 | }; | ||
2425 | |||
2426 | data->timestamp = jiffies; | 2433 | data->timestamp = jiffies; |
2427 | 2434 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; | |
2428 | rpc_call_setup(&data->task, &msg, 0); | ||
2429 | } | 2435 | } |
2430 | 2436 | ||
2431 | static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) | 2437 | static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) |
@@ -2443,33 +2449,15 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) | |||
2443 | return 0; | 2449 | return 0; |
2444 | } | 2450 | } |
2445 | 2451 | ||
2446 | static void nfs4_proc_write_setup(struct nfs_write_data *data, int how) | 2452 | static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg) |
2447 | { | 2453 | { |
2448 | struct rpc_message msg = { | 2454 | struct nfs_server *server = NFS_SERVER(data->inode); |
2449 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], | 2455 | |
2450 | .rpc_argp = &data->args, | ||
2451 | .rpc_resp = &data->res, | ||
2452 | .rpc_cred = data->cred, | ||
2453 | }; | ||
2454 | struct inode *inode = data->inode; | ||
2455 | struct nfs_server *server = NFS_SERVER(inode); | ||
2456 | int stable; | ||
2457 | |||
2458 | if (how & FLUSH_STABLE) { | ||
2459 | if (!NFS_I(inode)->ncommit) | ||
2460 | stable = NFS_FILE_SYNC; | ||
2461 | else | ||
2462 | stable = NFS_DATA_SYNC; | ||
2463 | } else | ||
2464 | stable = NFS_UNSTABLE; | ||
2465 | data->args.stable = stable; | ||
2466 | data->args.bitmask = server->attr_bitmask; | 2456 | data->args.bitmask = server->attr_bitmask; |
2467 | data->res.server = server; | 2457 | data->res.server = server; |
2468 | |||
2469 | data->timestamp = jiffies; | 2458 | data->timestamp = jiffies; |
2470 | 2459 | ||
2471 | /* Finalize the task. */ | 2460 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; |
2472 | rpc_call_setup(&data->task, &msg, 0); | ||
2473 | } | 2461 | } |
2474 | 2462 | ||
2475 | static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) | 2463 | static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) |
@@ -2484,20 +2472,13 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) | |||
2484 | return 0; | 2472 | return 0; |
2485 | } | 2473 | } |
2486 | 2474 | ||
2487 | static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how) | 2475 | static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg) |
2488 | { | 2476 | { |
2489 | struct rpc_message msg = { | ||
2490 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT], | ||
2491 | .rpc_argp = &data->args, | ||
2492 | .rpc_resp = &data->res, | ||
2493 | .rpc_cred = data->cred, | ||
2494 | }; | ||
2495 | struct nfs_server *server = NFS_SERVER(data->inode); | 2477 | struct nfs_server *server = NFS_SERVER(data->inode); |
2496 | 2478 | ||
2497 | data->args.bitmask = server->attr_bitmask; | 2479 | data->args.bitmask = server->attr_bitmask; |
2498 | data->res.server = server; | 2480 | data->res.server = server; |
2499 | 2481 | msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; | |
2500 | rpc_call_setup(&data->task, &msg, 0); | ||
2501 | } | 2482 | } |
2502 | 2483 | ||
2503 | /* | 2484 | /* |
@@ -2910,14 +2891,20 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po | |||
2910 | 2891 | ||
2911 | for(;;) { | 2892 | for(;;) { |
2912 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, | 2893 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, |
2913 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", | 2894 | sizeof(setclientid.sc_name), "%s/%s %s %s %u", |
2914 | clp->cl_ipaddr, NIPQUAD(clp->cl_addr.sin_addr), | 2895 | clp->cl_ipaddr, |
2896 | rpc_peeraddr2str(clp->cl_rpcclient, | ||
2897 | RPC_DISPLAY_ADDR), | ||
2898 | rpc_peeraddr2str(clp->cl_rpcclient, | ||
2899 | RPC_DISPLAY_PROTO), | ||
2915 | cred->cr_ops->cr_name, | 2900 | cred->cr_ops->cr_name, |
2916 | clp->cl_id_uniquifier); | 2901 | clp->cl_id_uniquifier); |
2917 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, | 2902 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, |
2918 | sizeof(setclientid.sc_netid), "tcp"); | 2903 | sizeof(setclientid.sc_netid), |
2904 | rpc_peeraddr2str(clp->cl_rpcclient, | ||
2905 | RPC_DISPLAY_NETID)); | ||
2919 | setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr, | 2906 | setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr, |
2920 | sizeof(setclientid.sc_uaddr), "%s.%d.%d", | 2907 | sizeof(setclientid.sc_uaddr), "%s.%u.%u", |
2921 | clp->cl_ipaddr, port >> 8, port & 255); | 2908 | clp->cl_ipaddr, port >> 8, port & 255); |
2922 | 2909 | ||
2923 | status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); | 2910 | status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); |
@@ -2981,25 +2968,11 @@ struct nfs4_delegreturndata { | |||
2981 | struct nfs4_delegreturnres res; | 2968 | struct nfs4_delegreturnres res; |
2982 | struct nfs_fh fh; | 2969 | struct nfs_fh fh; |
2983 | nfs4_stateid stateid; | 2970 | nfs4_stateid stateid; |
2984 | struct rpc_cred *cred; | ||
2985 | unsigned long timestamp; | 2971 | unsigned long timestamp; |
2986 | struct nfs_fattr fattr; | 2972 | struct nfs_fattr fattr; |
2987 | int rpc_status; | 2973 | int rpc_status; |
2988 | }; | 2974 | }; |
2989 | 2975 | ||
2990 | static void nfs4_delegreturn_prepare(struct rpc_task *task, void *calldata) | ||
2991 | { | ||
2992 | struct nfs4_delegreturndata *data = calldata; | ||
2993 | struct rpc_message msg = { | ||
2994 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], | ||
2995 | .rpc_argp = &data->args, | ||
2996 | .rpc_resp = &data->res, | ||
2997 | .rpc_cred = data->cred, | ||
2998 | }; | ||
2999 | nfs_fattr_init(data->res.fattr); | ||
3000 | rpc_call_setup(task, &msg, 0); | ||
3001 | } | ||
3002 | |||
3003 | static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) | 2976 | static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) |
3004 | { | 2977 | { |
3005 | struct nfs4_delegreturndata *data = calldata; | 2978 | struct nfs4_delegreturndata *data = calldata; |
@@ -3010,24 +2983,30 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) | |||
3010 | 2983 | ||
3011 | static void nfs4_delegreturn_release(void *calldata) | 2984 | static void nfs4_delegreturn_release(void *calldata) |
3012 | { | 2985 | { |
3013 | struct nfs4_delegreturndata *data = calldata; | ||
3014 | |||
3015 | put_rpccred(data->cred); | ||
3016 | kfree(calldata); | 2986 | kfree(calldata); |
3017 | } | 2987 | } |
3018 | 2988 | ||
3019 | static const struct rpc_call_ops nfs4_delegreturn_ops = { | 2989 | static const struct rpc_call_ops nfs4_delegreturn_ops = { |
3020 | .rpc_call_prepare = nfs4_delegreturn_prepare, | ||
3021 | .rpc_call_done = nfs4_delegreturn_done, | 2990 | .rpc_call_done = nfs4_delegreturn_done, |
3022 | .rpc_release = nfs4_delegreturn_release, | 2991 | .rpc_release = nfs4_delegreturn_release, |
3023 | }; | 2992 | }; |
3024 | 2993 | ||
3025 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | 2994 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync) |
3026 | { | 2995 | { |
3027 | struct nfs4_delegreturndata *data; | 2996 | struct nfs4_delegreturndata *data; |
3028 | struct nfs_server *server = NFS_SERVER(inode); | 2997 | struct nfs_server *server = NFS_SERVER(inode); |
3029 | struct rpc_task *task; | 2998 | struct rpc_task *task; |
3030 | int status; | 2999 | struct rpc_message msg = { |
3000 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], | ||
3001 | .rpc_cred = cred, | ||
3002 | }; | ||
3003 | struct rpc_task_setup task_setup_data = { | ||
3004 | .rpc_client = server->client, | ||
3005 | .rpc_message = &msg, | ||
3006 | .callback_ops = &nfs4_delegreturn_ops, | ||
3007 | .flags = RPC_TASK_ASYNC, | ||
3008 | }; | ||
3009 | int status = 0; | ||
3031 | 3010 | ||
3032 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 3011 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
3033 | if (data == NULL) | 3012 | if (data == NULL) |
@@ -3039,30 +3018,37 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co | |||
3039 | memcpy(&data->stateid, stateid, sizeof(data->stateid)); | 3018 | memcpy(&data->stateid, stateid, sizeof(data->stateid)); |
3040 | data->res.fattr = &data->fattr; | 3019 | data->res.fattr = &data->fattr; |
3041 | data->res.server = server; | 3020 | data->res.server = server; |
3042 | data->cred = get_rpccred(cred); | 3021 | nfs_fattr_init(data->res.fattr); |
3043 | data->timestamp = jiffies; | 3022 | data->timestamp = jiffies; |
3044 | data->rpc_status = 0; | 3023 | data->rpc_status = 0; |
3045 | 3024 | ||
3046 | task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); | 3025 | task_setup_data.callback_data = data; |
3026 | msg.rpc_argp = &data->args, | ||
3027 | msg.rpc_resp = &data->res, | ||
3028 | task = rpc_run_task(&task_setup_data); | ||
3047 | if (IS_ERR(task)) | 3029 | if (IS_ERR(task)) |
3048 | return PTR_ERR(task); | 3030 | return PTR_ERR(task); |
3031 | if (!issync) | ||
3032 | goto out; | ||
3049 | status = nfs4_wait_for_completion_rpc_task(task); | 3033 | status = nfs4_wait_for_completion_rpc_task(task); |
3050 | if (status == 0) { | 3034 | if (status != 0) |
3051 | status = data->rpc_status; | 3035 | goto out; |
3052 | if (status == 0) | 3036 | status = data->rpc_status; |
3053 | nfs_refresh_inode(inode, &data->fattr); | 3037 | if (status != 0) |
3054 | } | 3038 | goto out; |
3039 | nfs_refresh_inode(inode, &data->fattr); | ||
3040 | out: | ||
3055 | rpc_put_task(task); | 3041 | rpc_put_task(task); |
3056 | return status; | 3042 | return status; |
3057 | } | 3043 | } |
3058 | 3044 | ||
3059 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | 3045 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync) |
3060 | { | 3046 | { |
3061 | struct nfs_server *server = NFS_SERVER(inode); | 3047 | struct nfs_server *server = NFS_SERVER(inode); |
3062 | struct nfs4_exception exception = { }; | 3048 | struct nfs4_exception exception = { }; |
3063 | int err; | 3049 | int err; |
3064 | do { | 3050 | do { |
3065 | err = _nfs4_proc_delegreturn(inode, cred, stateid); | 3051 | err = _nfs4_proc_delegreturn(inode, cred, stateid, issync); |
3066 | switch (err) { | 3052 | switch (err) { |
3067 | case -NFS4ERR_STALE_STATEID: | 3053 | case -NFS4ERR_STALE_STATEID: |
3068 | case -NFS4ERR_EXPIRED: | 3054 | case -NFS4ERR_EXPIRED: |
@@ -3230,12 +3216,6 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) | |||
3230 | static void nfs4_locku_prepare(struct rpc_task *task, void *data) | 3216 | static void nfs4_locku_prepare(struct rpc_task *task, void *data) |
3231 | { | 3217 | { |
3232 | struct nfs4_unlockdata *calldata = data; | 3218 | struct nfs4_unlockdata *calldata = data; |
3233 | struct rpc_message msg = { | ||
3234 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU], | ||
3235 | .rpc_argp = &calldata->arg, | ||
3236 | .rpc_resp = &calldata->res, | ||
3237 | .rpc_cred = calldata->lsp->ls_state->owner->so_cred, | ||
3238 | }; | ||
3239 | 3219 | ||
3240 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) | 3220 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) |
3241 | return; | 3221 | return; |
@@ -3245,7 +3225,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) | |||
3245 | return; | 3225 | return; |
3246 | } | 3226 | } |
3247 | calldata->timestamp = jiffies; | 3227 | calldata->timestamp = jiffies; |
3248 | rpc_call_setup(task, &msg, 0); | 3228 | rpc_call_start(task); |
3249 | } | 3229 | } |
3250 | 3230 | ||
3251 | static const struct rpc_call_ops nfs4_locku_ops = { | 3231 | static const struct rpc_call_ops nfs4_locku_ops = { |
@@ -3260,6 +3240,16 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, | |||
3260 | struct nfs_seqid *seqid) | 3240 | struct nfs_seqid *seqid) |
3261 | { | 3241 | { |
3262 | struct nfs4_unlockdata *data; | 3242 | struct nfs4_unlockdata *data; |
3243 | struct rpc_message msg = { | ||
3244 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU], | ||
3245 | .rpc_cred = ctx->cred, | ||
3246 | }; | ||
3247 | struct rpc_task_setup task_setup_data = { | ||
3248 | .rpc_client = NFS_CLIENT(lsp->ls_state->inode), | ||
3249 | .rpc_message = &msg, | ||
3250 | .callback_ops = &nfs4_locku_ops, | ||
3251 | .flags = RPC_TASK_ASYNC, | ||
3252 | }; | ||
3263 | 3253 | ||
3264 | /* Ensure this is an unlock - when canceling a lock, the | 3254 | /* Ensure this is an unlock - when canceling a lock, the |
3265 | * canceled lock is passed in, and it won't be an unlock. | 3255 | * canceled lock is passed in, and it won't be an unlock. |
@@ -3272,7 +3262,10 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, | |||
3272 | return ERR_PTR(-ENOMEM); | 3262 | return ERR_PTR(-ENOMEM); |
3273 | } | 3263 | } |
3274 | 3264 | ||
3275 | return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data); | 3265 | msg.rpc_argp = &data->arg, |
3266 | msg.rpc_resp = &data->res, | ||
3267 | task_setup_data.callback_data = data; | ||
3268 | return rpc_run_task(&task_setup_data); | ||
3276 | } | 3269 | } |
3277 | 3270 | ||
3278 | static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) | 3271 | static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) |
@@ -3331,15 +3324,12 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, | |||
3331 | 3324 | ||
3332 | p->arg.fh = NFS_FH(inode); | 3325 | p->arg.fh = NFS_FH(inode); |
3333 | p->arg.fl = &p->fl; | 3326 | p->arg.fl = &p->fl; |
3334 | if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) { | 3327 | p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid); |
3335 | p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid); | 3328 | if (p->arg.open_seqid == NULL) |
3336 | if (p->arg.open_seqid == NULL) | 3329 | goto out_free; |
3337 | goto out_free; | ||
3338 | |||
3339 | } | ||
3340 | p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); | 3330 | p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); |
3341 | if (p->arg.lock_seqid == NULL) | 3331 | if (p->arg.lock_seqid == NULL) |
3342 | goto out_free; | 3332 | goto out_free_seqid; |
3343 | p->arg.lock_stateid = &lsp->ls_stateid; | 3333 | p->arg.lock_stateid = &lsp->ls_stateid; |
3344 | p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; | 3334 | p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; |
3345 | p->arg.lock_owner.id = lsp->ls_id.id; | 3335 | p->arg.lock_owner.id = lsp->ls_id.id; |
@@ -3348,9 +3338,9 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, | |||
3348 | p->ctx = get_nfs_open_context(ctx); | 3338 | p->ctx = get_nfs_open_context(ctx); |
3349 | memcpy(&p->fl, fl, sizeof(p->fl)); | 3339 | memcpy(&p->fl, fl, sizeof(p->fl)); |
3350 | return p; | 3340 | return p; |
3341 | out_free_seqid: | ||
3342 | nfs_free_seqid(p->arg.open_seqid); | ||
3351 | out_free: | 3343 | out_free: |
3352 | if (p->arg.open_seqid != NULL) | ||
3353 | nfs_free_seqid(p->arg.open_seqid); | ||
3354 | kfree(p); | 3344 | kfree(p); |
3355 | return NULL; | 3345 | return NULL; |
3356 | } | 3346 | } |
@@ -3359,31 +3349,20 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) | |||
3359 | { | 3349 | { |
3360 | struct nfs4_lockdata *data = calldata; | 3350 | struct nfs4_lockdata *data = calldata; |
3361 | struct nfs4_state *state = data->lsp->ls_state; | 3351 | struct nfs4_state *state = data->lsp->ls_state; |
3362 | struct nfs4_state_owner *sp = state->owner; | ||
3363 | struct rpc_message msg = { | ||
3364 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCK], | ||
3365 | .rpc_argp = &data->arg, | ||
3366 | .rpc_resp = &data->res, | ||
3367 | .rpc_cred = sp->so_cred, | ||
3368 | }; | ||
3369 | 3352 | ||
3370 | dprintk("%s: begin!\n", __FUNCTION__); | 3353 | dprintk("%s: begin!\n", __FUNCTION__); |
3354 | if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0) | ||
3355 | return; | ||
3371 | /* Do we need to do an open_to_lock_owner? */ | 3356 | /* Do we need to do an open_to_lock_owner? */ |
3372 | if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { | 3357 | if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { |
3373 | if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) | 3358 | if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) |
3374 | return; | 3359 | return; |
3375 | data->arg.open_stateid = &state->stateid; | 3360 | data->arg.open_stateid = &state->stateid; |
3376 | data->arg.new_lock_owner = 1; | 3361 | data->arg.new_lock_owner = 1; |
3377 | /* Retest in case we raced... */ | 3362 | } else |
3378 | if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) | 3363 | data->arg.new_lock_owner = 0; |
3379 | goto do_rpc; | ||
3380 | } | ||
3381 | if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0) | ||
3382 | return; | ||
3383 | data->arg.new_lock_owner = 0; | ||
3384 | do_rpc: | ||
3385 | data->timestamp = jiffies; | 3364 | data->timestamp = jiffies; |
3386 | rpc_call_setup(task, &msg, 0); | 3365 | rpc_call_start(task); |
3387 | dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status); | 3366 | dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status); |
3388 | } | 3367 | } |
3389 | 3368 | ||
@@ -3419,6 +3398,7 @@ static void nfs4_lock_release(void *calldata) | |||
3419 | struct nfs4_lockdata *data = calldata; | 3398 | struct nfs4_lockdata *data = calldata; |
3420 | 3399 | ||
3421 | dprintk("%s: begin!\n", __FUNCTION__); | 3400 | dprintk("%s: begin!\n", __FUNCTION__); |
3401 | nfs_free_seqid(data->arg.open_seqid); | ||
3422 | if (data->cancelled != 0) { | 3402 | if (data->cancelled != 0) { |
3423 | struct rpc_task *task; | 3403 | struct rpc_task *task; |
3424 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, | 3404 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, |
@@ -3428,8 +3408,6 @@ static void nfs4_lock_release(void *calldata) | |||
3428 | dprintk("%s: cancelling lock!\n", __FUNCTION__); | 3408 | dprintk("%s: cancelling lock!\n", __FUNCTION__); |
3429 | } else | 3409 | } else |
3430 | nfs_free_seqid(data->arg.lock_seqid); | 3410 | nfs_free_seqid(data->arg.lock_seqid); |
3431 | if (data->arg.open_seqid != NULL) | ||
3432 | nfs_free_seqid(data->arg.open_seqid); | ||
3433 | nfs4_put_lock_state(data->lsp); | 3411 | nfs4_put_lock_state(data->lsp); |
3434 | put_nfs_open_context(data->ctx); | 3412 | put_nfs_open_context(data->ctx); |
3435 | kfree(data); | 3413 | kfree(data); |
@@ -3446,6 +3424,16 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f | |||
3446 | { | 3424 | { |
3447 | struct nfs4_lockdata *data; | 3425 | struct nfs4_lockdata *data; |
3448 | struct rpc_task *task; | 3426 | struct rpc_task *task; |
3427 | struct rpc_message msg = { | ||
3428 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCK], | ||
3429 | .rpc_cred = state->owner->so_cred, | ||
3430 | }; | ||
3431 | struct rpc_task_setup task_setup_data = { | ||
3432 | .rpc_client = NFS_CLIENT(state->inode), | ||
3433 | .rpc_message = &msg, | ||
3434 | .callback_ops = &nfs4_lock_ops, | ||
3435 | .flags = RPC_TASK_ASYNC, | ||
3436 | }; | ||
3449 | int ret; | 3437 | int ret; |
3450 | 3438 | ||
3451 | dprintk("%s: begin!\n", __FUNCTION__); | 3439 | dprintk("%s: begin!\n", __FUNCTION__); |
@@ -3457,8 +3445,10 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f | |||
3457 | data->arg.block = 1; | 3445 | data->arg.block = 1; |
3458 | if (reclaim != 0) | 3446 | if (reclaim != 0) |
3459 | data->arg.reclaim = 1; | 3447 | data->arg.reclaim = 1; |
3460 | task = rpc_run_task(NFS_CLIENT(state->inode), RPC_TASK_ASYNC, | 3448 | msg.rpc_argp = &data->arg, |
3461 | &nfs4_lock_ops, data); | 3449 | msg.rpc_resp = &data->res, |
3450 | task_setup_data.callback_data = data; | ||
3451 | task = rpc_run_task(&task_setup_data); | ||
3462 | if (IS_ERR(task)) | 3452 | if (IS_ERR(task)) |
3463 | return PTR_ERR(task); | 3453 | return PTR_ERR(task); |
3464 | ret = nfs4_wait_for_completion_rpc_task(task); | 3454 | ret = nfs4_wait_for_completion_rpc_task(task); |
@@ -3631,10 +3621,6 @@ int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf, | |||
3631 | if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0) | 3621 | if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0) |
3632 | return -EOPNOTSUPP; | 3622 | return -EOPNOTSUPP; |
3633 | 3623 | ||
3634 | if (!S_ISREG(inode->i_mode) && | ||
3635 | (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) | ||
3636 | return -EPERM; | ||
3637 | |||
3638 | return nfs4_proc_set_acl(inode, buf, buflen); | 3624 | return nfs4_proc_set_acl(inode, buf, buflen); |
3639 | } | 3625 | } |
3640 | 3626 | ||