diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/callback.c | 3 | ||||
-rw-r--r-- | fs/nfs/callback_xdr.c | 6 | ||||
-rw-r--r-- | fs/nfs/client.c | 2 | ||||
-rw-r--r-- | fs/nfs/delegation.c | 2 | ||||
-rw-r--r-- | fs/nfs/direct.c | 9 | ||||
-rw-r--r-- | fs/nfs/idmap.c | 2 | ||||
-rw-r--r-- | fs/nfs/inode.c | 43 | ||||
-rw-r--r-- | fs/nfs/internal.h | 1 | ||||
-rw-r--r-- | fs/nfs/namespace.c | 29 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 18 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 10 | ||||
-rw-r--r-- | fs/nfs/read.c | 16 | ||||
-rw-r--r-- | fs/nfs/write.c | 31 |
13 files changed, 115 insertions, 57 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index ecc06c619494..66648dd92d97 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -93,6 +93,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp) | |||
93 | svc_process(rqstp); | 93 | svc_process(rqstp); |
94 | } | 94 | } |
95 | 95 | ||
96 | flush_signals(current); | ||
96 | svc_exit_thread(rqstp); | 97 | svc_exit_thread(rqstp); |
97 | nfs_callback_info.pid = 0; | 98 | nfs_callback_info.pid = 0; |
98 | complete(&nfs_callback_info.stopped); | 99 | complete(&nfs_callback_info.stopped); |
@@ -171,7 +172,7 @@ void nfs_callback_down(void) | |||
171 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) | 172 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) |
172 | { | 173 | { |
173 | struct nfs_client *clp; | 174 | struct nfs_client *clp; |
174 | char buf[RPC_MAX_ADDRBUFLEN]; | 175 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
175 | 176 | ||
176 | /* Don't talk to strangers */ | 177 | /* Don't talk to strangers */ |
177 | clp = nfs_find_client(svc_addr(rqstp), 4); | 178 | clp = nfs_find_client(svc_addr(rqstp), 4); |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index c63eb720b68b..13619d24f023 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
@@ -254,7 +254,7 @@ static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, | |||
254 | if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) | 254 | if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) |
255 | return 0; | 255 | return 0; |
256 | p = xdr_reserve_space(xdr, 8); | 256 | p = xdr_reserve_space(xdr, 8); |
257 | if (unlikely(p == 0)) | 257 | if (unlikely(!p)) |
258 | return htonl(NFS4ERR_RESOURCE); | 258 | return htonl(NFS4ERR_RESOURCE); |
259 | p = xdr_encode_hyper(p, change); | 259 | p = xdr_encode_hyper(p, change); |
260 | return 0; | 260 | return 0; |
@@ -267,7 +267,7 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u | |||
267 | if (!(bitmap[0] & FATTR4_WORD0_SIZE)) | 267 | if (!(bitmap[0] & FATTR4_WORD0_SIZE)) |
268 | return 0; | 268 | return 0; |
269 | p = xdr_reserve_space(xdr, 8); | 269 | p = xdr_reserve_space(xdr, 8); |
270 | if (unlikely(p == 0)) | 270 | if (unlikely(!p)) |
271 | return htonl(NFS4ERR_RESOURCE); | 271 | return htonl(NFS4ERR_RESOURCE); |
272 | p = xdr_encode_hyper(p, size); | 272 | p = xdr_encode_hyper(p, size); |
273 | return 0; | 273 | return 0; |
@@ -278,7 +278,7 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti | |||
278 | __be32 *p; | 278 | __be32 *p; |
279 | 279 | ||
280 | p = xdr_reserve_space(xdr, 12); | 280 | p = xdr_reserve_space(xdr, 12); |
281 | if (unlikely(p == 0)) | 281 | if (unlikely(!p)) |
282 | return htonl(NFS4ERR_RESOURCE); | 282 | return htonl(NFS4ERR_RESOURCE); |
283 | p = xdr_encode_hyper(p, time->tv_sec); | 283 | p = xdr_encode_hyper(p, time->tv_sec); |
284 | *p = htonl(time->tv_nsec); | 284 | *p = htonl(time->tv_nsec); |
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/delegation.c b/fs/nfs/delegation.c index b9eadd18ba70..00a5e4405e16 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -49,7 +49,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ | |||
49 | struct file_lock *fl; | 49 | struct file_lock *fl; |
50 | int status; | 50 | int status; |
51 | 51 | ||
52 | for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { | 52 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
53 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 53 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
54 | continue; | 54 | continue; |
55 | if (nfs_file_open_context(fl->fl_file) != ctx) | 55 | if (nfs_file_open_context(fl->fl_file) != ctx) |
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/idmap.c b/fs/nfs/idmap.c index 8ae5dba2d4e5..86147b0ab2cf 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -309,7 +309,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, | |||
309 | mutex_lock(&idmap->idmap_im_lock); | 309 | mutex_lock(&idmap->idmap_im_lock); |
310 | 310 | ||
311 | he = idmap_lookup_id(h, id); | 311 | he = idmap_lookup_id(h, id); |
312 | if (he != 0) { | 312 | if (he) { |
313 | memcpy(name, he->ih_name, he->ih_namelen); | 313 | memcpy(name, he->ih_name, he->ih_namelen); |
314 | ret = he->ih_namelen; | 314 | ret = he->ih_namelen; |
315 | goto out; | 315 | goto out; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 966a8850aa30..36cb99985d22 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -521,8 +521,12 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | |||
521 | 521 | ||
522 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) | 522 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) |
523 | { | 523 | { |
524 | struct inode *inode = ctx->path.dentry->d_inode; | 524 | struct inode *inode; |
525 | 525 | ||
526 | if (ctx == NULL) | ||
527 | return; | ||
528 | |||
529 | inode = ctx->path.dentry->d_inode; | ||
526 | if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock)) | 530 | if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock)) |
527 | return; | 531 | return; |
528 | list_del(&ctx->list); | 532 | list_del(&ctx->list); |
@@ -1215,6 +1219,36 @@ static void nfs_destroy_inodecache(void) | |||
1215 | kmem_cache_destroy(nfs_inode_cachep); | 1219 | kmem_cache_destroy(nfs_inode_cachep); |
1216 | } | 1220 | } |
1217 | 1221 | ||
1222 | struct workqueue_struct *nfsiod_workqueue; | ||
1223 | |||
1224 | /* | ||
1225 | * start up the nfsiod workqueue | ||
1226 | */ | ||
1227 | static int nfsiod_start(void) | ||
1228 | { | ||
1229 | struct workqueue_struct *wq; | ||
1230 | dprintk("RPC: creating workqueue nfsiod\n"); | ||
1231 | wq = create_singlethread_workqueue("nfsiod"); | ||
1232 | if (wq == NULL) | ||
1233 | return -ENOMEM; | ||
1234 | nfsiod_workqueue = wq; | ||
1235 | return 0; | ||
1236 | } | ||
1237 | |||
1238 | /* | ||
1239 | * Destroy the nfsiod workqueue | ||
1240 | */ | ||
1241 | static void nfsiod_stop(void) | ||
1242 | { | ||
1243 | struct workqueue_struct *wq; | ||
1244 | |||
1245 | wq = nfsiod_workqueue; | ||
1246 | if (wq == NULL) | ||
1247 | return; | ||
1248 | nfsiod_workqueue = NULL; | ||
1249 | destroy_workqueue(wq); | ||
1250 | } | ||
1251 | |||
1218 | /* | 1252 | /* |
1219 | * Initialize NFS | 1253 | * Initialize NFS |
1220 | */ | 1254 | */ |
@@ -1222,6 +1256,10 @@ static int __init init_nfs_fs(void) | |||
1222 | { | 1256 | { |
1223 | int err; | 1257 | int err; |
1224 | 1258 | ||
1259 | err = nfsiod_start(); | ||
1260 | if (err) | ||
1261 | goto out6; | ||
1262 | |||
1225 | err = nfs_fs_proc_init(); | 1263 | err = nfs_fs_proc_init(); |
1226 | if (err) | 1264 | if (err) |
1227 | goto out5; | 1265 | goto out5; |
@@ -1268,6 +1306,8 @@ out3: | |||
1268 | out4: | 1306 | out4: |
1269 | nfs_fs_proc_exit(); | 1307 | nfs_fs_proc_exit(); |
1270 | out5: | 1308 | out5: |
1309 | nfsiod_stop(); | ||
1310 | out6: | ||
1271 | return err; | 1311 | return err; |
1272 | } | 1312 | } |
1273 | 1313 | ||
@@ -1283,6 +1323,7 @@ static void __exit exit_nfs_fs(void) | |||
1283 | #endif | 1323 | #endif |
1284 | unregister_nfs_fs(); | 1324 | unregister_nfs_fs(); |
1285 | nfs_fs_proc_exit(); | 1325 | nfs_fs_proc_exit(); |
1326 | nfsiod_stop(); | ||
1286 | } | 1327 | } |
1287 | 1328 | ||
1288 | /* Not quite true; I just maintain it */ | 1329 | /* Not quite true; I just maintain it */ |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 0f5619611b8d..985dc2931031 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -143,6 +143,7 @@ extern struct rpc_procinfo nfs4_procedures[]; | |||
143 | extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); | 143 | extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); |
144 | 144 | ||
145 | /* inode.c */ | 145 | /* inode.c */ |
146 | extern struct workqueue_struct *nfsiod_workqueue; | ||
146 | extern struct inode *nfs_alloc_inode(struct super_block *sb); | 147 | extern struct inode *nfs_alloc_inode(struct super_block *sb); |
147 | extern void nfs_destroy_inode(struct inode *); | 148 | extern void nfs_destroy_inode(struct inode *); |
148 | extern int nfs_write_inode(struct inode *,int); | 149 | extern int nfs_write_inode(struct inode *,int); |
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index be4ce1c3a3d8..607f6eb9cdb5 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
@@ -107,38 +107,40 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) | |||
107 | 107 | ||
108 | BUG_ON(IS_ROOT(dentry)); | 108 | BUG_ON(IS_ROOT(dentry)); |
109 | dprintk("%s: enter\n", __FUNCTION__); | 109 | dprintk("%s: enter\n", __FUNCTION__); |
110 | dput(nd->dentry); | 110 | dput(nd->path.dentry); |
111 | nd->dentry = dget(dentry); | 111 | nd->path.dentry = dget(dentry); |
112 | 112 | ||
113 | /* Look it up again */ | 113 | /* Look it up again */ |
114 | parent = dget_parent(nd->dentry); | 114 | parent = dget_parent(nd->path.dentry); |
115 | err = server->nfs_client->rpc_ops->lookup(parent->d_inode, | 115 | err = server->nfs_client->rpc_ops->lookup(parent->d_inode, |
116 | &nd->dentry->d_name, | 116 | &nd->path.dentry->d_name, |
117 | &fh, &fattr); | 117 | &fh, &fattr); |
118 | dput(parent); | 118 | dput(parent); |
119 | if (err != 0) | 119 | if (err != 0) |
120 | goto out_err; | 120 | goto out_err; |
121 | 121 | ||
122 | if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) | 122 | if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) |
123 | mnt = nfs_do_refmount(nd->mnt, nd->dentry); | 123 | mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry); |
124 | else | 124 | else |
125 | mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr); | 125 | mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh, |
126 | &fattr); | ||
126 | err = PTR_ERR(mnt); | 127 | err = PTR_ERR(mnt); |
127 | if (IS_ERR(mnt)) | 128 | if (IS_ERR(mnt)) |
128 | goto out_err; | 129 | goto out_err; |
129 | 130 | ||
130 | mntget(mnt); | 131 | mntget(mnt); |
131 | err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list); | 132 | err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE, |
133 | &nfs_automount_list); | ||
132 | if (err < 0) { | 134 | if (err < 0) { |
133 | mntput(mnt); | 135 | mntput(mnt); |
134 | if (err == -EBUSY) | 136 | if (err == -EBUSY) |
135 | goto out_follow; | 137 | goto out_follow; |
136 | goto out_err; | 138 | goto out_err; |
137 | } | 139 | } |
138 | mntput(nd->mnt); | 140 | mntput(nd->path.mnt); |
139 | dput(nd->dentry); | 141 | dput(nd->path.dentry); |
140 | nd->mnt = mnt; | 142 | nd->path.mnt = mnt; |
141 | nd->dentry = dget(mnt->mnt_root); | 143 | nd->path.dentry = dget(mnt->mnt_root); |
142 | schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); | 144 | schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); |
143 | out: | 145 | out: |
144 | dprintk("%s: done, returned %d\n", __FUNCTION__, err); | 146 | dprintk("%s: done, returned %d\n", __FUNCTION__, err); |
@@ -146,10 +148,11 @@ out: | |||
146 | dprintk("<-- nfs_follow_mountpoint() = %d\n", err); | 148 | dprintk("<-- nfs_follow_mountpoint() = %d\n", err); |
147 | return ERR_PTR(err); | 149 | return ERR_PTR(err); |
148 | out_err: | 150 | out_err: |
149 | path_release(nd); | 151 | path_put(&nd->path); |
150 | goto out; | 152 | goto out; |
151 | out_follow: | 153 | out_follow: |
152 | while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) | 154 | while (d_mountpoint(nd->path.dentry) && |
155 | follow_down(&nd->path.mnt, &nd->path.dentry)) | ||
153 | ; | 156 | ; |
154 | err = 0; | 157 | err = 0; |
155 | goto out; | 158 | goto out; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 027e1095256e..bbb0d58ee6ac 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; |
@@ -1384,11 +1388,11 @@ out_close: | |||
1384 | struct dentry * | 1388 | struct dentry * |
1385 | nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 1389 | nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
1386 | { | 1390 | { |
1387 | struct dentry *parent; | ||
1388 | struct path path = { | 1391 | struct path path = { |
1389 | .mnt = nd->mnt, | 1392 | .mnt = nd->path.mnt, |
1390 | .dentry = dentry, | 1393 | .dentry = dentry, |
1391 | }; | 1394 | }; |
1395 | struct dentry *parent; | ||
1392 | struct iattr attr; | 1396 | struct iattr attr; |
1393 | struct rpc_cred *cred; | 1397 | struct rpc_cred *cred; |
1394 | struct nfs4_state *state; | 1398 | struct nfs4_state *state; |
@@ -1433,7 +1437,7 @@ int | |||
1433 | nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd) | 1437 | nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd) |
1434 | { | 1438 | { |
1435 | struct path path = { | 1439 | struct path path = { |
1436 | .mnt = nd->mnt, | 1440 | .mnt = nd->path.mnt, |
1437 | .dentry = dentry, | 1441 | .dentry = dentry, |
1438 | }; | 1442 | }; |
1439 | struct rpc_cred *cred; | 1443 | struct rpc_cred *cred; |
@@ -1885,7 +1889,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
1885 | int flags, struct nameidata *nd) | 1889 | int flags, struct nameidata *nd) |
1886 | { | 1890 | { |
1887 | struct path path = { | 1891 | struct path path = { |
1888 | .mnt = nd->mnt, | 1892 | .mnt = nd->path.mnt, |
1889 | .dentry = dentry, | 1893 | .dentry = dentry, |
1890 | }; | 1894 | }; |
1891 | struct nfs4_state *state; | 1895 | struct nfs4_state *state; |
@@ -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 6233eb5e98c1..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); |
@@ -785,7 +789,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s | |||
785 | struct file_lock *fl; | 789 | struct file_lock *fl; |
786 | int status = 0; | 790 | int status = 0; |
787 | 791 | ||
788 | for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { | 792 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
789 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 793 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
790 | continue; | 794 | continue; |
791 | if (nfs_file_open_context(fl->fl_file)->state != state) | 795 | if (nfs_file_open_context(fl->fl_file)->state != state) |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 3d7d9631e125..be9e8270f4d7 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/write.c b/fs/nfs/write.c index 7be42e6eb63a..1667e3984418 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -58,19 +58,13 @@ struct nfs_write_data *nfs_commit_alloc(void) | |||
58 | return p; | 58 | return p; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void nfs_commit_rcu_free(struct rcu_head *head) | 61 | void nfs_commit_free(struct nfs_write_data *p) |
62 | { | 62 | { |
63 | struct nfs_write_data *p = container_of(head, struct nfs_write_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_commit_mempool); | 65 | mempool_free(p, nfs_commit_mempool); |
67 | } | 66 | } |
68 | 67 | ||
69 | void nfs_commit_free(struct nfs_write_data *wdata) | ||
70 | { | ||
71 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); | ||
72 | } | ||
73 | |||
74 | struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) | 68 | struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) |
75 | { | 69 | { |
76 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); | 70 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); |
@@ -92,21 +86,18 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) | |||
92 | return p; | 86 | return p; |
93 | } | 87 | } |
94 | 88 | ||
95 | static void nfs_writedata_rcu_free(struct rcu_head *head) | 89 | static void nfs_writedata_free(struct nfs_write_data *p) |
96 | { | 90 | { |
97 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
98 | if (p && (p->pagevec != &p->page_array[0])) | 91 | if (p && (p->pagevec != &p->page_array[0])) |
99 | kfree(p->pagevec); | 92 | kfree(p->pagevec); |
100 | mempool_free(p, nfs_wdata_mempool); | 93 | mempool_free(p, nfs_wdata_mempool); |
101 | } | 94 | } |
102 | 95 | ||
103 | static void nfs_writedata_free(struct nfs_write_data *wdata) | 96 | void nfs_writedata_release(void *data) |
104 | { | 97 | { |
105 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free); | 98 | struct nfs_write_data *wdata = data; |
106 | } | ||
107 | 99 | ||
108 | void nfs_writedata_release(void *wdata) | 100 | put_nfs_open_context(wdata->args.context); |
109 | { | ||
110 | nfs_writedata_free(wdata); | 101 | nfs_writedata_free(wdata); |
111 | } | 102 | } |
112 | 103 | ||
@@ -738,7 +729,7 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
738 | */ | 729 | */ |
739 | if (nfs_write_pageuptodate(page, inode) && | 730 | if (nfs_write_pageuptodate(page, inode) && |
740 | inode->i_flock == NULL && | 731 | inode->i_flock == NULL && |
741 | !(file->f_mode & O_SYNC)) { | 732 | !(file->f_flags & O_SYNC)) { |
742 | count = max(count + offset, nfs_page_length(page)); | 733 | count = max(count + offset, nfs_page_length(page)); |
743 | offset = 0; | 734 | offset = 0; |
744 | } | 735 | } |
@@ -804,6 +795,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req, | |||
804 | .rpc_message = &msg, | 795 | .rpc_message = &msg, |
805 | .callback_ops = call_ops, | 796 | .callback_ops = call_ops, |
806 | .callback_data = data, | 797 | .callback_data = data, |
798 | .workqueue = nfsiod_workqueue, | ||
807 | .flags = flags, | 799 | .flags = flags, |
808 | .priority = priority, | 800 | .priority = priority, |
809 | }; | 801 | }; |
@@ -820,7 +812,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req, | |||
820 | data->args.pgbase = req->wb_pgbase + offset; | 812 | data->args.pgbase = req->wb_pgbase + offset; |
821 | data->args.pages = data->pagevec; | 813 | data->args.pages = data->pagevec; |
822 | data->args.count = count; | 814 | data->args.count = count; |
823 | data->args.context = req->wb_context; | 815 | data->args.context = get_nfs_open_context(req->wb_context); |
824 | data->args.stable = NFS_UNSTABLE; | 816 | data->args.stable = NFS_UNSTABLE; |
825 | if (how & FLUSH_STABLE) { | 817 | if (how & FLUSH_STABLE) { |
826 | data->args.stable = NFS_DATA_SYNC; | 818 | data->args.stable = NFS_DATA_SYNC; |
@@ -1157,8 +1149,11 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) | |||
1157 | 1149 | ||
1158 | 1150 | ||
1159 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1151 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1160 | void nfs_commit_release(void *wdata) | 1152 | void nfs_commit_release(void *data) |
1161 | { | 1153 | { |
1154 | struct nfs_write_data *wdata = data; | ||
1155 | |||
1156 | put_nfs_open_context(wdata->args.context); | ||
1162 | nfs_commit_free(wdata); | 1157 | nfs_commit_free(wdata); |
1163 | } | 1158 | } |
1164 | 1159 | ||
@@ -1185,6 +1180,7 @@ static void nfs_commit_rpcsetup(struct list_head *head, | |||
1185 | .rpc_message = &msg, | 1180 | .rpc_message = &msg, |
1186 | .callback_ops = &nfs_commit_ops, | 1181 | .callback_ops = &nfs_commit_ops, |
1187 | .callback_data = data, | 1182 | .callback_data = data, |
1183 | .workqueue = nfsiod_workqueue, | ||
1188 | .flags = flags, | 1184 | .flags = flags, |
1189 | .priority = priority, | 1185 | .priority = priority, |
1190 | }; | 1186 | }; |
@@ -1201,6 +1197,7 @@ static void nfs_commit_rpcsetup(struct list_head *head, | |||
1201 | /* Note: we always request a commit of the entire inode */ | 1197 | /* Note: we always request a commit of the entire inode */ |
1202 | data->args.offset = 0; | 1198 | data->args.offset = 0; |
1203 | data->args.count = 0; | 1199 | data->args.count = 0; |
1200 | data->args.context = get_nfs_open_context(first->wb_context); | ||
1204 | data->res.count = 0; | 1201 | data->res.count = 0; |
1205 | data->res.fattr = &data->fattr; | 1202 | data->res.fattr = &data->fattr; |
1206 | data->res.verf = &data->verf; | 1203 | data->res.verf = &data->verf; |