diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/client.c | 2 | ||||
-rw-r--r-- | fs/nfs/dir.c | 2 | ||||
-rw-r--r-- | fs/nfs/direct.c | 9 | ||||
-rw-r--r-- | fs/nfs/inode.c | 45 | ||||
-rw-r--r-- | fs/nfs/internal.h | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 18 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 8 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 2 | ||||
-rw-r--r-- | fs/nfs/read.c | 16 | ||||
-rw-r--r-- | fs/nfs/unlink.c | 2 | ||||
-rw-r--r-- | fs/nfs/write.c | 63 |
11 files changed, 113 insertions, 55 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index c5c0175898f6..06f064d8fbbe 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -170,6 +170,8 @@ static void nfs4_shutdown_client(struct nfs_client *clp) | |||
170 | BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners)); | 170 | BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners)); |
171 | if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) | 171 | if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) |
172 | nfs_idmap_delete(clp); | 172 | nfs_idmap_delete(clp); |
173 | |||
174 | rpc_destroy_wait_queue(&clp->cl_rpcwaitq); | ||
173 | #endif | 175 | #endif |
174 | } | 176 | } |
175 | 177 | ||
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 6cea7479c5b4..d583654a0b39 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1966,7 +1966,7 @@ force_lookup: | |||
1966 | if (!NFS_PROTO(inode)->access) | 1966 | if (!NFS_PROTO(inode)->access) |
1967 | goto out_notsup; | 1967 | goto out_notsup; |
1968 | 1968 | ||
1969 | cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); | 1969 | cred = rpc_lookup_cred(); |
1970 | if (!IS_ERR(cred)) { | 1970 | if (!IS_ERR(cred)) { |
1971 | res = nfs_do_access(inode, cred, mask); | 1971 | res = nfs_do_access(inode, cred, mask); |
1972 | put_rpccred(cred); | 1972 | put_rpccred(cred); |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 16844f98f50e..e44200579c8d 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -280,6 +280,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, | |||
280 | .rpc_client = NFS_CLIENT(inode), | 280 | .rpc_client = NFS_CLIENT(inode), |
281 | .rpc_message = &msg, | 281 | .rpc_message = &msg, |
282 | .callback_ops = &nfs_read_direct_ops, | 282 | .callback_ops = &nfs_read_direct_ops, |
283 | .workqueue = nfsiod_workqueue, | ||
283 | .flags = RPC_TASK_ASYNC, | 284 | .flags = RPC_TASK_ASYNC, |
284 | }; | 285 | }; |
285 | unsigned int pgbase; | 286 | unsigned int pgbase; |
@@ -323,7 +324,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, | |||
323 | data->inode = inode; | 324 | data->inode = inode; |
324 | data->cred = msg.rpc_cred; | 325 | data->cred = msg.rpc_cred; |
325 | data->args.fh = NFS_FH(inode); | 326 | data->args.fh = NFS_FH(inode); |
326 | data->args.context = ctx; | 327 | data->args.context = get_nfs_open_context(ctx); |
327 | data->args.offset = pos; | 328 | data->args.offset = pos; |
328 | data->args.pgbase = pgbase; | 329 | data->args.pgbase = pgbase; |
329 | data->args.pages = data->pagevec; | 330 | data->args.pages = data->pagevec; |
@@ -446,6 +447,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | |||
446 | struct rpc_task_setup task_setup_data = { | 447 | struct rpc_task_setup task_setup_data = { |
447 | .rpc_client = NFS_CLIENT(inode), | 448 | .rpc_client = NFS_CLIENT(inode), |
448 | .callback_ops = &nfs_write_direct_ops, | 449 | .callback_ops = &nfs_write_direct_ops, |
450 | .workqueue = nfsiod_workqueue, | ||
449 | .flags = RPC_TASK_ASYNC, | 451 | .flags = RPC_TASK_ASYNC, |
450 | }; | 452 | }; |
451 | 453 | ||
@@ -537,6 +539,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | |||
537 | .rpc_message = &msg, | 539 | .rpc_message = &msg, |
538 | .callback_ops = &nfs_commit_direct_ops, | 540 | .callback_ops = &nfs_commit_direct_ops, |
539 | .callback_data = data, | 541 | .callback_data = data, |
542 | .workqueue = nfsiod_workqueue, | ||
540 | .flags = RPC_TASK_ASYNC, | 543 | .flags = RPC_TASK_ASYNC, |
541 | }; | 544 | }; |
542 | 545 | ||
@@ -546,6 +549,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | |||
546 | data->args.fh = NFS_FH(data->inode); | 549 | data->args.fh = NFS_FH(data->inode); |
547 | data->args.offset = 0; | 550 | data->args.offset = 0; |
548 | data->args.count = 0; | 551 | data->args.count = 0; |
552 | data->args.context = get_nfs_open_context(dreq->ctx); | ||
549 | data->res.count = 0; | 553 | data->res.count = 0; |
550 | data->res.fattr = &data->fattr; | 554 | data->res.fattr = &data->fattr; |
551 | data->res.verf = &data->verf; | 555 | data->res.verf = &data->verf; |
@@ -682,6 +686,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, | |||
682 | .rpc_client = NFS_CLIENT(inode), | 686 | .rpc_client = NFS_CLIENT(inode), |
683 | .rpc_message = &msg, | 687 | .rpc_message = &msg, |
684 | .callback_ops = &nfs_write_direct_ops, | 688 | .callback_ops = &nfs_write_direct_ops, |
689 | .workqueue = nfsiod_workqueue, | ||
685 | .flags = RPC_TASK_ASYNC, | 690 | .flags = RPC_TASK_ASYNC, |
686 | }; | 691 | }; |
687 | size_t wsize = NFS_SERVER(inode)->wsize; | 692 | size_t wsize = NFS_SERVER(inode)->wsize; |
@@ -728,7 +733,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, | |||
728 | data->inode = inode; | 733 | data->inode = inode; |
729 | data->cred = msg.rpc_cred; | 734 | data->cred = msg.rpc_cred; |
730 | data->args.fh = NFS_FH(inode); | 735 | data->args.fh = NFS_FH(inode); |
731 | data->args.context = ctx; | 736 | data->args.context = get_nfs_open_context(ctx); |
732 | data->args.offset = pos; | 737 | data->args.offset = pos; |
733 | data->args.pgbase = pgbase; | 738 | data->args.pgbase = pgbase; |
734 | data->args.pages = data->pagevec; | 739 | data->args.pages = data->pagevec; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index a4c7cf2bff3a..15f787355d27 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -522,8 +522,12 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | |||
522 | 522 | ||
523 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) | 523 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) |
524 | { | 524 | { |
525 | struct inode *inode = ctx->path.dentry->d_inode; | 525 | struct inode *inode; |
526 | 526 | ||
527 | if (ctx == NULL) | ||
528 | return; | ||
529 | |||
530 | inode = ctx->path.dentry->d_inode; | ||
527 | if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock)) | 531 | if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock)) |
528 | return; | 532 | return; |
529 | list_del(&ctx->list); | 533 | list_del(&ctx->list); |
@@ -609,7 +613,7 @@ int nfs_open(struct inode *inode, struct file *filp) | |||
609 | struct nfs_open_context *ctx; | 613 | struct nfs_open_context *ctx; |
610 | struct rpc_cred *cred; | 614 | struct rpc_cred *cred; |
611 | 615 | ||
612 | cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); | 616 | cred = rpc_lookup_cred(); |
613 | if (IS_ERR(cred)) | 617 | if (IS_ERR(cred)) |
614 | return PTR_ERR(cred); | 618 | return PTR_ERR(cred); |
615 | ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred); | 619 | ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred); |
@@ -1217,6 +1221,36 @@ static void nfs_destroy_inodecache(void) | |||
1217 | kmem_cache_destroy(nfs_inode_cachep); | 1221 | kmem_cache_destroy(nfs_inode_cachep); |
1218 | } | 1222 | } |
1219 | 1223 | ||
1224 | struct workqueue_struct *nfsiod_workqueue; | ||
1225 | |||
1226 | /* | ||
1227 | * start up the nfsiod workqueue | ||
1228 | */ | ||
1229 | static int nfsiod_start(void) | ||
1230 | { | ||
1231 | struct workqueue_struct *wq; | ||
1232 | dprintk("RPC: creating workqueue nfsiod\n"); | ||
1233 | wq = create_singlethread_workqueue("nfsiod"); | ||
1234 | if (wq == NULL) | ||
1235 | return -ENOMEM; | ||
1236 | nfsiod_workqueue = wq; | ||
1237 | return 0; | ||
1238 | } | ||
1239 | |||
1240 | /* | ||
1241 | * Destroy the nfsiod workqueue | ||
1242 | */ | ||
1243 | static void nfsiod_stop(void) | ||
1244 | { | ||
1245 | struct workqueue_struct *wq; | ||
1246 | |||
1247 | wq = nfsiod_workqueue; | ||
1248 | if (wq == NULL) | ||
1249 | return; | ||
1250 | nfsiod_workqueue = NULL; | ||
1251 | destroy_workqueue(wq); | ||
1252 | } | ||
1253 | |||
1220 | /* | 1254 | /* |
1221 | * Initialize NFS | 1255 | * Initialize NFS |
1222 | */ | 1256 | */ |
@@ -1224,6 +1258,10 @@ static int __init init_nfs_fs(void) | |||
1224 | { | 1258 | { |
1225 | int err; | 1259 | int err; |
1226 | 1260 | ||
1261 | err = nfsiod_start(); | ||
1262 | if (err) | ||
1263 | goto out6; | ||
1264 | |||
1227 | err = nfs_fs_proc_init(); | 1265 | err = nfs_fs_proc_init(); |
1228 | if (err) | 1266 | if (err) |
1229 | goto out5; | 1267 | goto out5; |
@@ -1270,6 +1308,8 @@ out3: | |||
1270 | out4: | 1308 | out4: |
1271 | nfs_fs_proc_exit(); | 1309 | nfs_fs_proc_exit(); |
1272 | out5: | 1310 | out5: |
1311 | nfsiod_stop(); | ||
1312 | out6: | ||
1273 | return err; | 1313 | return err; |
1274 | } | 1314 | } |
1275 | 1315 | ||
@@ -1285,6 +1325,7 @@ static void __exit exit_nfs_fs(void) | |||
1285 | #endif | 1325 | #endif |
1286 | unregister_nfs_fs(); | 1326 | unregister_nfs_fs(); |
1287 | nfs_fs_proc_exit(); | 1327 | nfs_fs_proc_exit(); |
1328 | nfsiod_stop(); | ||
1288 | } | 1329 | } |
1289 | 1330 | ||
1290 | /* Not quite true; I just maintain it */ | 1331 | /* Not quite true; I just maintain it */ |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 931992763e68..4c1122a13844 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -146,6 +146,7 @@ extern struct rpc_procinfo nfs4_procedures[]; | |||
146 | extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); | 146 | extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); |
147 | 147 | ||
148 | /* inode.c */ | 148 | /* inode.c */ |
149 | extern struct workqueue_struct *nfsiod_workqueue; | ||
149 | extern struct inode *nfs_alloc_inode(struct super_block *sb); | 150 | extern struct inode *nfs_alloc_inode(struct super_block *sb); |
150 | extern void nfs_destroy_inode(struct inode *); | 151 | extern void nfs_destroy_inode(struct inode *); |
151 | extern int nfs_write_inode(struct inode *,int); | 152 | extern int nfs_write_inode(struct inode *,int); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7ce07862c2fb..f38d0573be18 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -51,6 +51,7 @@ | |||
51 | 51 | ||
52 | #include "nfs4_fs.h" | 52 | #include "nfs4_fs.h" |
53 | #include "delegation.h" | 53 | #include "delegation.h" |
54 | #include "internal.h" | ||
54 | #include "iostat.h" | 55 | #include "iostat.h" |
55 | 56 | ||
56 | #define NFSDBG_FACILITY NFSDBG_PROC | 57 | #define NFSDBG_FACILITY NFSDBG_PROC |
@@ -773,6 +774,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) | |||
773 | .rpc_message = &msg, | 774 | .rpc_message = &msg, |
774 | .callback_ops = &nfs4_open_confirm_ops, | 775 | .callback_ops = &nfs4_open_confirm_ops, |
775 | .callback_data = data, | 776 | .callback_data = data, |
777 | .workqueue = nfsiod_workqueue, | ||
776 | .flags = RPC_TASK_ASYNC, | 778 | .flags = RPC_TASK_ASYNC, |
777 | }; | 779 | }; |
778 | int status; | 780 | int status; |
@@ -910,6 +912,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
910 | .rpc_message = &msg, | 912 | .rpc_message = &msg, |
911 | .callback_ops = &nfs4_open_ops, | 913 | .callback_ops = &nfs4_open_ops, |
912 | .callback_data = data, | 914 | .callback_data = data, |
915 | .workqueue = nfsiod_workqueue, | ||
913 | .flags = RPC_TASK_ASYNC, | 916 | .flags = RPC_TASK_ASYNC, |
914 | }; | 917 | }; |
915 | int status; | 918 | int status; |
@@ -1315,6 +1318,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait) | |||
1315 | .rpc_client = server->client, | 1318 | .rpc_client = server->client, |
1316 | .rpc_message = &msg, | 1319 | .rpc_message = &msg, |
1317 | .callback_ops = &nfs4_close_ops, | 1320 | .callback_ops = &nfs4_close_ops, |
1321 | .workqueue = nfsiod_workqueue, | ||
1318 | .flags = RPC_TASK_ASYNC, | 1322 | .flags = RPC_TASK_ASYNC, |
1319 | }; | 1323 | }; |
1320 | int status = -ENOMEM; | 1324 | int status = -ENOMEM; |
@@ -1404,7 +1408,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
1404 | BUG_ON(nd->intent.open.flags & O_CREAT); | 1408 | BUG_ON(nd->intent.open.flags & O_CREAT); |
1405 | } | 1409 | } |
1406 | 1410 | ||
1407 | cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); | 1411 | cred = rpc_lookup_cred(); |
1408 | if (IS_ERR(cred)) | 1412 | if (IS_ERR(cred)) |
1409 | return (struct dentry *)cred; | 1413 | return (struct dentry *)cred; |
1410 | parent = dentry->d_parent; | 1414 | parent = dentry->d_parent; |
@@ -1439,7 +1443,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st | |||
1439 | struct rpc_cred *cred; | 1443 | struct rpc_cred *cred; |
1440 | struct nfs4_state *state; | 1444 | struct nfs4_state *state; |
1441 | 1445 | ||
1442 | cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); | 1446 | cred = rpc_lookup_cred(); |
1443 | if (IS_ERR(cred)) | 1447 | if (IS_ERR(cred)) |
1444 | return PTR_ERR(cred); | 1448 | return PTR_ERR(cred); |
1445 | state = nfs4_do_open(dir, &path, openflags, NULL, cred); | 1449 | state = nfs4_do_open(dir, &path, openflags, NULL, cred); |
@@ -1656,7 +1660,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, | |||
1656 | 1660 | ||
1657 | nfs_fattr_init(fattr); | 1661 | nfs_fattr_init(fattr); |
1658 | 1662 | ||
1659 | cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); | 1663 | cred = rpc_lookup_cred(); |
1660 | if (IS_ERR(cred)) | 1664 | if (IS_ERR(cred)) |
1661 | return PTR_ERR(cred); | 1665 | return PTR_ERR(cred); |
1662 | 1666 | ||
@@ -1892,7 +1896,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
1892 | struct rpc_cred *cred; | 1896 | struct rpc_cred *cred; |
1893 | int status = 0; | 1897 | int status = 0; |
1894 | 1898 | ||
1895 | cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); | 1899 | cred = rpc_lookup_cred(); |
1896 | if (IS_ERR(cred)) { | 1900 | if (IS_ERR(cred)) { |
1897 | status = PTR_ERR(cred); | 1901 | status = PTR_ERR(cred); |
1898 | goto out; | 1902 | goto out; |
@@ -2761,10 +2765,10 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) | |||
2761 | case -NFS4ERR_STALE_CLIENTID: | 2765 | case -NFS4ERR_STALE_CLIENTID: |
2762 | case -NFS4ERR_STALE_STATEID: | 2766 | case -NFS4ERR_STALE_STATEID: |
2763 | case -NFS4ERR_EXPIRED: | 2767 | case -NFS4ERR_EXPIRED: |
2764 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL); | 2768 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); |
2765 | nfs4_schedule_state_recovery(clp); | 2769 | nfs4_schedule_state_recovery(clp); |
2766 | if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) | 2770 | if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) |
2767 | rpc_wake_up_task(task); | 2771 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); |
2768 | task->tk_status = 0; | 2772 | task->tk_status = 0; |
2769 | return -EAGAIN; | 2773 | return -EAGAIN; |
2770 | case -NFS4ERR_DELAY: | 2774 | case -NFS4ERR_DELAY: |
@@ -3235,6 +3239,7 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, | |||
3235 | .rpc_client = NFS_CLIENT(lsp->ls_state->inode), | 3239 | .rpc_client = NFS_CLIENT(lsp->ls_state->inode), |
3236 | .rpc_message = &msg, | 3240 | .rpc_message = &msg, |
3237 | .callback_ops = &nfs4_locku_ops, | 3241 | .callback_ops = &nfs4_locku_ops, |
3242 | .workqueue = nfsiod_workqueue, | ||
3238 | .flags = RPC_TASK_ASYNC, | 3243 | .flags = RPC_TASK_ASYNC, |
3239 | }; | 3244 | }; |
3240 | 3245 | ||
@@ -3419,6 +3424,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f | |||
3419 | .rpc_client = NFS_CLIENT(state->inode), | 3424 | .rpc_client = NFS_CLIENT(state->inode), |
3420 | .rpc_message = &msg, | 3425 | .rpc_message = &msg, |
3421 | .callback_ops = &nfs4_lock_ops, | 3426 | .callback_ops = &nfs4_lock_ops, |
3427 | .workqueue = nfsiod_workqueue, | ||
3422 | .flags = RPC_TASK_ASYNC, | 3428 | .flags = RPC_TASK_ASYNC, |
3423 | }; | 3429 | }; |
3424 | int ret; | 3430 | int ret; |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index b962397004c1..7775435ea7a5 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -292,8 +292,10 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct | |||
292 | spin_unlock(&clp->cl_lock); | 292 | spin_unlock(&clp->cl_lock); |
293 | if (sp == new) | 293 | if (sp == new) |
294 | get_rpccred(cred); | 294 | get_rpccred(cred); |
295 | else | 295 | else { |
296 | rpc_destroy_wait_queue(&new->so_sequence.wait); | ||
296 | kfree(new); | 297 | kfree(new); |
298 | } | ||
297 | return sp; | 299 | return sp; |
298 | } | 300 | } |
299 | 301 | ||
@@ -310,6 +312,7 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp) | |||
310 | return; | 312 | return; |
311 | nfs4_remove_state_owner(clp, sp); | 313 | nfs4_remove_state_owner(clp, sp); |
312 | spin_unlock(&clp->cl_lock); | 314 | spin_unlock(&clp->cl_lock); |
315 | rpc_destroy_wait_queue(&sp->so_sequence.wait); | ||
313 | put_rpccred(cred); | 316 | put_rpccred(cred); |
314 | kfree(sp); | 317 | kfree(sp); |
315 | } | 318 | } |
@@ -529,6 +532,7 @@ static void nfs4_free_lock_state(struct nfs4_lock_state *lsp) | |||
529 | spin_lock(&clp->cl_lock); | 532 | spin_lock(&clp->cl_lock); |
530 | nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id); | 533 | nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id); |
531 | spin_unlock(&clp->cl_lock); | 534 | spin_unlock(&clp->cl_lock); |
535 | rpc_destroy_wait_queue(&lsp->ls_sequence.wait); | ||
532 | kfree(lsp); | 536 | kfree(lsp); |
533 | } | 537 | } |
534 | 538 | ||
@@ -731,7 +735,7 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task) | |||
731 | list_add_tail(&seqid->list, &sequence->list); | 735 | list_add_tail(&seqid->list, &sequence->list); |
732 | if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid) | 736 | if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid) |
733 | goto unlock; | 737 | goto unlock; |
734 | rpc_sleep_on(&sequence->wait, task, NULL, NULL); | 738 | rpc_sleep_on(&sequence->wait, task, NULL); |
735 | status = -EAGAIN; | 739 | status = -EAGAIN; |
736 | unlock: | 740 | unlock: |
737 | spin_unlock(&sequence->lock); | 741 | spin_unlock(&sequence->lock); |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index db1ed9c46ede..37421dd4805d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -110,7 +110,7 @@ static int nfs4_stat_to_errno(int); | |||
110 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) | 110 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) |
111 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) | 111 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) |
112 | #define decode_restorefh_maxsz (op_decode_hdr_maxsz) | 112 | #define decode_restorefh_maxsz (op_decode_hdr_maxsz) |
113 | #define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2) | 113 | #define encode_fsinfo_maxsz (encode_getattr_maxsz) |
114 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11) | 114 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11) |
115 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) | 115 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) |
116 | #define decode_renew_maxsz (op_decode_hdr_maxsz) | 116 | #define decode_renew_maxsz (op_decode_hdr_maxsz) |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 5a70be589bbe..ab2f7d233e01 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -58,22 +58,19 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) | |||
58 | return p; | 58 | return p; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void nfs_readdata_rcu_free(struct rcu_head *head) | 61 | static void nfs_readdata_free(struct nfs_read_data *p) |
62 | { | 62 | { |
63 | struct nfs_read_data *p = container_of(head, struct nfs_read_data, task.u.tk_rcu); | ||
64 | if (p && (p->pagevec != &p->page_array[0])) | 63 | if (p && (p->pagevec != &p->page_array[0])) |
65 | kfree(p->pagevec); | 64 | kfree(p->pagevec); |
66 | mempool_free(p, nfs_rdata_mempool); | 65 | mempool_free(p, nfs_rdata_mempool); |
67 | } | 66 | } |
68 | 67 | ||
69 | static void nfs_readdata_free(struct nfs_read_data *rdata) | ||
70 | { | ||
71 | call_rcu_bh(&rdata->task.u.tk_rcu, nfs_readdata_rcu_free); | ||
72 | } | ||
73 | |||
74 | void nfs_readdata_release(void *data) | 68 | void nfs_readdata_release(void *data) |
75 | { | 69 | { |
76 | nfs_readdata_free(data); | 70 | struct nfs_read_data *rdata = data; |
71 | |||
72 | put_nfs_open_context(rdata->args.context); | ||
73 | nfs_readdata_free(rdata); | ||
77 | } | 74 | } |
78 | 75 | ||
79 | static | 76 | static |
@@ -174,6 +171,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | |||
174 | .rpc_message = &msg, | 171 | .rpc_message = &msg, |
175 | .callback_ops = call_ops, | 172 | .callback_ops = call_ops, |
176 | .callback_data = data, | 173 | .callback_data = data, |
174 | .workqueue = nfsiod_workqueue, | ||
177 | .flags = RPC_TASK_ASYNC | swap_flags, | 175 | .flags = RPC_TASK_ASYNC | swap_flags, |
178 | }; | 176 | }; |
179 | 177 | ||
@@ -186,7 +184,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | |||
186 | data->args.pgbase = req->wb_pgbase + offset; | 184 | data->args.pgbase = req->wb_pgbase + offset; |
187 | data->args.pages = data->pagevec; | 185 | data->args.pages = data->pagevec; |
188 | data->args.count = count; | 186 | data->args.count = count; |
189 | data->args.context = req->wb_context; | 187 | data->args.context = get_nfs_open_context(req->wb_context); |
190 | 188 | ||
191 | data->res.fattr = &data->fattr; | 189 | data->res.fattr = &data->fattr; |
192 | data->res.count = count; | 190 | data->res.count = count; |
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 757415363422..3adf8b266461 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c | |||
@@ -234,7 +234,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry) | |||
234 | if (data == NULL) | 234 | if (data == NULL) |
235 | goto out; | 235 | goto out; |
236 | 236 | ||
237 | data->cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); | 237 | data->cred = rpc_lookup_cred(); |
238 | if (IS_ERR(data->cred)) { | 238 | if (IS_ERR(data->cred)) { |
239 | status = PTR_ERR(data->cred); | 239 | status = PTR_ERR(data->cred); |
240 | goto out_free; | 240 | goto out_free; |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index bed63416a55b..4cb88df12f83 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -59,19 +59,13 @@ struct nfs_write_data *nfs_commit_alloc(void) | |||
59 | return p; | 59 | return p; |
60 | } | 60 | } |
61 | 61 | ||
62 | static void nfs_commit_rcu_free(struct rcu_head *head) | 62 | void nfs_commit_free(struct nfs_write_data *p) |
63 | { | 63 | { |
64 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
65 | if (p && (p->pagevec != &p->page_array[0])) | 64 | if (p && (p->pagevec != &p->page_array[0])) |
66 | kfree(p->pagevec); | 65 | kfree(p->pagevec); |
67 | mempool_free(p, nfs_commit_mempool); | 66 | mempool_free(p, nfs_commit_mempool); |
68 | } | 67 | } |
69 | 68 | ||
70 | void nfs_commit_free(struct nfs_write_data *wdata) | ||
71 | { | ||
72 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); | ||
73 | } | ||
74 | |||
75 | struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) | 69 | struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) |
76 | { | 70 | { |
77 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); | 71 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); |
@@ -93,21 +87,18 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) | |||
93 | return p; | 87 | return p; |
94 | } | 88 | } |
95 | 89 | ||
96 | static void nfs_writedata_rcu_free(struct rcu_head *head) | 90 | static void nfs_writedata_free(struct nfs_write_data *p) |
97 | { | 91 | { |
98 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
99 | if (p && (p->pagevec != &p->page_array[0])) | 92 | if (p && (p->pagevec != &p->page_array[0])) |
100 | kfree(p->pagevec); | 93 | kfree(p->pagevec); |
101 | mempool_free(p, nfs_wdata_mempool); | 94 | mempool_free(p, nfs_wdata_mempool); |
102 | } | 95 | } |
103 | 96 | ||
104 | static void nfs_writedata_free(struct nfs_write_data *wdata) | 97 | void nfs_writedata_release(void *data) |
105 | { | 98 | { |
106 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free); | 99 | struct nfs_write_data *wdata = data; |
107 | } | ||
108 | 100 | ||
109 | void nfs_writedata_release(void *wdata) | 101 | put_nfs_open_context(wdata->args.context); |
110 | { | ||
111 | nfs_writedata_free(wdata); | 102 | nfs_writedata_free(wdata); |
112 | } | 103 | } |
113 | 104 | ||
@@ -366,15 +357,13 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
366 | /* | 357 | /* |
367 | * Insert a write request into an inode | 358 | * Insert a write request into an inode |
368 | */ | 359 | */ |
369 | static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | 360 | static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) |
370 | { | 361 | { |
371 | struct nfs_inode *nfsi = NFS_I(inode); | 362 | struct nfs_inode *nfsi = NFS_I(inode); |
372 | int error; | 363 | int error; |
373 | 364 | ||
374 | error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); | 365 | error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); |
375 | BUG_ON(error == -EEXIST); | 366 | BUG_ON(error); |
376 | if (error) | ||
377 | return error; | ||
378 | if (!nfsi->npages) { | 367 | if (!nfsi->npages) { |
379 | igrab(inode); | 368 | igrab(inode); |
380 | if (nfs_have_delegation(inode, FMODE_WRITE)) | 369 | if (nfs_have_delegation(inode, FMODE_WRITE)) |
@@ -384,8 +373,8 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
384 | set_page_private(req->wb_page, (unsigned long)req); | 373 | set_page_private(req->wb_page, (unsigned long)req); |
385 | nfsi->npages++; | 374 | nfsi->npages++; |
386 | kref_get(&req->wb_kref); | 375 | kref_get(&req->wb_kref); |
387 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); | 376 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, |
388 | return 0; | 377 | NFS_PAGE_TAG_LOCKED); |
389 | } | 378 | } |
390 | 379 | ||
391 | /* | 380 | /* |
@@ -597,6 +586,13 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
597 | /* Loop over all inode entries and see if we find | 586 | /* Loop over all inode entries and see if we find |
598 | * A request for the page we wish to update | 587 | * A request for the page we wish to update |
599 | */ | 588 | */ |
589 | if (new) { | ||
590 | if (radix_tree_preload(GFP_NOFS)) { | ||
591 | nfs_release_request(new); | ||
592 | return ERR_PTR(-ENOMEM); | ||
593 | } | ||
594 | } | ||
595 | |||
600 | spin_lock(&inode->i_lock); | 596 | spin_lock(&inode->i_lock); |
601 | req = nfs_page_find_request_locked(page); | 597 | req = nfs_page_find_request_locked(page); |
602 | if (req) { | 598 | if (req) { |
@@ -607,28 +603,27 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
607 | error = nfs_wait_on_request(req); | 603 | error = nfs_wait_on_request(req); |
608 | nfs_release_request(req); | 604 | nfs_release_request(req); |
609 | if (error < 0) { | 605 | if (error < 0) { |
610 | if (new) | 606 | if (new) { |
607 | radix_tree_preload_end(); | ||
611 | nfs_release_request(new); | 608 | nfs_release_request(new); |
609 | } | ||
612 | return ERR_PTR(error); | 610 | return ERR_PTR(error); |
613 | } | 611 | } |
614 | continue; | 612 | continue; |
615 | } | 613 | } |
616 | spin_unlock(&inode->i_lock); | 614 | spin_unlock(&inode->i_lock); |
617 | if (new) | 615 | if (new) { |
616 | radix_tree_preload_end(); | ||
618 | nfs_release_request(new); | 617 | nfs_release_request(new); |
618 | } | ||
619 | break; | 619 | break; |
620 | } | 620 | } |
621 | 621 | ||
622 | if (new) { | 622 | if (new) { |
623 | int error; | ||
624 | nfs_lock_request_dontget(new); | 623 | nfs_lock_request_dontget(new); |
625 | error = nfs_inode_add_request(inode, new); | 624 | nfs_inode_add_request(inode, new); |
626 | if (error) { | ||
627 | spin_unlock(&inode->i_lock); | ||
628 | nfs_unlock_request(new); | ||
629 | return ERR_PTR(error); | ||
630 | } | ||
631 | spin_unlock(&inode->i_lock); | 625 | spin_unlock(&inode->i_lock); |
626 | radix_tree_preload_end(); | ||
632 | req = new; | 627 | req = new; |
633 | goto zero_page; | 628 | goto zero_page; |
634 | } | 629 | } |
@@ -806,6 +801,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req, | |||
806 | .rpc_message = &msg, | 801 | .rpc_message = &msg, |
807 | .callback_ops = call_ops, | 802 | .callback_ops = call_ops, |
808 | .callback_data = data, | 803 | .callback_data = data, |
804 | .workqueue = nfsiod_workqueue, | ||
809 | .flags = flags, | 805 | .flags = flags, |
810 | .priority = priority, | 806 | .priority = priority, |
811 | }; | 807 | }; |
@@ -822,7 +818,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req, | |||
822 | data->args.pgbase = req->wb_pgbase + offset; | 818 | data->args.pgbase = req->wb_pgbase + offset; |
823 | data->args.pages = data->pagevec; | 819 | data->args.pages = data->pagevec; |
824 | data->args.count = count; | 820 | data->args.count = count; |
825 | data->args.context = req->wb_context; | 821 | data->args.context = get_nfs_open_context(req->wb_context); |
826 | data->args.stable = NFS_UNSTABLE; | 822 | data->args.stable = NFS_UNSTABLE; |
827 | if (how & FLUSH_STABLE) { | 823 | if (how & FLUSH_STABLE) { |
828 | data->args.stable = NFS_DATA_SYNC; | 824 | data->args.stable = NFS_DATA_SYNC; |
@@ -1159,8 +1155,11 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) | |||
1159 | 1155 | ||
1160 | 1156 | ||
1161 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1157 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1162 | void nfs_commit_release(void *wdata) | 1158 | void nfs_commit_release(void *data) |
1163 | { | 1159 | { |
1160 | struct nfs_write_data *wdata = data; | ||
1161 | |||
1162 | put_nfs_open_context(wdata->args.context); | ||
1164 | nfs_commit_free(wdata); | 1163 | nfs_commit_free(wdata); |
1165 | } | 1164 | } |
1166 | 1165 | ||
@@ -1187,6 +1186,7 @@ static void nfs_commit_rpcsetup(struct list_head *head, | |||
1187 | .rpc_message = &msg, | 1186 | .rpc_message = &msg, |
1188 | .callback_ops = &nfs_commit_ops, | 1187 | .callback_ops = &nfs_commit_ops, |
1189 | .callback_data = data, | 1188 | .callback_data = data, |
1189 | .workqueue = nfsiod_workqueue, | ||
1190 | .flags = flags, | 1190 | .flags = flags, |
1191 | .priority = priority, | 1191 | .priority = priority, |
1192 | }; | 1192 | }; |
@@ -1203,6 +1203,7 @@ static void nfs_commit_rpcsetup(struct list_head *head, | |||
1203 | /* Note: we always request a commit of the entire inode */ | 1203 | /* Note: we always request a commit of the entire inode */ |
1204 | data->args.offset = 0; | 1204 | data->args.offset = 0; |
1205 | data->args.count = 0; | 1205 | data->args.count = 0; |
1206 | data->args.context = get_nfs_open_context(first->wb_context); | ||
1206 | data->res.count = 0; | 1207 | data->res.count = 0; |
1207 | data->res.fattr = &data->fattr; | 1208 | data->res.fattr = &data->fattr; |
1208 | data->res.verf = &data->verf; | 1209 | data->res.verf = &data->verf; |