aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/callback.c3
-rw-r--r--fs/nfs/callback_xdr.c6
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/delegation.c2
-rw-r--r--fs/nfs/direct.c9
-rw-r--r--fs/nfs/idmap.c2
-rw-r--r--fs/nfs/inode.c43
-rw-r--r--fs/nfs/internal.h1
-rw-r--r--fs/nfs/namespace.c29
-rw-r--r--fs/nfs/nfs4proc.c18
-rw-r--r--fs/nfs/nfs4state.c10
-rw-r--r--fs/nfs/read.c16
-rw-r--r--fs/nfs/write.c31
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)
171static int nfs_callback_authenticate(struct svc_rqst *rqstp) 172static 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
522static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) 522static 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
1222struct workqueue_struct *nfsiod_workqueue;
1223
1224/*
1225 * start up the nfsiod workqueue
1226 */
1227static 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 */
1241static 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:
1268out4: 1306out4:
1269 nfs_fs_proc_exit(); 1307 nfs_fs_proc_exit();
1270out5: 1308out5:
1309 nfsiod_stop();
1310out6:
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[];
143extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); 143extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask);
144 144
145/* inode.c */ 145/* inode.c */
146extern struct workqueue_struct *nfsiod_workqueue;
146extern struct inode *nfs_alloc_inode(struct super_block *sb); 147extern struct inode *nfs_alloc_inode(struct super_block *sb);
147extern void nfs_destroy_inode(struct inode *); 148extern void nfs_destroy_inode(struct inode *);
148extern int nfs_write_inode(struct inode *,int); 149extern 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);
143out: 145out:
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);
148out_err: 150out_err:
149 path_release(nd); 151 path_put(&nd->path);
150 goto out; 152 goto out;
151out_follow: 153out_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:
1384struct dentry * 1388struct dentry *
1385nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 1389nfs4_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
1433nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd) 1437nfs4_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;
736unlock: 740unlock:
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
61static void nfs_readdata_rcu_free(struct rcu_head *head) 61static 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
69static 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
74void nfs_readdata_release(void *data) 68void 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
79static 76static
@@ -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
61static void nfs_commit_rcu_free(struct rcu_head *head) 61void 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
69void nfs_commit_free(struct nfs_write_data *wdata)
70{
71 call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free);
72}
73
74struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) 68struct 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
95static void nfs_writedata_rcu_free(struct rcu_head *head) 89static 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
103static void nfs_writedata_free(struct nfs_write_data *wdata) 96void 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
108void 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)
1160void nfs_commit_release(void *wdata) 1152void 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;