aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-11 23:11:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-11 23:11:28 -0500
commit31c1febd7a45229edb3e5d86f354e3c1df543cbb (patch)
tree9c96b4bb18d47c606d6d85d774d2523f3e47aec0
parentb4a237598aa740562f842db76d97465c44fb74c1 (diff)
parent0442f14b15f8e7a8b3778a9f8cf640ef89b2df26 (diff)
Merge tag 'nfsd-4.4' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: "Apologies for coming a little late in the merge window. Fortunately this is another fairly quiet one: Mainly smaller bugfixes and cleanup. We're still finding some bugs from the breakup of the big NFSv4 state lock in 3.17 -- thanks especially to Andrew Elble and Jeff Layton for tracking down some of the remaining races" * tag 'nfsd-4.4' of git://linux-nfs.org/~bfields/linux: svcrpc: document lack of some memory barriers nfsd: fix race with open / open upgrade stateids nfsd: eliminate sending duplicate and repeated delegations nfsd: remove recurring workqueue job to clean DRC SUNRPC: drop stale comment in svc_setup_socket() nfsd: ensure that seqid morphing operations are atomic wrt to copies nfsd: serialize layout stateid morphing operations nfsd: improve client_has_state to check for unused openowners nfsd: fix clid_inuse on mount with security change sunrpc/cache: make cache flushing more reliable. nfsd: move include of state.h from trace.c to trace.h sunrpc: avoid warning in gss_key_timeout lockd: get rid of reference-counted NSM RPC clients SUNRPC: Use MSG_SENDPAGE_NOTLAST when calling sendpage() lockd: create NSM handles per net namespace nfsd: switch unsigned char flags in svc_fh to bools nfsd: move svc_fh->fh_maxsize to just after fh_handle nfsd: drop null test before destroy functions nfsd: serialize state seqid morphing operations
-rw-r--r--fs/lockd/host.c8
-rw-r--r--fs/lockd/mon.c125
-rw-r--r--fs/lockd/netns.h4
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/lockd/svc4proc.c2
-rw-r--r--fs/lockd/svcproc.c2
-rw-r--r--fs/nfsd/nfs3xdr.c4
-rw-r--r--fs/nfsd/nfs4layouts.c34
-rw-r--r--fs/nfsd/nfs4proc.c4
-rw-r--r--fs/nfsd/nfs4state.c265
-rw-r--r--fs/nfsd/nfscache.c32
-rw-r--r--fs/nfsd/nfsfh.c5
-rw-r--r--fs/nfsd/nfsfh.h20
-rw-r--r--fs/nfsd/state.h43
-rw-r--r--fs/nfsd/trace.c2
-rw-r--r--fs/nfsd/trace.h2
-rw-r--r--fs/nfsd/vfs.c4
-rw-r--r--fs/nfsd/vfs.h4
-rw-r--r--fs/nfsd/xdr4.h2
-rw-r--r--include/linux/lockd/lockd.h10
-rw-r--r--include/linux/sunrpc/cache.h16
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c13
-rw-r--r--net/sunrpc/cache.c53
-rw-r--r--net/sunrpc/svcsock.c40
24 files changed, 412 insertions, 284 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 969d589c848d..d716c9993a26 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -116,7 +116,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
116 atomic_inc(&nsm->sm_count); 116 atomic_inc(&nsm->sm_count);
117 else { 117 else {
118 host = NULL; 118 host = NULL;
119 nsm = nsm_get_handle(ni->sap, ni->salen, 119 nsm = nsm_get_handle(ni->net, ni->sap, ni->salen,
120 ni->hostname, ni->hostname_len); 120 ni->hostname, ni->hostname_len);
121 if (unlikely(nsm == NULL)) { 121 if (unlikely(nsm == NULL)) {
122 dprintk("lockd: %s failed; no nsm handle\n", 122 dprintk("lockd: %s failed; no nsm handle\n",
@@ -161,6 +161,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
161 host->h_nsmhandle = nsm; 161 host->h_nsmhandle = nsm;
162 host->h_addrbuf = nsm->sm_addrbuf; 162 host->h_addrbuf = nsm->sm_addrbuf;
163 host->net = ni->net; 163 host->net = ni->net;
164 strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename));
164 165
165out: 166out:
166 return host; 167 return host;
@@ -534,17 +535,18 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
534 535
535/** 536/**
536 * nlm_host_rebooted - Release all resources held by rebooted host 537 * nlm_host_rebooted - Release all resources held by rebooted host
538 * @net: network namespace
537 * @info: pointer to decoded results of NLM_SM_NOTIFY call 539 * @info: pointer to decoded results of NLM_SM_NOTIFY call
538 * 540 *
539 * We were notified that the specified host has rebooted. Release 541 * We were notified that the specified host has rebooted. Release
540 * all resources held by that peer. 542 * all resources held by that peer.
541 */ 543 */
542void nlm_host_rebooted(const struct nlm_reboot *info) 544void nlm_host_rebooted(const struct net *net, const struct nlm_reboot *info)
543{ 545{
544 struct nsm_handle *nsm; 546 struct nsm_handle *nsm;
545 struct nlm_host *host; 547 struct nlm_host *host;
546 548
547 nsm = nsm_reboot_lookup(info); 549 nsm = nsm_reboot_lookup(net, info);
548 if (unlikely(nsm == NULL)) 550 if (unlikely(nsm == NULL))
549 return; 551 return;
550 552
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 47a32b6d9b90..19166d4a8d31 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -42,7 +42,7 @@ struct nsm_args {
42 u32 proc; 42 u32 proc;
43 43
44 char *mon_name; 44 char *mon_name;
45 char *nodename; 45 const char *nodename;
46}; 46};
47 47
48struct nsm_res { 48struct nsm_res {
@@ -51,7 +51,6 @@ struct nsm_res {
51}; 51};
52 52
53static const struct rpc_program nsm_program; 53static const struct rpc_program nsm_program;
54static LIST_HEAD(nsm_handles);
55static DEFINE_SPINLOCK(nsm_lock); 54static DEFINE_SPINLOCK(nsm_lock);
56 55
57/* 56/*
@@ -87,69 +86,18 @@ static struct rpc_clnt *nsm_create(struct net *net, const char *nodename)
87 return rpc_create(&args); 86 return rpc_create(&args);
88} 87}
89 88
90static struct rpc_clnt *nsm_client_set(struct lockd_net *ln,
91 struct rpc_clnt *clnt)
92{
93 spin_lock(&ln->nsm_clnt_lock);
94 if (ln->nsm_users == 0) {
95 if (clnt == NULL)
96 goto out;
97 ln->nsm_clnt = clnt;
98 }
99 clnt = ln->nsm_clnt;
100 ln->nsm_users++;
101out:
102 spin_unlock(&ln->nsm_clnt_lock);
103 return clnt;
104}
105
106static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename)
107{
108 struct rpc_clnt *clnt, *new;
109 struct lockd_net *ln = net_generic(net, lockd_net_id);
110
111 clnt = nsm_client_set(ln, NULL);
112 if (clnt != NULL)
113 goto out;
114
115 clnt = new = nsm_create(net, nodename);
116 if (IS_ERR(clnt))
117 goto out;
118
119 clnt = nsm_client_set(ln, new);
120 if (clnt != new)
121 rpc_shutdown_client(new);
122out:
123 return clnt;
124}
125
126static void nsm_client_put(struct net *net)
127{
128 struct lockd_net *ln = net_generic(net, lockd_net_id);
129 struct rpc_clnt *clnt = NULL;
130
131 spin_lock(&ln->nsm_clnt_lock);
132 ln->nsm_users--;
133 if (ln->nsm_users == 0) {
134 clnt = ln->nsm_clnt;
135 ln->nsm_clnt = NULL;
136 }
137 spin_unlock(&ln->nsm_clnt_lock);
138 if (clnt != NULL)
139 rpc_shutdown_client(clnt);
140}
141
142static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, 89static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
143 struct rpc_clnt *clnt) 90 const struct nlm_host *host)
144{ 91{
145 int status; 92 int status;
93 struct rpc_clnt *clnt;
146 struct nsm_args args = { 94 struct nsm_args args = {
147 .priv = &nsm->sm_priv, 95 .priv = &nsm->sm_priv,
148 .prog = NLM_PROGRAM, 96 .prog = NLM_PROGRAM,
149 .vers = 3, 97 .vers = 3,
150 .proc = NLMPROC_NSM_NOTIFY, 98 .proc = NLMPROC_NSM_NOTIFY,
151 .mon_name = nsm->sm_mon_name, 99 .mon_name = nsm->sm_mon_name,
152 .nodename = clnt->cl_nodename, 100 .nodename = host->nodename,
153 }; 101 };
154 struct rpc_message msg = { 102 struct rpc_message msg = {
155 .rpc_argp = &args, 103 .rpc_argp = &args,
@@ -158,6 +106,13 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
158 106
159 memset(res, 0, sizeof(*res)); 107 memset(res, 0, sizeof(*res));
160 108
109 clnt = nsm_create(host->net, host->nodename);
110 if (IS_ERR(clnt)) {
111 dprintk("lockd: failed to create NSM upcall transport, "
112 "status=%ld, net=%p\n", PTR_ERR(clnt), host->net);
113 return PTR_ERR(clnt);
114 }
115
161 msg.rpc_proc = &clnt->cl_procinfo[proc]; 116 msg.rpc_proc = &clnt->cl_procinfo[proc];
162 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN); 117 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
163 if (status == -ECONNREFUSED) { 118 if (status == -ECONNREFUSED) {
@@ -171,6 +126,8 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
171 status); 126 status);
172 else 127 else
173 status = 0; 128 status = 0;
129
130 rpc_shutdown_client(clnt);
174 return status; 131 return status;
175} 132}
176 133
@@ -190,32 +147,19 @@ int nsm_monitor(const struct nlm_host *host)
190 struct nsm_handle *nsm = host->h_nsmhandle; 147 struct nsm_handle *nsm = host->h_nsmhandle;
191 struct nsm_res res; 148 struct nsm_res res;
192 int status; 149 int status;
193 struct rpc_clnt *clnt;
194 const char *nodename = NULL;
195 150
196 dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); 151 dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
197 152
198 if (nsm->sm_monitored) 153 if (nsm->sm_monitored)
199 return 0; 154 return 0;
200 155
201 if (host->h_rpcclnt)
202 nodename = host->h_rpcclnt->cl_nodename;
203
204 /* 156 /*
205 * Choose whether to record the caller_name or IP address of 157 * Choose whether to record the caller_name or IP address of
206 * this peer in the local rpc.statd's database. 158 * this peer in the local rpc.statd's database.
207 */ 159 */
208 nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; 160 nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
209 161
210 clnt = nsm_client_get(host->net, nodename); 162 status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host);
211 if (IS_ERR(clnt)) {
212 status = PTR_ERR(clnt);
213 dprintk("lockd: failed to create NSM upcall transport, "
214 "status=%d, net=%p\n", status, host->net);
215 return status;
216 }
217
218 status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
219 if (unlikely(res.status != 0)) 163 if (unlikely(res.status != 0))
220 status = -EIO; 164 status = -EIO;
221 if (unlikely(status < 0)) { 165 if (unlikely(status < 0)) {
@@ -247,11 +191,9 @@ void nsm_unmonitor(const struct nlm_host *host)
247 191
248 if (atomic_read(&nsm->sm_count) == 1 192 if (atomic_read(&nsm->sm_count) == 1
249 && nsm->sm_monitored && !nsm->sm_sticky) { 193 && nsm->sm_monitored && !nsm->sm_sticky) {
250 struct lockd_net *ln = net_generic(host->net, lockd_net_id);
251
252 dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); 194 dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
253 195
254 status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt); 196 status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host);
255 if (res.status != 0) 197 if (res.status != 0)
256 status = -EIO; 198 status = -EIO;
257 if (status < 0) 199 if (status < 0)
@@ -259,38 +201,38 @@ void nsm_unmonitor(const struct nlm_host *host)
259 nsm->sm_name); 201 nsm->sm_name);
260 else 202 else
261 nsm->sm_monitored = 0; 203 nsm->sm_monitored = 0;
262
263 nsm_client_put(host->net);
264 } 204 }
265} 205}
266 206
267static struct nsm_handle *nsm_lookup_hostname(const char *hostname, 207static struct nsm_handle *nsm_lookup_hostname(const struct list_head *nsm_handles,
268 const size_t len) 208 const char *hostname, const size_t len)
269{ 209{
270 struct nsm_handle *nsm; 210 struct nsm_handle *nsm;
271 211
272 list_for_each_entry(nsm, &nsm_handles, sm_link) 212 list_for_each_entry(nsm, nsm_handles, sm_link)
273 if (strlen(nsm->sm_name) == len && 213 if (strlen(nsm->sm_name) == len &&
274 memcmp(nsm->sm_name, hostname, len) == 0) 214 memcmp(nsm->sm_name, hostname, len) == 0)
275 return nsm; 215 return nsm;
276 return NULL; 216 return NULL;
277} 217}
278 218
279static struct nsm_handle *nsm_lookup_addr(const struct sockaddr *sap) 219static struct nsm_handle *nsm_lookup_addr(const struct list_head *nsm_handles,
220 const struct sockaddr *sap)
280{ 221{
281 struct nsm_handle *nsm; 222 struct nsm_handle *nsm;
282 223
283 list_for_each_entry(nsm, &nsm_handles, sm_link) 224 list_for_each_entry(nsm, nsm_handles, sm_link)
284 if (rpc_cmp_addr(nsm_addr(nsm), sap)) 225 if (rpc_cmp_addr(nsm_addr(nsm), sap))
285 return nsm; 226 return nsm;
286 return NULL; 227 return NULL;
287} 228}
288 229
289static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv) 230static struct nsm_handle *nsm_lookup_priv(const struct list_head *nsm_handles,
231 const struct nsm_private *priv)
290{ 232{
291 struct nsm_handle *nsm; 233 struct nsm_handle *nsm;
292 234
293 list_for_each_entry(nsm, &nsm_handles, sm_link) 235 list_for_each_entry(nsm, nsm_handles, sm_link)
294 if (memcmp(nsm->sm_priv.data, priv->data, 236 if (memcmp(nsm->sm_priv.data, priv->data,
295 sizeof(priv->data)) == 0) 237 sizeof(priv->data)) == 0)
296 return nsm; 238 return nsm;
@@ -353,6 +295,7 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
353 295
354/** 296/**
355 * nsm_get_handle - Find or create a cached nsm_handle 297 * nsm_get_handle - Find or create a cached nsm_handle
298 * @net: network namespace
356 * @sap: pointer to socket address of handle to find 299 * @sap: pointer to socket address of handle to find
357 * @salen: length of socket address 300 * @salen: length of socket address
358 * @hostname: pointer to C string containing hostname to find 301 * @hostname: pointer to C string containing hostname to find
@@ -365,11 +308,13 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
365 * @hostname cannot be found in the handle cache. Returns NULL if 308 * @hostname cannot be found in the handle cache. Returns NULL if
366 * an error occurs. 309 * an error occurs.
367 */ 310 */
368struct nsm_handle *nsm_get_handle(const struct sockaddr *sap, 311struct nsm_handle *nsm_get_handle(const struct net *net,
312 const struct sockaddr *sap,
369 const size_t salen, const char *hostname, 313 const size_t salen, const char *hostname,
370 const size_t hostname_len) 314 const size_t hostname_len)
371{ 315{
372 struct nsm_handle *cached, *new = NULL; 316 struct nsm_handle *cached, *new = NULL;
317 struct lockd_net *ln = net_generic(net, lockd_net_id);
373 318
374 if (hostname && memchr(hostname, '/', hostname_len) != NULL) { 319 if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
375 if (printk_ratelimit()) { 320 if (printk_ratelimit()) {
@@ -384,9 +329,10 @@ retry:
384 spin_lock(&nsm_lock); 329 spin_lock(&nsm_lock);
385 330
386 if (nsm_use_hostnames && hostname != NULL) 331 if (nsm_use_hostnames && hostname != NULL)
387 cached = nsm_lookup_hostname(hostname, hostname_len); 332 cached = nsm_lookup_hostname(&ln->nsm_handles,
333 hostname, hostname_len);
388 else 334 else
389 cached = nsm_lookup_addr(sap); 335 cached = nsm_lookup_addr(&ln->nsm_handles, sap);
390 336
391 if (cached != NULL) { 337 if (cached != NULL) {
392 atomic_inc(&cached->sm_count); 338 atomic_inc(&cached->sm_count);
@@ -400,7 +346,7 @@ retry:
400 } 346 }
401 347
402 if (new != NULL) { 348 if (new != NULL) {
403 list_add(&new->sm_link, &nsm_handles); 349 list_add(&new->sm_link, &ln->nsm_handles);
404 spin_unlock(&nsm_lock); 350 spin_unlock(&nsm_lock);
405 dprintk("lockd: created nsm_handle for %s (%s)\n", 351 dprintk("lockd: created nsm_handle for %s (%s)\n",
406 new->sm_name, new->sm_addrbuf); 352 new->sm_name, new->sm_addrbuf);
@@ -417,19 +363,22 @@ retry:
417 363
418/** 364/**
419 * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle 365 * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle
366 * @net: network namespace
420 * @info: pointer to NLMPROC_SM_NOTIFY arguments 367 * @info: pointer to NLMPROC_SM_NOTIFY arguments
421 * 368 *
422 * Returns a matching nsm_handle if found in the nsm cache. The returned 369 * Returns a matching nsm_handle if found in the nsm cache. The returned
423 * nsm_handle's reference count is bumped. Otherwise returns NULL if some 370 * nsm_handle's reference count is bumped. Otherwise returns NULL if some
424 * error occurred. 371 * error occurred.
425 */ 372 */
426struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info) 373struct nsm_handle *nsm_reboot_lookup(const struct net *net,
374 const struct nlm_reboot *info)
427{ 375{
428 struct nsm_handle *cached; 376 struct nsm_handle *cached;
377 struct lockd_net *ln = net_generic(net, lockd_net_id);
429 378
430 spin_lock(&nsm_lock); 379 spin_lock(&nsm_lock);
431 380
432 cached = nsm_lookup_priv(&info->priv); 381 cached = nsm_lookup_priv(&ln->nsm_handles, &info->priv);
433 if (unlikely(cached == NULL)) { 382 if (unlikely(cached == NULL)) {
434 spin_unlock(&nsm_lock); 383 spin_unlock(&nsm_lock);
435 dprintk("lockd: never saw rebooted peer '%.*s' before\n", 384 dprintk("lockd: never saw rebooted peer '%.*s' before\n",
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h
index 097bfa3adb1c..5426189406c1 100644
--- a/fs/lockd/netns.h
+++ b/fs/lockd/netns.h
@@ -12,9 +12,7 @@ struct lockd_net {
12 struct delayed_work grace_period_end; 12 struct delayed_work grace_period_end;
13 struct lock_manager lockd_manager; 13 struct lock_manager lockd_manager;
14 14
15 spinlock_t nsm_clnt_lock; 15 struct list_head nsm_handles;
16 unsigned int nsm_users;
17 struct rpc_clnt *nsm_clnt;
18}; 16};
19 17
20extern int lockd_net_id; 18extern int lockd_net_id;
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index d678bcc3cbcb..5f31ebd96c06 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -592,7 +592,7 @@ static int lockd_init_net(struct net *net)
592 INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); 592 INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
593 INIT_LIST_HEAD(&ln->lockd_manager.list); 593 INIT_LIST_HEAD(&ln->lockd_manager.list);
594 ln->lockd_manager.block_opens = false; 594 ln->lockd_manager.block_opens = false;
595 spin_lock_init(&ln->nsm_clnt_lock); 595 INIT_LIST_HEAD(&ln->nsm_handles);
596 return 0; 596 return 0;
597} 597}
598 598
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index b147d1ae71fd..09c576f26c7b 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -421,7 +421,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
421 return rpc_system_err; 421 return rpc_system_err;
422 } 422 }
423 423
424 nlm_host_rebooted(argp); 424 nlm_host_rebooted(SVC_NET(rqstp), argp);
425 return rpc_success; 425 return rpc_success;
426} 426}
427 427
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 21171f0c6477..fb26b9f522e7 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -464,7 +464,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
464 return rpc_system_err; 464 return rpc_system_err;
465 } 465 }
466 466
467 nlm_host_rebooted(argp); 467 nlm_host_rebooted(SVC_NET(rqstp), argp);
468 return rpc_success; 468 return rpc_success;
469} 469}
470 470
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index f6e7cbabac5a..00575d776d91 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -262,11 +262,11 @@ void fill_post_wcc(struct svc_fh *fhp)
262 err = fh_getattr(fhp, &fhp->fh_post_attr); 262 err = fh_getattr(fhp, &fhp->fh_post_attr);
263 fhp->fh_post_change = d_inode(fhp->fh_dentry)->i_version; 263 fhp->fh_post_change = d_inode(fhp->fh_dentry)->i_version;
264 if (err) { 264 if (err) {
265 fhp->fh_post_saved = 0; 265 fhp->fh_post_saved = false;
266 /* Grab the ctime anyway - set_change_info might use it */ 266 /* Grab the ctime anyway - set_change_info might use it */
267 fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime; 267 fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime;
268 } else 268 } else
269 fhp->fh_post_saved = 1; 269 fhp->fh_post_saved = true;
270} 270}
271 271
272/* 272/*
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index ebf90e487c75..9ffef06b30d5 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -201,6 +201,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
201 INIT_LIST_HEAD(&ls->ls_perfile); 201 INIT_LIST_HEAD(&ls->ls_perfile);
202 spin_lock_init(&ls->ls_lock); 202 spin_lock_init(&ls->ls_lock);
203 INIT_LIST_HEAD(&ls->ls_layouts); 203 INIT_LIST_HEAD(&ls->ls_layouts);
204 mutex_init(&ls->ls_mutex);
204 ls->ls_layout_type = layout_type; 205 ls->ls_layout_type = layout_type;
205 nfsd4_init_cb(&ls->ls_recall, clp, &nfsd4_cb_layout_ops, 206 nfsd4_init_cb(&ls->ls_recall, clp, &nfsd4_cb_layout_ops,
206 NFSPROC4_CLNT_CB_LAYOUT); 207 NFSPROC4_CLNT_CB_LAYOUT);
@@ -262,19 +263,23 @@ nfsd4_preprocess_layout_stateid(struct svc_rqst *rqstp,
262 status = nfserr_jukebox; 263 status = nfserr_jukebox;
263 if (!ls) 264 if (!ls)
264 goto out; 265 goto out;
266 mutex_lock(&ls->ls_mutex);
265 } else { 267 } else {
266 ls = container_of(stid, struct nfs4_layout_stateid, ls_stid); 268 ls = container_of(stid, struct nfs4_layout_stateid, ls_stid);
267 269
268 status = nfserr_bad_stateid; 270 status = nfserr_bad_stateid;
271 mutex_lock(&ls->ls_mutex);
269 if (stateid->si_generation > stid->sc_stateid.si_generation) 272 if (stateid->si_generation > stid->sc_stateid.si_generation)
270 goto out_put_stid; 273 goto out_unlock_stid;
271 if (layout_type != ls->ls_layout_type) 274 if (layout_type != ls->ls_layout_type)
272 goto out_put_stid; 275 goto out_unlock_stid;
273 } 276 }
274 277
275 *lsp = ls; 278 *lsp = ls;
276 return 0; 279 return 0;
277 280
281out_unlock_stid:
282 mutex_unlock(&ls->ls_mutex);
278out_put_stid: 283out_put_stid:
279 nfs4_put_stid(stid); 284 nfs4_put_stid(stid);
280out: 285out:
@@ -296,8 +301,6 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
296 trace_layout_recall(&ls->ls_stid.sc_stateid); 301 trace_layout_recall(&ls->ls_stid.sc_stateid);
297 302
298 atomic_inc(&ls->ls_stid.sc_count); 303 atomic_inc(&ls->ls_stid.sc_count);
299 update_stateid(&ls->ls_stid.sc_stateid);
300 memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t));
301 nfsd4_run_cb(&ls->ls_recall); 304 nfsd4_run_cb(&ls->ls_recall);
302 305
303out_unlock: 306out_unlock:
@@ -406,8 +409,7 @@ nfsd4_insert_layout(struct nfsd4_layoutget *lgp, struct nfs4_layout_stateid *ls)
406 list_add_tail(&new->lo_perstate, &ls->ls_layouts); 409 list_add_tail(&new->lo_perstate, &ls->ls_layouts);
407 new = NULL; 410 new = NULL;
408done: 411done:
409 update_stateid(&ls->ls_stid.sc_stateid); 412 nfs4_inc_and_copy_stateid(&lgp->lg_sid, &ls->ls_stid);
410 memcpy(&lgp->lg_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t));
411 spin_unlock(&ls->ls_lock); 413 spin_unlock(&ls->ls_lock);
412out: 414out:
413 spin_unlock(&fp->fi_lock); 415 spin_unlock(&fp->fi_lock);
@@ -481,11 +483,8 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
481 } 483 }
482 } 484 }
483 if (!list_empty(&ls->ls_layouts)) { 485 if (!list_empty(&ls->ls_layouts)) {
484 if (found) { 486 if (found)
485 update_stateid(&ls->ls_stid.sc_stateid); 487 nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
486 memcpy(&lrp->lr_sid, &ls->ls_stid.sc_stateid,
487 sizeof(stateid_t));
488 }
489 lrp->lrs_present = 1; 488 lrp->lrs_present = 1;
490 } else { 489 } else {
491 trace_layoutstate_unhash(&ls->ls_stid.sc_stateid); 490 trace_layoutstate_unhash(&ls->ls_stid.sc_stateid);
@@ -494,6 +493,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
494 } 493 }
495 spin_unlock(&ls->ls_lock); 494 spin_unlock(&ls->ls_lock);
496 495
496 mutex_unlock(&ls->ls_mutex);
497 nfs4_put_stid(&ls->ls_stid); 497 nfs4_put_stid(&ls->ls_stid);
498 nfsd4_free_layouts(&reaplist); 498 nfsd4_free_layouts(&reaplist);
499 return nfs_ok; 499 return nfs_ok;
@@ -608,6 +608,16 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls)
608 } 608 }
609} 609}
610 610
611static void
612nfsd4_cb_layout_prepare(struct nfsd4_callback *cb)
613{
614 struct nfs4_layout_stateid *ls =
615 container_of(cb, struct nfs4_layout_stateid, ls_recall);
616
617 mutex_lock(&ls->ls_mutex);
618 nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid);
619}
620
611static int 621static int
612nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task) 622nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
613{ 623{
@@ -649,12 +659,14 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
649 659
650 trace_layout_recall_release(&ls->ls_stid.sc_stateid); 660 trace_layout_recall_release(&ls->ls_stid.sc_stateid);
651 661
662 mutex_unlock(&ls->ls_mutex);
652 nfsd4_return_all_layouts(ls, &reaplist); 663 nfsd4_return_all_layouts(ls, &reaplist);
653 nfsd4_free_layouts(&reaplist); 664 nfsd4_free_layouts(&reaplist);
654 nfs4_put_stid(&ls->ls_stid); 665 nfs4_put_stid(&ls->ls_stid);
655} 666}
656 667
657static struct nfsd4_callback_ops nfsd4_cb_layout_ops = { 668static struct nfsd4_callback_ops nfsd4_cb_layout_ops = {
669 .prepare = nfsd4_cb_layout_prepare,
658 .done = nfsd4_cb_layout_done, 670 .done = nfsd4_cb_layout_done,
659 .release = nfsd4_cb_layout_release, 671 .release = nfsd4_cb_layout_release,
660}; 672};
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 4ce6b97b31ad..a9f096c7e99f 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1309,6 +1309,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
1309 nfserr = nfsd4_insert_layout(lgp, ls); 1309 nfserr = nfsd4_insert_layout(lgp, ls);
1310 1310
1311out_put_stid: 1311out_put_stid:
1312 mutex_unlock(&ls->ls_mutex);
1312 nfs4_put_stid(&ls->ls_stid); 1313 nfs4_put_stid(&ls->ls_stid);
1313out: 1314out:
1314 return nfserr; 1315 return nfserr;
@@ -1362,6 +1363,9 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
1362 goto out; 1363 goto out;
1363 } 1364 }
1364 1365
1366 /* LAYOUTCOMMIT does not require any serialization */
1367 mutex_unlock(&ls->ls_mutex);
1368
1365 if (new_size > i_size_read(inode)) { 1369 if (new_size > i_size_read(inode)) {
1366 lcp->lc_size_chg = 1; 1370 lcp->lc_size_chg = 1;
1367 lcp->lc_newsize = new_size; 1371 lcp->lc_newsize = new_size;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 0f1d5691b795..6b800b5b8fed 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -575,6 +575,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
575 stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid; 575 stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
576 /* Will be incremented before return to client: */ 576 /* Will be incremented before return to client: */
577 atomic_set(&stid->sc_count, 1); 577 atomic_set(&stid->sc_count, 1);
578 spin_lock_init(&stid->sc_lock);
578 579
579 /* 580 /*
580 * It shouldn't be a problem to reuse an opaque stateid value. 581 * It shouldn't be a problem to reuse an opaque stateid value.
@@ -745,6 +746,18 @@ nfs4_put_stid(struct nfs4_stid *s)
745 put_nfs4_file(fp); 746 put_nfs4_file(fp);
746} 747}
747 748
749void
750nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid)
751{
752 stateid_t *src = &stid->sc_stateid;
753
754 spin_lock(&stid->sc_lock);
755 if (unlikely(++src->si_generation == 0))
756 src->si_generation = 1;
757 memcpy(dst, src, sizeof(*dst));
758 spin_unlock(&stid->sc_lock);
759}
760
748static void nfs4_put_deleg_lease(struct nfs4_file *fp) 761static void nfs4_put_deleg_lease(struct nfs4_file *fp)
749{ 762{
750 struct file *filp = NULL; 763 struct file *filp = NULL;
@@ -765,16 +778,68 @@ void nfs4_unhash_stid(struct nfs4_stid *s)
765 s->sc_type = 0; 778 s->sc_type = 0;
766} 779}
767 780
768static void 781/**
782 * nfs4_get_existing_delegation - Discover if this delegation already exists
783 * @clp: a pointer to the nfs4_client we're granting a delegation to
784 * @fp: a pointer to the nfs4_file we're granting a delegation on
785 *
786 * Return:
787 * On success: NULL if an existing delegation was not found.
788 *
789 * On error: -EAGAIN if one was previously granted to this nfs4_client
790 * for this nfs4_file.
791 *
792 */
793
794static int
795nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp)
796{
797 struct nfs4_delegation *searchdp = NULL;
798 struct nfs4_client *searchclp = NULL;
799
800 lockdep_assert_held(&state_lock);
801 lockdep_assert_held(&fp->fi_lock);
802
803 list_for_each_entry(searchdp, &fp->fi_delegations, dl_perfile) {
804 searchclp = searchdp->dl_stid.sc_client;
805 if (clp == searchclp) {
806 return -EAGAIN;
807 }
808 }
809 return 0;
810}
811
812/**
813 * hash_delegation_locked - Add a delegation to the appropriate lists
814 * @dp: a pointer to the nfs4_delegation we are adding.
815 * @fp: a pointer to the nfs4_file we're granting a delegation on
816 *
817 * Return:
818 * On success: NULL if the delegation was successfully hashed.
819 *
820 * On error: -EAGAIN if one was previously granted to this
821 * nfs4_client for this nfs4_file. Delegation is not hashed.
822 *
823 */
824
825static int
769hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp) 826hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
770{ 827{
828 int status;
829 struct nfs4_client *clp = dp->dl_stid.sc_client;
830
771 lockdep_assert_held(&state_lock); 831 lockdep_assert_held(&state_lock);
772 lockdep_assert_held(&fp->fi_lock); 832 lockdep_assert_held(&fp->fi_lock);
773 833
834 status = nfs4_get_existing_delegation(clp, fp);
835 if (status)
836 return status;
837 ++fp->fi_delegees;
774 atomic_inc(&dp->dl_stid.sc_count); 838 atomic_inc(&dp->dl_stid.sc_count);
775 dp->dl_stid.sc_type = NFS4_DELEG_STID; 839 dp->dl_stid.sc_type = NFS4_DELEG_STID;
776 list_add(&dp->dl_perfile, &fp->fi_delegations); 840 list_add(&dp->dl_perfile, &fp->fi_delegations);
777 list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); 841 list_add(&dp->dl_perclnt, &clp->cl_delegations);
842 return 0;
778} 843}
779 844
780static bool 845static bool
@@ -2256,15 +2321,20 @@ nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
2256 clid->flags = new->cl_exchange_flags; 2321 clid->flags = new->cl_exchange_flags;
2257} 2322}
2258 2323
2324static bool client_has_openowners(struct nfs4_client *clp)
2325{
2326 struct nfs4_openowner *oo;
2327
2328 list_for_each_entry(oo, &clp->cl_openowners, oo_perclient) {
2329 if (!list_empty(&oo->oo_owner.so_stateids))
2330 return true;
2331 }
2332 return false;
2333}
2334
2259static bool client_has_state(struct nfs4_client *clp) 2335static bool client_has_state(struct nfs4_client *clp)
2260{ 2336{
2261 /* 2337 return client_has_openowners(clp)
2262 * Note clp->cl_openowners check isn't quite right: there's no
2263 * need to count owners without stateid's.
2264 *
2265 * Also note we should probably be using this in 4.0 case too.
2266 */
2267 return !list_empty(&clp->cl_openowners)
2268#ifdef CONFIG_NFSD_PNFS 2338#ifdef CONFIG_NFSD_PNFS
2269 || !list_empty(&clp->cl_lo_states) 2339 || !list_empty(&clp->cl_lo_states)
2270#endif 2340#endif
@@ -3049,7 +3119,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3049 /* Cases below refer to rfc 3530 section 14.2.33: */ 3119 /* Cases below refer to rfc 3530 section 14.2.33: */
3050 spin_lock(&nn->client_lock); 3120 spin_lock(&nn->client_lock);
3051 conf = find_confirmed_client_by_name(&clname, nn); 3121 conf = find_confirmed_client_by_name(&clname, nn);
3052 if (conf) { 3122 if (conf && client_has_state(conf)) {
3053 /* case 0: */ 3123 /* case 0: */
3054 status = nfserr_clid_inuse; 3124 status = nfserr_clid_inuse;
3055 if (clp_used_exchangeid(conf)) 3125 if (clp_used_exchangeid(conf))
@@ -3136,6 +3206,11 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
3136 } else { /* case 3: normal case; new or rebooted client */ 3206 } else { /* case 3: normal case; new or rebooted client */
3137 old = find_confirmed_client_by_name(&unconf->cl_name, nn); 3207 old = find_confirmed_client_by_name(&unconf->cl_name, nn);
3138 if (old) { 3208 if (old) {
3209 status = nfserr_clid_inuse;
3210 if (client_has_state(old)
3211 && !same_creds(&unconf->cl_cred,
3212 &old->cl_cred))
3213 goto out;
3139 status = mark_client_expired_locked(old); 3214 status = mark_client_expired_locked(old);
3140 if (status) { 3215 if (status) {
3141 old = NULL; 3216 old = NULL;
@@ -3317,6 +3392,27 @@ static const struct nfs4_stateowner_operations openowner_ops = {
3317 .so_free = nfs4_free_openowner, 3392 .so_free = nfs4_free_openowner,
3318}; 3393};
3319 3394
3395static struct nfs4_ol_stateid *
3396nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
3397{
3398 struct nfs4_ol_stateid *local, *ret = NULL;
3399 struct nfs4_openowner *oo = open->op_openowner;
3400
3401 lockdep_assert_held(&fp->fi_lock);
3402
3403 list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
3404 /* ignore lock owners */
3405 if (local->st_stateowner->so_is_open_owner == 0)
3406 continue;
3407 if (local->st_stateowner == &oo->oo_owner) {
3408 ret = local;
3409 atomic_inc(&ret->st_stid.sc_count);
3410 break;
3411 }
3412 }
3413 return ret;
3414}
3415
3320static struct nfs4_openowner * 3416static struct nfs4_openowner *
3321alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open, 3417alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
3322 struct nfsd4_compound_state *cstate) 3418 struct nfsd4_compound_state *cstate)
@@ -3348,9 +3444,20 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open,
3348 return ret; 3444 return ret;
3349} 3445}
3350 3446
3351static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { 3447static struct nfs4_ol_stateid *
3448init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
3449 struct nfsd4_open *open)
3450{
3451
3352 struct nfs4_openowner *oo = open->op_openowner; 3452 struct nfs4_openowner *oo = open->op_openowner;
3453 struct nfs4_ol_stateid *retstp = NULL;
3353 3454
3455 spin_lock(&oo->oo_owner.so_client->cl_lock);
3456 spin_lock(&fp->fi_lock);
3457
3458 retstp = nfsd4_find_existing_open(fp, open);
3459 if (retstp)
3460 goto out_unlock;
3354 atomic_inc(&stp->st_stid.sc_count); 3461 atomic_inc(&stp->st_stid.sc_count);
3355 stp->st_stid.sc_type = NFS4_OPEN_STID; 3462 stp->st_stid.sc_type = NFS4_OPEN_STID;
3356 INIT_LIST_HEAD(&stp->st_locks); 3463 INIT_LIST_HEAD(&stp->st_locks);
@@ -3360,12 +3467,14 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
3360 stp->st_access_bmap = 0; 3467 stp->st_access_bmap = 0;
3361 stp->st_deny_bmap = 0; 3468 stp->st_deny_bmap = 0;
3362 stp->st_openstp = NULL; 3469 stp->st_openstp = NULL;
3363 spin_lock(&oo->oo_owner.so_client->cl_lock); 3470 init_rwsem(&stp->st_rwsem);
3364 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); 3471 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
3365 spin_lock(&fp->fi_lock);
3366 list_add(&stp->st_perfile, &fp->fi_stateids); 3472 list_add(&stp->st_perfile, &fp->fi_stateids);
3473
3474out_unlock:
3367 spin_unlock(&fp->fi_lock); 3475 spin_unlock(&fp->fi_lock);
3368 spin_unlock(&oo->oo_owner.so_client->cl_lock); 3476 spin_unlock(&oo->oo_owner.so_client->cl_lock);
3477 return retstp;
3369} 3478}
3370 3479
3371/* 3480/*
@@ -3776,27 +3885,6 @@ out:
3776 return nfs_ok; 3885 return nfs_ok;
3777} 3886}
3778 3887
3779static struct nfs4_ol_stateid *
3780nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open)
3781{
3782 struct nfs4_ol_stateid *local, *ret = NULL;
3783 struct nfs4_openowner *oo = open->op_openowner;
3784
3785 spin_lock(&fp->fi_lock);
3786 list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
3787 /* ignore lock owners */
3788 if (local->st_stateowner->so_is_open_owner == 0)
3789 continue;
3790 if (local->st_stateowner == &oo->oo_owner) {
3791 ret = local;
3792 atomic_inc(&ret->st_stid.sc_count);
3793 break;
3794 }
3795 }
3796 spin_unlock(&fp->fi_lock);
3797 return ret;
3798}
3799
3800static inline int nfs4_access_to_access(u32 nfs4_access) 3888static inline int nfs4_access_to_access(u32 nfs4_access)
3801{ 3889{
3802 int flags = 0; 3890 int flags = 0;
@@ -3945,6 +4033,18 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
3945 return fl; 4033 return fl;
3946} 4034}
3947 4035
4036/**
4037 * nfs4_setlease - Obtain a delegation by requesting lease from vfs layer
4038 * @dp: a pointer to the nfs4_delegation we're adding.
4039 *
4040 * Return:
4041 * On success: Return code will be 0 on success.
4042 *
4043 * On error: -EAGAIN if there was an existing delegation.
4044 * nonzero if there is an error in other cases.
4045 *
4046 */
4047
3948static int nfs4_setlease(struct nfs4_delegation *dp) 4048static int nfs4_setlease(struct nfs4_delegation *dp)
3949{ 4049{
3950 struct nfs4_file *fp = dp->dl_stid.sc_file; 4050 struct nfs4_file *fp = dp->dl_stid.sc_file;
@@ -3976,16 +4076,19 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
3976 goto out_unlock; 4076 goto out_unlock;
3977 /* Race breaker */ 4077 /* Race breaker */
3978 if (fp->fi_deleg_file) { 4078 if (fp->fi_deleg_file) {
3979 status = 0; 4079 status = hash_delegation_locked(dp, fp);
3980 ++fp->fi_delegees;
3981 hash_delegation_locked(dp, fp);
3982 goto out_unlock; 4080 goto out_unlock;
3983 } 4081 }
3984 fp->fi_deleg_file = filp; 4082 fp->fi_deleg_file = filp;
3985 fp->fi_delegees = 1; 4083 fp->fi_delegees = 0;
3986 hash_delegation_locked(dp, fp); 4084 status = hash_delegation_locked(dp, fp);
3987 spin_unlock(&fp->fi_lock); 4085 spin_unlock(&fp->fi_lock);
3988 spin_unlock(&state_lock); 4086 spin_unlock(&state_lock);
4087 if (status) {
4088 /* Should never happen, this is a new fi_deleg_file */
4089 WARN_ON_ONCE(1);
4090 goto out_fput;
4091 }
3989 return 0; 4092 return 0;
3990out_unlock: 4093out_unlock:
3991 spin_unlock(&fp->fi_lock); 4094 spin_unlock(&fp->fi_lock);
@@ -4005,6 +4108,15 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
4005 if (fp->fi_had_conflict) 4108 if (fp->fi_had_conflict)
4006 return ERR_PTR(-EAGAIN); 4109 return ERR_PTR(-EAGAIN);
4007 4110
4111 spin_lock(&state_lock);
4112 spin_lock(&fp->fi_lock);
4113 status = nfs4_get_existing_delegation(clp, fp);
4114 spin_unlock(&fp->fi_lock);
4115 spin_unlock(&state_lock);
4116
4117 if (status)
4118 return ERR_PTR(status);
4119
4008 dp = alloc_init_deleg(clp, fh, odstate); 4120 dp = alloc_init_deleg(clp, fh, odstate);
4009 if (!dp) 4121 if (!dp)
4010 return ERR_PTR(-ENOMEM); 4122 return ERR_PTR(-ENOMEM);
@@ -4023,9 +4135,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
4023 status = -EAGAIN; 4135 status = -EAGAIN;
4024 goto out_unlock; 4136 goto out_unlock;
4025 } 4137 }
4026 ++fp->fi_delegees; 4138 status = hash_delegation_locked(dp, fp);
4027 hash_delegation_locked(dp, fp);
4028 status = 0;
4029out_unlock: 4139out_unlock:
4030 spin_unlock(&fp->fi_lock); 4140 spin_unlock(&fp->fi_lock);
4031 spin_unlock(&state_lock); 4141 spin_unlock(&state_lock);
@@ -4160,6 +4270,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
4160 struct nfs4_client *cl = open->op_openowner->oo_owner.so_client; 4270 struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
4161 struct nfs4_file *fp = NULL; 4271 struct nfs4_file *fp = NULL;
4162 struct nfs4_ol_stateid *stp = NULL; 4272 struct nfs4_ol_stateid *stp = NULL;
4273 struct nfs4_ol_stateid *swapstp = NULL;
4163 struct nfs4_delegation *dp = NULL; 4274 struct nfs4_delegation *dp = NULL;
4164 __be32 status; 4275 __be32 status;
4165 4276
@@ -4173,7 +4284,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
4173 status = nfs4_check_deleg(cl, open, &dp); 4284 status = nfs4_check_deleg(cl, open, &dp);
4174 if (status) 4285 if (status)
4175 goto out; 4286 goto out;
4287 spin_lock(&fp->fi_lock);
4176 stp = nfsd4_find_existing_open(fp, open); 4288 stp = nfsd4_find_existing_open(fp, open);
4289 spin_unlock(&fp->fi_lock);
4177 } else { 4290 } else {
4178 open->op_file = NULL; 4291 open->op_file = NULL;
4179 status = nfserr_bad_stateid; 4292 status = nfserr_bad_stateid;
@@ -4187,15 +4300,32 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
4187 */ 4300 */
4188 if (stp) { 4301 if (stp) {
4189 /* Stateid was found, this is an OPEN upgrade */ 4302 /* Stateid was found, this is an OPEN upgrade */
4303 down_read(&stp->st_rwsem);
4190 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open); 4304 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
4191 if (status) 4305 if (status) {
4306 up_read(&stp->st_rwsem);
4192 goto out; 4307 goto out;
4308 }
4193 } else { 4309 } else {
4194 stp = open->op_stp; 4310 stp = open->op_stp;
4195 open->op_stp = NULL; 4311 open->op_stp = NULL;
4196 init_open_stateid(stp, fp, open); 4312 swapstp = init_open_stateid(stp, fp, open);
4313 if (swapstp) {
4314 nfs4_put_stid(&stp->st_stid);
4315 stp = swapstp;
4316 down_read(&stp->st_rwsem);
4317 status = nfs4_upgrade_open(rqstp, fp, current_fh,
4318 stp, open);
4319 if (status) {
4320 up_read(&stp->st_rwsem);
4321 goto out;
4322 }
4323 goto upgrade_out;
4324 }
4325 down_read(&stp->st_rwsem);
4197 status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open); 4326 status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
4198 if (status) { 4327 if (status) {
4328 up_read(&stp->st_rwsem);
4199 release_open_stateid(stp); 4329 release_open_stateid(stp);
4200 goto out; 4330 goto out;
4201 } 4331 }
@@ -4205,8 +4335,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
4205 if (stp->st_clnt_odstate == open->op_odstate) 4335 if (stp->st_clnt_odstate == open->op_odstate)
4206 open->op_odstate = NULL; 4336 open->op_odstate = NULL;
4207 } 4337 }
4208 update_stateid(&stp->st_stid.sc_stateid); 4338upgrade_out:
4209 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4339 nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
4340 up_read(&stp->st_rwsem);
4210 4341
4211 if (nfsd4_has_session(&resp->cstate)) { 4342 if (nfsd4_has_session(&resp->cstate)) {
4212 if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) { 4343 if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
@@ -4819,10 +4950,13 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
4819 * revoked delegations are kept only for free_stateid. 4950 * revoked delegations are kept only for free_stateid.
4820 */ 4951 */
4821 return nfserr_bad_stateid; 4952 return nfserr_bad_stateid;
4953 down_write(&stp->st_rwsem);
4822 status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate)); 4954 status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
4823 if (status) 4955 if (status == nfs_ok)
4824 return status; 4956 status = nfs4_check_fh(current_fh, &stp->st_stid);
4825 return nfs4_check_fh(current_fh, &stp->st_stid); 4957 if (status != nfs_ok)
4958 up_write(&stp->st_rwsem);
4959 return status;
4826} 4960}
4827 4961
4828/* 4962/*
@@ -4869,6 +5003,7 @@ static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cs
4869 return status; 5003 return status;
4870 oo = openowner(stp->st_stateowner); 5004 oo = openowner(stp->st_stateowner);
4871 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) { 5005 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
5006 up_write(&stp->st_rwsem);
4872 nfs4_put_stid(&stp->st_stid); 5007 nfs4_put_stid(&stp->st_stid);
4873 return nfserr_bad_stateid; 5008 return nfserr_bad_stateid;
4874 } 5009 }
@@ -4899,11 +5034,13 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4899 goto out; 5034 goto out;
4900 oo = openowner(stp->st_stateowner); 5035 oo = openowner(stp->st_stateowner);
4901 status = nfserr_bad_stateid; 5036 status = nfserr_bad_stateid;
4902 if (oo->oo_flags & NFS4_OO_CONFIRMED) 5037 if (oo->oo_flags & NFS4_OO_CONFIRMED) {
5038 up_write(&stp->st_rwsem);
4903 goto put_stateid; 5039 goto put_stateid;
5040 }
4904 oo->oo_flags |= NFS4_OO_CONFIRMED; 5041 oo->oo_flags |= NFS4_OO_CONFIRMED;
4905 update_stateid(&stp->st_stid.sc_stateid); 5042 nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid);
4906 memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 5043 up_write(&stp->st_rwsem);
4907 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", 5044 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
4908 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid)); 5045 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
4909 5046
@@ -4975,13 +5112,11 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
4975 goto put_stateid; 5112 goto put_stateid;
4976 } 5113 }
4977 nfs4_stateid_downgrade(stp, od->od_share_access); 5114 nfs4_stateid_downgrade(stp, od->od_share_access);
4978
4979 reset_union_bmap_deny(od->od_share_deny, stp); 5115 reset_union_bmap_deny(od->od_share_deny, stp);
4980 5116 nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid);
4981 update_stateid(&stp->st_stid.sc_stateid);
4982 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4983 status = nfs_ok; 5117 status = nfs_ok;
4984put_stateid: 5118put_stateid:
5119 up_write(&stp->st_rwsem);
4985 nfs4_put_stid(&stp->st_stid); 5120 nfs4_put_stid(&stp->st_stid);
4986out: 5121out:
4987 nfsd4_bump_seqid(cstate, status); 5122 nfsd4_bump_seqid(cstate, status);
@@ -5033,8 +5168,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5033 nfsd4_bump_seqid(cstate, status); 5168 nfsd4_bump_seqid(cstate, status);
5034 if (status) 5169 if (status)
5035 goto out; 5170 goto out;
5036 update_stateid(&stp->st_stid.sc_stateid); 5171 nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
5037 memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 5172 up_write(&stp->st_rwsem);
5038 5173
5039 nfsd4_close_open_stateid(stp); 5174 nfsd4_close_open_stateid(stp);
5040 5175
@@ -5260,6 +5395,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
5260 stp->st_access_bmap = 0; 5395 stp->st_access_bmap = 0;
5261 stp->st_deny_bmap = open_stp->st_deny_bmap; 5396 stp->st_deny_bmap = open_stp->st_deny_bmap;
5262 stp->st_openstp = open_stp; 5397 stp->st_openstp = open_stp;
5398 init_rwsem(&stp->st_rwsem);
5263 list_add(&stp->st_locks, &open_stp->st_locks); 5399 list_add(&stp->st_locks, &open_stp->st_locks);
5264 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); 5400 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
5265 spin_lock(&fp->fi_lock); 5401 spin_lock(&fp->fi_lock);
@@ -5428,6 +5564,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5428 &open_stp, nn); 5564 &open_stp, nn);
5429 if (status) 5565 if (status)
5430 goto out; 5566 goto out;
5567 up_write(&open_stp->st_rwsem);
5431 open_sop = openowner(open_stp->st_stateowner); 5568 open_sop = openowner(open_stp->st_stateowner);
5432 status = nfserr_bad_stateid; 5569 status = nfserr_bad_stateid;
5433 if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid, 5570 if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
@@ -5435,6 +5572,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5435 goto out; 5572 goto out;
5436 status = lookup_or_create_lock_state(cstate, open_stp, lock, 5573 status = lookup_or_create_lock_state(cstate, open_stp, lock,
5437 &lock_stp, &new); 5574 &lock_stp, &new);
5575 if (status == nfs_ok)
5576 down_write(&lock_stp->st_rwsem);
5438 } else { 5577 } else {
5439 status = nfs4_preprocess_seqid_op(cstate, 5578 status = nfs4_preprocess_seqid_op(cstate,
5440 lock->lk_old_lock_seqid, 5579 lock->lk_old_lock_seqid,
@@ -5512,9 +5651,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5512 err = vfs_lock_file(filp, F_SETLK, file_lock, conflock); 5651 err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
5513 switch (-err) { 5652 switch (-err) {
5514 case 0: /* success! */ 5653 case 0: /* success! */
5515 update_stateid(&lock_stp->st_stid.sc_stateid); 5654 nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid);
5516 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid,
5517 sizeof(stateid_t));
5518 status = 0; 5655 status = 0;
5519 break; 5656 break;
5520 case (EAGAIN): /* conflock holds conflicting lock */ 5657 case (EAGAIN): /* conflock holds conflicting lock */
@@ -5540,6 +5677,8 @@ out:
5540 seqid_mutating_err(ntohl(status))) 5677 seqid_mutating_err(ntohl(status)))
5541 lock_sop->lo_owner.so_seqid++; 5678 lock_sop->lo_owner.so_seqid++;
5542 5679
5680 up_write(&lock_stp->st_rwsem);
5681
5543 /* 5682 /*
5544 * If this is a new, never-before-used stateid, and we are 5683 * If this is a new, never-before-used stateid, and we are
5545 * returning an error, then just go ahead and release it. 5684 * returning an error, then just go ahead and release it.
@@ -5704,11 +5843,11 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5704 dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n"); 5843 dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
5705 goto out_nfserr; 5844 goto out_nfserr;
5706 } 5845 }
5707 update_stateid(&stp->st_stid.sc_stateid); 5846 nfs4_inc_and_copy_stateid(&locku->lu_stateid, &stp->st_stid);
5708 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
5709fput: 5847fput:
5710 fput(filp); 5848 fput(filp);
5711put_stateid: 5849put_stateid:
5850 up_write(&stp->st_rwsem);
5712 nfs4_put_stid(&stp->st_stid); 5851 nfs4_put_stid(&stp->st_stid);
5713out: 5852out:
5714 nfsd4_bump_seqid(cstate, status); 5853 nfsd4_bump_seqid(cstate, status);
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index 46ec934f5dee..54cde9a5864e 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -63,7 +63,6 @@ static unsigned int longest_chain;
63static unsigned int longest_chain_cachesize; 63static unsigned int longest_chain_cachesize;
64 64
65static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec); 65static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
66static void cache_cleaner_func(struct work_struct *unused);
67static unsigned long nfsd_reply_cache_count(struct shrinker *shrink, 66static unsigned long nfsd_reply_cache_count(struct shrinker *shrink,
68 struct shrink_control *sc); 67 struct shrink_control *sc);
69static unsigned long nfsd_reply_cache_scan(struct shrinker *shrink, 68static unsigned long nfsd_reply_cache_scan(struct shrinker *shrink,
@@ -76,13 +75,6 @@ static struct shrinker nfsd_reply_cache_shrinker = {
76}; 75};
77 76
78/* 77/*
79 * locking for the reply cache:
80 * A cache entry is "single use" if c_state == RC_INPROG
81 * Otherwise, it when accessing _prev or _next, the lock must be held.
82 */
83static DECLARE_DELAYED_WORK(cache_cleaner, cache_cleaner_func);
84
85/*
86 * Put a cap on the size of the DRC based on the amount of available 78 * Put a cap on the size of the DRC based on the amount of available
87 * low memory in the machine. 79 * low memory in the machine.
88 * 80 *
@@ -203,7 +195,6 @@ void nfsd_reply_cache_shutdown(void)
203 unsigned int i; 195 unsigned int i;
204 196
205 unregister_shrinker(&nfsd_reply_cache_shrinker); 197 unregister_shrinker(&nfsd_reply_cache_shrinker);
206 cancel_delayed_work_sync(&cache_cleaner);
207 198
208 for (i = 0; i < drc_hashsize; i++) { 199 for (i = 0; i < drc_hashsize; i++) {
209 struct list_head *head = &drc_hashtbl[i].lru_head; 200 struct list_head *head = &drc_hashtbl[i].lru_head;
@@ -217,10 +208,8 @@ void nfsd_reply_cache_shutdown(void)
217 drc_hashtbl = NULL; 208 drc_hashtbl = NULL;
218 drc_hashsize = 0; 209 drc_hashsize = 0;
219 210
220 if (drc_slab) { 211 kmem_cache_destroy(drc_slab);
221 kmem_cache_destroy(drc_slab); 212 drc_slab = NULL;
222 drc_slab = NULL;
223 }
224} 213}
225 214
226/* 215/*
@@ -232,7 +221,6 @@ lru_put_end(struct nfsd_drc_bucket *b, struct svc_cacherep *rp)
232{ 221{
233 rp->c_timestamp = jiffies; 222 rp->c_timestamp = jiffies;
234 list_move_tail(&rp->c_lru, &b->lru_head); 223 list_move_tail(&rp->c_lru, &b->lru_head);
235 schedule_delayed_work(&cache_cleaner, RC_EXPIRE);
236} 224}
237 225
238static long 226static long
@@ -266,7 +254,6 @@ prune_cache_entries(void)
266{ 254{
267 unsigned int i; 255 unsigned int i;
268 long freed = 0; 256 long freed = 0;
269 bool cancel = true;
270 257
271 for (i = 0; i < drc_hashsize; i++) { 258 for (i = 0; i < drc_hashsize; i++) {
272 struct nfsd_drc_bucket *b = &drc_hashtbl[i]; 259 struct nfsd_drc_bucket *b = &drc_hashtbl[i];
@@ -275,26 +262,11 @@ prune_cache_entries(void)
275 continue; 262 continue;
276 spin_lock(&b->cache_lock); 263 spin_lock(&b->cache_lock);
277 freed += prune_bucket(b); 264 freed += prune_bucket(b);
278 if (!list_empty(&b->lru_head))
279 cancel = false;
280 spin_unlock(&b->cache_lock); 265 spin_unlock(&b->cache_lock);
281 } 266 }
282
283 /*
284 * Conditionally rearm the job to run in RC_EXPIRE since we just
285 * ran the pruner.
286 */
287 if (!cancel)
288 mod_delayed_work(system_wq, &cache_cleaner, RC_EXPIRE);
289 return freed; 267 return freed;
290} 268}
291 269
292static void
293cache_cleaner_func(struct work_struct *unused)
294{
295 prune_cache_entries();
296}
297
298static unsigned long 270static unsigned long
299nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc) 271nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc)
300{ 272{
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 350041a40fe5..c1681ce894c5 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -631,10 +631,7 @@ fh_put(struct svc_fh *fhp)
631 fh_unlock(fhp); 631 fh_unlock(fhp);
632 fhp->fh_dentry = NULL; 632 fhp->fh_dentry = NULL;
633 dput(dentry); 633 dput(dentry);
634#ifdef CONFIG_NFSD_V3 634 fh_clear_wcc(fhp);
635 fhp->fh_pre_saved = 0;
636 fhp->fh_post_saved = 0;
637#endif
638 } 635 }
639 fh_drop_write(fhp); 636 fh_drop_write(fhp);
640 if (exp) { 637 if (exp) {
diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h
index 1e90dad4926b..2087bae17582 100644
--- a/fs/nfsd/nfsfh.h
+++ b/fs/nfsd/nfsfh.h
@@ -26,16 +26,16 @@ static inline ino_t u32_to_ino_t(__u32 uino)
26 */ 26 */
27typedef struct svc_fh { 27typedef struct svc_fh {
28 struct knfsd_fh fh_handle; /* FH data */ 28 struct knfsd_fh fh_handle; /* FH data */
29 int fh_maxsize; /* max size for fh_handle */
29 struct dentry * fh_dentry; /* validated dentry */ 30 struct dentry * fh_dentry; /* validated dentry */
30 struct svc_export * fh_export; /* export pointer */ 31 struct svc_export * fh_export; /* export pointer */
31 int fh_maxsize; /* max size for fh_handle */
32 32
33 unsigned char fh_locked; /* inode locked by us */ 33 bool fh_locked; /* inode locked by us */
34 unsigned char fh_want_write; /* remount protection taken */ 34 bool fh_want_write; /* remount protection taken */
35 35
36#ifdef CONFIG_NFSD_V3 36#ifdef CONFIG_NFSD_V3
37 unsigned char fh_post_saved; /* post-op attrs saved */ 37 bool fh_post_saved; /* post-op attrs saved */
38 unsigned char fh_pre_saved; /* pre-op attrs saved */ 38 bool fh_pre_saved; /* pre-op attrs saved */
39 39
40 /* Pre-op attributes saved during fh_lock */ 40 /* Pre-op attributes saved during fh_lock */
41 __u64 fh_pre_size; /* size before operation */ 41 __u64 fh_pre_size; /* size before operation */
@@ -213,8 +213,8 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
213static inline void 213static inline void
214fh_clear_wcc(struct svc_fh *fhp) 214fh_clear_wcc(struct svc_fh *fhp)
215{ 215{
216 fhp->fh_post_saved = 0; 216 fhp->fh_post_saved = false;
217 fhp->fh_pre_saved = 0; 217 fhp->fh_pre_saved = false;
218} 218}
219 219
220/* 220/*
@@ -231,7 +231,7 @@ fill_pre_wcc(struct svc_fh *fhp)
231 fhp->fh_pre_ctime = inode->i_ctime; 231 fhp->fh_pre_ctime = inode->i_ctime;
232 fhp->fh_pre_size = inode->i_size; 232 fhp->fh_pre_size = inode->i_size;
233 fhp->fh_pre_change = inode->i_version; 233 fhp->fh_pre_change = inode->i_version;
234 fhp->fh_pre_saved = 1; 234 fhp->fh_pre_saved = true;
235 } 235 }
236} 236}
237 237
@@ -267,7 +267,7 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
267 inode = d_inode(dentry); 267 inode = d_inode(dentry);
268 mutex_lock_nested(&inode->i_mutex, subclass); 268 mutex_lock_nested(&inode->i_mutex, subclass);
269 fill_pre_wcc(fhp); 269 fill_pre_wcc(fhp);
270 fhp->fh_locked = 1; 270 fhp->fh_locked = true;
271} 271}
272 272
273static inline void 273static inline void
@@ -285,7 +285,7 @@ fh_unlock(struct svc_fh *fhp)
285 if (fhp->fh_locked) { 285 if (fhp->fh_locked) {
286 fill_post_wcc(fhp); 286 fill_post_wcc(fhp);
287 mutex_unlock(&d_inode(fhp->fh_dentry)->i_mutex); 287 mutex_unlock(&d_inode(fhp->fh_dentry)->i_mutex);
288 fhp->fh_locked = 0; 288 fhp->fh_locked = false;
289 } 289 }
290} 290}
291 291
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 583ffc13cae2..77fdf4de91ba 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -84,7 +84,7 @@ struct nfsd4_callback_ops {
84 * fields that are of general use to any stateid. 84 * fields that are of general use to any stateid.
85 */ 85 */
86struct nfs4_stid { 86struct nfs4_stid {
87 atomic_t sc_count; 87 atomic_t sc_count;
88#define NFS4_OPEN_STID 1 88#define NFS4_OPEN_STID 1
89#define NFS4_LOCK_STID 2 89#define NFS4_LOCK_STID 2
90#define NFS4_DELEG_STID 4 90#define NFS4_DELEG_STID 4
@@ -94,11 +94,12 @@ struct nfs4_stid {
94#define NFS4_REVOKED_DELEG_STID 16 94#define NFS4_REVOKED_DELEG_STID 16
95#define NFS4_CLOSED_DELEG_STID 32 95#define NFS4_CLOSED_DELEG_STID 32
96#define NFS4_LAYOUT_STID 64 96#define NFS4_LAYOUT_STID 64
97 unsigned char sc_type; 97 unsigned char sc_type;
98 stateid_t sc_stateid; 98 stateid_t sc_stateid;
99 struct nfs4_client *sc_client; 99 spinlock_t sc_lock;
100 struct nfs4_file *sc_file; 100 struct nfs4_client *sc_client;
101 void (*sc_free)(struct nfs4_stid *); 101 struct nfs4_file *sc_file;
102 void (*sc_free)(struct nfs4_stid *);
102}; 103};
103 104
104/* 105/*
@@ -364,15 +365,6 @@ struct nfs4_client_reclaim {
364 char cr_recdir[HEXDIR_LEN]; /* recover dir */ 365 char cr_recdir[HEXDIR_LEN]; /* recover dir */
365}; 366};
366 367
367static inline void
368update_stateid(stateid_t *stateid)
369{
370 stateid->si_generation++;
371 /* Wraparound recommendation from 3530bis-13 9.1.3.2: */
372 if (stateid->si_generation == 0)
373 stateid->si_generation = 1;
374}
375
376/* A reasonable value for REPLAY_ISIZE was estimated as follows: 368/* A reasonable value for REPLAY_ISIZE was estimated as follows:
377 * The OPEN response, typically the largest, requires 369 * The OPEN response, typically the largest, requires
378 * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + 370 * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) +
@@ -534,15 +526,16 @@ struct nfs4_file {
534 * Better suggestions welcome. 526 * Better suggestions welcome.
535 */ 527 */
536struct nfs4_ol_stateid { 528struct nfs4_ol_stateid {
537 struct nfs4_stid st_stid; /* must be first field */ 529 struct nfs4_stid st_stid;
538 struct list_head st_perfile; 530 struct list_head st_perfile;
539 struct list_head st_perstateowner; 531 struct list_head st_perstateowner;
540 struct list_head st_locks; 532 struct list_head st_locks;
541 struct nfs4_stateowner * st_stateowner; 533 struct nfs4_stateowner *st_stateowner;
542 struct nfs4_clnt_odstate * st_clnt_odstate; 534 struct nfs4_clnt_odstate *st_clnt_odstate;
543 unsigned char st_access_bmap; 535 unsigned char st_access_bmap;
544 unsigned char st_deny_bmap; 536 unsigned char st_deny_bmap;
545 struct nfs4_ol_stateid * st_openstp; 537 struct nfs4_ol_stateid *st_openstp;
538 struct rw_semaphore st_rwsem;
546}; 539};
547 540
548static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s) 541static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
@@ -561,6 +554,7 @@ struct nfs4_layout_stateid {
561 struct nfsd4_callback ls_recall; 554 struct nfsd4_callback ls_recall;
562 stateid_t ls_recall_sid; 555 stateid_t ls_recall_sid;
563 bool ls_recalled; 556 bool ls_recalled;
557 struct mutex ls_mutex;
564}; 558};
565 559
566static inline struct nfs4_layout_stateid *layoutstateid(struct nfs4_stid *s) 560static inline struct nfs4_layout_stateid *layoutstateid(struct nfs4_stid *s)
@@ -593,6 +587,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
593 struct kmem_cache *slab); 587 struct kmem_cache *slab);
594void nfs4_unhash_stid(struct nfs4_stid *s); 588void nfs4_unhash_stid(struct nfs4_stid *s);
595void nfs4_put_stid(struct nfs4_stid *s); 589void nfs4_put_stid(struct nfs4_stid *s);
590void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
596void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *); 591void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *);
597extern void nfs4_release_reclaim(struct nfsd_net *); 592extern void nfs4_release_reclaim(struct nfsd_net *);
598extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, 593extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
diff --git a/fs/nfsd/trace.c b/fs/nfsd/trace.c
index 82f89070594c..90967466a1e5 100644
--- a/fs/nfsd/trace.c
+++ b/fs/nfsd/trace.c
@@ -1,5 +1,3 @@
1 1
2#include "state.h"
3
4#define CREATE_TRACE_POINTS 2#define CREATE_TRACE_POINTS
5#include "trace.h" 3#include "trace.h"
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index c668520c344b..0befe762762b 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -9,6 +9,8 @@
9 9
10#include <linux/tracepoint.h> 10#include <linux/tracepoint.h>
11 11
12#include "state.h"
13
12DECLARE_EVENT_CLASS(nfsd_stateid_class, 14DECLARE_EVENT_CLASS(nfsd_stateid_class,
13 TP_PROTO(stateid_t *stp), 15 TP_PROTO(stateid_t *stp),
14 TP_ARGS(stp), 16 TP_ARGS(stp),
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 45c04979e7b3..994d66fbb446 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1631,7 +1631,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1631 /* cannot use fh_lock as we need deadlock protective ordering 1631 /* cannot use fh_lock as we need deadlock protective ordering
1632 * so do it by hand */ 1632 * so do it by hand */
1633 trap = lock_rename(tdentry, fdentry); 1633 trap = lock_rename(tdentry, fdentry);
1634 ffhp->fh_locked = tfhp->fh_locked = 1; 1634 ffhp->fh_locked = tfhp->fh_locked = true;
1635 fill_pre_wcc(ffhp); 1635 fill_pre_wcc(ffhp);
1636 fill_pre_wcc(tfhp); 1636 fill_pre_wcc(tfhp);
1637 1637
@@ -1681,7 +1681,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1681 fill_post_wcc(ffhp); 1681 fill_post_wcc(ffhp);
1682 fill_post_wcc(tfhp); 1682 fill_post_wcc(tfhp);
1683 unlock_rename(tdentry, fdentry); 1683 unlock_rename(tdentry, fdentry);
1684 ffhp->fh_locked = tfhp->fh_locked = 0; 1684 ffhp->fh_locked = tfhp->fh_locked = false;
1685 fh_drop_write(ffhp); 1685 fh_drop_write(ffhp);
1686 1686
1687out: 1687out:
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index fee2451ae248..fcfc48cbe136 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -112,14 +112,14 @@ static inline int fh_want_write(struct svc_fh *fh)
112 int ret = mnt_want_write(fh->fh_export->ex_path.mnt); 112 int ret = mnt_want_write(fh->fh_export->ex_path.mnt);
113 113
114 if (!ret) 114 if (!ret)
115 fh->fh_want_write = 1; 115 fh->fh_want_write = true;
116 return ret; 116 return ret;
117} 117}
118 118
119static inline void fh_drop_write(struct svc_fh *fh) 119static inline void fh_drop_write(struct svc_fh *fh)
120{ 120{
121 if (fh->fh_want_write) { 121 if (fh->fh_want_write) {
122 fh->fh_want_write = 0; 122 fh->fh_want_write = false;
123 mnt_drop_write(fh->fh_export->ex_path.mnt); 123 mnt_drop_write(fh->fh_export->ex_path.mnt);
124 } 124 }
125} 125}
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 9f991007a578..ce7362c88b48 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -632,7 +632,7 @@ static inline void
632set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) 632set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
633{ 633{
634 BUG_ON(!fhp->fh_pre_saved); 634 BUG_ON(!fhp->fh_pre_saved);
635 cinfo->atomic = fhp->fh_post_saved; 635 cinfo->atomic = (u32)fhp->fh_post_saved;
636 cinfo->change_supported = IS_I_VERSION(d_inode(fhp->fh_dentry)); 636 cinfo->change_supported = IS_I_VERSION(d_inode(fhp->fh_dentry));
637 637
638 cinfo->before_change = fhp->fh_pre_change; 638 cinfo->before_change = fhp->fh_pre_change;
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index ff82a32871b5..c15373894a42 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -68,6 +68,7 @@ struct nlm_host {
68 struct nsm_handle *h_nsmhandle; /* NSM status handle */ 68 struct nsm_handle *h_nsmhandle; /* NSM status handle */
69 char *h_addrbuf; /* address eyecatcher */ 69 char *h_addrbuf; /* address eyecatcher */
70 struct net *net; /* host net */ 70 struct net *net; /* host net */
71 char nodename[UNX_MAXNODENAME + 1];
71}; 72};
72 73
73/* 74/*
@@ -235,7 +236,8 @@ void nlm_rebind_host(struct nlm_host *);
235struct nlm_host * nlm_get_host(struct nlm_host *); 236struct nlm_host * nlm_get_host(struct nlm_host *);
236void nlm_shutdown_hosts(void); 237void nlm_shutdown_hosts(void);
237void nlm_shutdown_hosts_net(struct net *net); 238void nlm_shutdown_hosts_net(struct net *net);
238void nlm_host_rebooted(const struct nlm_reboot *); 239void nlm_host_rebooted(const struct net *net,
240 const struct nlm_reboot *);
239 241
240/* 242/*
241 * Host monitoring 243 * Host monitoring
@@ -243,11 +245,13 @@ void nlm_host_rebooted(const struct nlm_reboot *);
243int nsm_monitor(const struct nlm_host *host); 245int nsm_monitor(const struct nlm_host *host);
244void nsm_unmonitor(const struct nlm_host *host); 246void nsm_unmonitor(const struct nlm_host *host);
245 247
246struct nsm_handle *nsm_get_handle(const struct sockaddr *sap, 248struct nsm_handle *nsm_get_handle(const struct net *net,
249 const struct sockaddr *sap,
247 const size_t salen, 250 const size_t salen,
248 const char *hostname, 251 const char *hostname,
249 const size_t hostname_len); 252 const size_t hostname_len);
250struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info); 253struct nsm_handle *nsm_reboot_lookup(const struct net *net,
254 const struct nlm_reboot *info);
251void nsm_release(struct nsm_handle *nsm); 255void nsm_release(struct nsm_handle *nsm);
252 256
253/* 257/*
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 03d3b4c92d9f..ed03c9f7f908 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -48,8 +48,10 @@
48struct cache_head { 48struct cache_head {
49 struct hlist_node cache_list; 49 struct hlist_node cache_list;
50 time_t expiry_time; /* After time time, don't use the data */ 50 time_t expiry_time; /* After time time, don't use the data */
51 time_t last_refresh; /* If CACHE_PENDING, this is when upcall 51 time_t last_refresh; /* If CACHE_PENDING, this is when upcall was
52 * was sent, else this is when update was received 52 * sent, else this is when update was
53 * received, though it is alway set to
54 * be *after* ->flush_time.
53 */ 55 */
54 struct kref ref; 56 struct kref ref;
55 unsigned long flags; 57 unsigned long flags;
@@ -105,8 +107,12 @@ struct cache_detail {
105 /* fields below this comment are for internal use 107 /* fields below this comment are for internal use
106 * and should not be touched by cache owners 108 * and should not be touched by cache owners
107 */ 109 */
108 time_t flush_time; /* flush all cache items with last_refresh 110 time_t flush_time; /* flush all cache items with
109 * earlier than this */ 111 * last_refresh at or earlier
112 * than this. last_refresh
113 * is never set at or earlier
114 * than this.
115 */
110 struct list_head others; 116 struct list_head others;
111 time_t nextcheck; 117 time_t nextcheck;
112 int entries; 118 int entries;
@@ -203,7 +209,7 @@ static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
203static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) 209static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
204{ 210{
205 return (h->expiry_time < seconds_since_boot()) || 211 return (h->expiry_time < seconds_since_boot()) ||
206 (detail->flush_time > h->last_refresh); 212 (detail->flush_time >= h->last_refresh);
207} 213}
208 214
209extern int cache_check(struct cache_detail *detail, 215extern int cache_check(struct cache_detail *detail,
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index dace13d7638e..799e65b944b9 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1411,17 +1411,16 @@ gss_key_timeout(struct rpc_cred *rc)
1411{ 1411{
1412 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 1412 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
1413 struct gss_cl_ctx *ctx; 1413 struct gss_cl_ctx *ctx;
1414 unsigned long now = jiffies; 1414 unsigned long timeout = jiffies + (gss_key_expire_timeo * HZ);
1415 unsigned long expire; 1415 int ret = 0;
1416 1416
1417 rcu_read_lock(); 1417 rcu_read_lock();
1418 ctx = rcu_dereference(gss_cred->gc_ctx); 1418 ctx = rcu_dereference(gss_cred->gc_ctx);
1419 if (ctx) 1419 if (!ctx || time_after(timeout, ctx->gc_expiry))
1420 expire = ctx->gc_expiry - (gss_key_expire_timeo * HZ); 1420 ret = -EACCES;
1421 rcu_read_unlock(); 1421 rcu_read_unlock();
1422 if (!ctx || time_after(now, expire)) 1422
1423 return -EACCES; 1423 return ret;
1424 return 0;
1425} 1424}
1426 1425
1427static int 1426static int
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 4a2340a54401..5e4f815c2b34 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -41,13 +41,16 @@
41static bool cache_defer_req(struct cache_req *req, struct cache_head *item); 41static bool cache_defer_req(struct cache_req *req, struct cache_head *item);
42static void cache_revisit_request(struct cache_head *item); 42static void cache_revisit_request(struct cache_head *item);
43 43
44static void cache_init(struct cache_head *h) 44static void cache_init(struct cache_head *h, struct cache_detail *detail)
45{ 45{
46 time_t now = seconds_since_boot(); 46 time_t now = seconds_since_boot();
47 INIT_HLIST_NODE(&h->cache_list); 47 INIT_HLIST_NODE(&h->cache_list);
48 h->flags = 0; 48 h->flags = 0;
49 kref_init(&h->ref); 49 kref_init(&h->ref);
50 h->expiry_time = now + CACHE_NEW_EXPIRY; 50 h->expiry_time = now + CACHE_NEW_EXPIRY;
51 if (now <= detail->flush_time)
52 /* ensure it isn't already expired */
53 now = detail->flush_time + 1;
51 h->last_refresh = now; 54 h->last_refresh = now;
52} 55}
53 56
@@ -81,7 +84,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
81 * we might get lose if we need to 84 * we might get lose if we need to
82 * cache_put it soon. 85 * cache_put it soon.
83 */ 86 */
84 cache_init(new); 87 cache_init(new, detail);
85 detail->init(new, key); 88 detail->init(new, key);
86 89
87 write_lock(&detail->hash_lock); 90 write_lock(&detail->hash_lock);
@@ -116,10 +119,15 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
116 119
117static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch); 120static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
118 121
119static void cache_fresh_locked(struct cache_head *head, time_t expiry) 122static void cache_fresh_locked(struct cache_head *head, time_t expiry,
123 struct cache_detail *detail)
120{ 124{
125 time_t now = seconds_since_boot();
126 if (now <= detail->flush_time)
127 /* ensure it isn't immediately treated as expired */
128 now = detail->flush_time + 1;
121 head->expiry_time = expiry; 129 head->expiry_time = expiry;
122 head->last_refresh = seconds_since_boot(); 130 head->last_refresh = now;
123 smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */ 131 smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */
124 set_bit(CACHE_VALID, &head->flags); 132 set_bit(CACHE_VALID, &head->flags);
125} 133}
@@ -149,7 +157,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
149 set_bit(CACHE_NEGATIVE, &old->flags); 157 set_bit(CACHE_NEGATIVE, &old->flags);
150 else 158 else
151 detail->update(old, new); 159 detail->update(old, new);
152 cache_fresh_locked(old, new->expiry_time); 160 cache_fresh_locked(old, new->expiry_time, detail);
153 write_unlock(&detail->hash_lock); 161 write_unlock(&detail->hash_lock);
154 cache_fresh_unlocked(old, detail); 162 cache_fresh_unlocked(old, detail);
155 return old; 163 return old;
@@ -162,7 +170,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
162 cache_put(old, detail); 170 cache_put(old, detail);
163 return NULL; 171 return NULL;
164 } 172 }
165 cache_init(tmp); 173 cache_init(tmp, detail);
166 detail->init(tmp, old); 174 detail->init(tmp, old);
167 175
168 write_lock(&detail->hash_lock); 176 write_lock(&detail->hash_lock);
@@ -173,8 +181,8 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
173 hlist_add_head(&tmp->cache_list, &detail->hash_table[hash]); 181 hlist_add_head(&tmp->cache_list, &detail->hash_table[hash]);
174 detail->entries++; 182 detail->entries++;
175 cache_get(tmp); 183 cache_get(tmp);
176 cache_fresh_locked(tmp, new->expiry_time); 184 cache_fresh_locked(tmp, new->expiry_time, detail);
177 cache_fresh_locked(old, 0); 185 cache_fresh_locked(old, 0, detail);
178 write_unlock(&detail->hash_lock); 186 write_unlock(&detail->hash_lock);
179 cache_fresh_unlocked(tmp, detail); 187 cache_fresh_unlocked(tmp, detail);
180 cache_fresh_unlocked(old, detail); 188 cache_fresh_unlocked(old, detail);
@@ -219,7 +227,8 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h
219 rv = cache_is_valid(h); 227 rv = cache_is_valid(h);
220 if (rv == -EAGAIN) { 228 if (rv == -EAGAIN) {
221 set_bit(CACHE_NEGATIVE, &h->flags); 229 set_bit(CACHE_NEGATIVE, &h->flags);
222 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); 230 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY,
231 detail);
223 rv = -ENOENT; 232 rv = -ENOENT;
224 } 233 }
225 write_unlock(&detail->hash_lock); 234 write_unlock(&detail->hash_lock);
@@ -487,10 +496,13 @@ EXPORT_SYMBOL_GPL(cache_flush);
487 496
488void cache_purge(struct cache_detail *detail) 497void cache_purge(struct cache_detail *detail)
489{ 498{
490 detail->flush_time = LONG_MAX; 499 time_t now = seconds_since_boot();
500 if (detail->flush_time >= now)
501 now = detail->flush_time + 1;
502 /* 'now' is the maximum value any 'last_refresh' can have */
503 detail->flush_time = now;
491 detail->nextcheck = seconds_since_boot(); 504 detail->nextcheck = seconds_since_boot();
492 cache_flush(); 505 cache_flush();
493 detail->flush_time = 1;
494} 506}
495EXPORT_SYMBOL_GPL(cache_purge); 507EXPORT_SYMBOL_GPL(cache_purge);
496 508
@@ -1436,6 +1448,7 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
1436{ 1448{
1437 char tbuf[20]; 1449 char tbuf[20];
1438 char *bp, *ep; 1450 char *bp, *ep;
1451 time_t then, now;
1439 1452
1440 if (*ppos || count > sizeof(tbuf)-1) 1453 if (*ppos || count > sizeof(tbuf)-1)
1441 return -EINVAL; 1454 return -EINVAL;
@@ -1447,8 +1460,22 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
1447 return -EINVAL; 1460 return -EINVAL;
1448 1461
1449 bp = tbuf; 1462 bp = tbuf;
1450 cd->flush_time = get_expiry(&bp); 1463 then = get_expiry(&bp);
1451 cd->nextcheck = seconds_since_boot(); 1464 now = seconds_since_boot();
1465 cd->nextcheck = now;
1466 /* Can only set flush_time to 1 second beyond "now", or
1467 * possibly 1 second beyond flushtime. This is because
1468 * flush_time never goes backwards so it mustn't get too far
1469 * ahead of time.
1470 */
1471 if (then >= now) {
1472 /* Want to flush everything, so behave like cache_purge() */
1473 if (cd->flush_time >= now)
1474 now = cd->flush_time + 1;
1475 then = now;
1476 }
1477
1478 cd->flush_time = then;
1452 cache_flush(); 1479 cache_flush();
1453 1480
1454 *ppos += count; 1481 *ppos += count;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 0c8120229a03..1413cdcc131c 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -181,7 +181,7 @@ int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
181 struct page **ppage = xdr->pages; 181 struct page **ppage = xdr->pages;
182 size_t base = xdr->page_base; 182 size_t base = xdr->page_base;
183 unsigned int pglen = xdr->page_len; 183 unsigned int pglen = xdr->page_len;
184 unsigned int flags = MSG_MORE; 184 unsigned int flags = MSG_MORE | MSG_SENDPAGE_NOTLAST;
185 int slen; 185 int slen;
186 int len = 0; 186 int len = 0;
187 187
@@ -399,6 +399,31 @@ static int svc_sock_secure_port(struct svc_rqst *rqstp)
399 return svc_port_is_privileged(svc_addr(rqstp)); 399 return svc_port_is_privileged(svc_addr(rqstp));
400} 400}
401 401
402static bool sunrpc_waitqueue_active(wait_queue_head_t *wq)
403{
404 if (!wq)
405 return false;
406 /*
407 * There should normally be a memory * barrier here--see
408 * wq_has_sleeper().
409 *
410 * It appears that isn't currently necessary, though, basically
411 * because callers all appear to have sufficient memory barriers
412 * between the time the relevant change is made and the
413 * time they call these callbacks.
414 *
415 * The nfsd code itself doesn't actually explicitly wait on
416 * these waitqueues, but it may wait on them for example in
417 * sendpage() or sendmsg() calls. (And those may be the only
418 * places, since it it uses nonblocking reads.)
419 *
420 * Maybe we should add the memory barriers anyway, but these are
421 * hot paths so we'd need to be convinced there's no sigificant
422 * penalty.
423 */
424 return waitqueue_active(wq);
425}
426
402/* 427/*
403 * INET callback when data has been received on the socket. 428 * INET callback when data has been received on the socket.
404 */ 429 */
@@ -414,7 +439,7 @@ static void svc_udp_data_ready(struct sock *sk)
414 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 439 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
415 svc_xprt_enqueue(&svsk->sk_xprt); 440 svc_xprt_enqueue(&svsk->sk_xprt);
416 } 441 }
417 if (wq && waitqueue_active(wq)) 442 if (sunrpc_waitqueue_active(wq))
418 wake_up_interruptible(wq); 443 wake_up_interruptible(wq);
419} 444}
420 445
@@ -432,7 +457,7 @@ static void svc_write_space(struct sock *sk)
432 svc_xprt_enqueue(&svsk->sk_xprt); 457 svc_xprt_enqueue(&svsk->sk_xprt);
433 } 458 }
434 459
435 if (wq && waitqueue_active(wq)) { 460 if (sunrpc_waitqueue_active(wq)) {
436 dprintk("RPC svc_write_space: someone sleeping on %p\n", 461 dprintk("RPC svc_write_space: someone sleeping on %p\n",
437 svsk); 462 svsk);
438 wake_up_interruptible(wq); 463 wake_up_interruptible(wq);
@@ -787,7 +812,7 @@ static void svc_tcp_listen_data_ready(struct sock *sk)
787 } 812 }
788 813
789 wq = sk_sleep(sk); 814 wq = sk_sleep(sk);
790 if (wq && waitqueue_active(wq)) 815 if (sunrpc_waitqueue_active(wq))
791 wake_up_interruptible_all(wq); 816 wake_up_interruptible_all(wq);
792} 817}
793 818
@@ -808,7 +833,7 @@ static void svc_tcp_state_change(struct sock *sk)
808 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 833 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
809 svc_xprt_enqueue(&svsk->sk_xprt); 834 svc_xprt_enqueue(&svsk->sk_xprt);
810 } 835 }
811 if (wq && waitqueue_active(wq)) 836 if (sunrpc_waitqueue_active(wq))
812 wake_up_interruptible_all(wq); 837 wake_up_interruptible_all(wq);
813} 838}
814 839
@@ -823,7 +848,7 @@ static void svc_tcp_data_ready(struct sock *sk)
823 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 848 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
824 svc_xprt_enqueue(&svsk->sk_xprt); 849 svc_xprt_enqueue(&svsk->sk_xprt);
825 } 850 }
826 if (wq && waitqueue_active(wq)) 851 if (sunrpc_waitqueue_active(wq))
827 wake_up_interruptible(wq); 852 wake_up_interruptible(wq);
828} 853}
829 854
@@ -1367,7 +1392,6 @@ EXPORT_SYMBOL_GPL(svc_sock_update_bufs);
1367 1392
1368/* 1393/*
1369 * Initialize socket for RPC use and create svc_sock struct 1394 * Initialize socket for RPC use and create svc_sock struct
1370 * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF.
1371 */ 1395 */
1372static struct svc_sock *svc_setup_socket(struct svc_serv *serv, 1396static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1373 struct socket *sock, 1397 struct socket *sock,
@@ -1594,7 +1618,7 @@ static void svc_sock_detach(struct svc_xprt *xprt)
1594 sk->sk_write_space = svsk->sk_owspace; 1618 sk->sk_write_space = svsk->sk_owspace;
1595 1619
1596 wq = sk_sleep(sk); 1620 wq = sk_sleep(sk);
1597 if (wq && waitqueue_active(wq)) 1621 if (sunrpc_waitqueue_active(wq))
1598 wake_up_interruptible(wq); 1622 wake_up_interruptible(wq);
1599} 1623}
1600 1624