Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+414 -286
+5 -3
fs/lockd/host.c
··· 116 116 atomic_inc(&nsm->sm_count); 117 117 else { 118 118 host = NULL; 119 - nsm = nsm_get_handle(ni->sap, ni->salen, 119 + nsm = nsm_get_handle(ni->net, ni->sap, ni->salen, 120 120 ni->hostname, ni->hostname_len); 121 121 if (unlikely(nsm == NULL)) { 122 122 dprintk("lockd: %s failed; no nsm handle\n", ··· 161 161 host->h_nsmhandle = nsm; 162 162 host->h_addrbuf = nsm->sm_addrbuf; 163 163 host->net = ni->net; 164 + strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename)); 164 165 165 166 out: 166 167 return host; ··· 535 534 536 535 /** 537 536 * nlm_host_rebooted - Release all resources held by rebooted host 537 + * @net: network namespace 538 538 * @info: pointer to decoded results of NLM_SM_NOTIFY call 539 539 * 540 540 * We were notified that the specified host has rebooted. Release 541 541 * all resources held by that peer. 542 542 */ 543 - void nlm_host_rebooted(const struct nlm_reboot *info) 543 + void nlm_host_rebooted(const struct net *net, const struct nlm_reboot *info) 544 544 { 545 545 struct nsm_handle *nsm; 546 546 struct nlm_host *host; 547 547 548 - nsm = nsm_reboot_lookup(info); 548 + nsm = nsm_reboot_lookup(net, info); 549 549 if (unlikely(nsm == NULL)) 550 550 return; 551 551
+37 -88
fs/lockd/mon.c
··· 42 42 u32 proc; 43 43 44 44 char *mon_name; 45 - char *nodename; 45 + const char *nodename; 46 46 }; 47 47 48 48 struct nsm_res { ··· 51 51 }; 52 52 53 53 static const struct rpc_program nsm_program; 54 - static LIST_HEAD(nsm_handles); 55 54 static DEFINE_SPINLOCK(nsm_lock); 56 55 57 56 /* ··· 86 87 return rpc_create(&args); 87 88 } 88 89 89 - static struct rpc_clnt *nsm_client_set(struct lockd_net *ln, 90 - struct rpc_clnt *clnt) 91 - { 92 - spin_lock(&ln->nsm_clnt_lock); 93 - if (ln->nsm_users == 0) { 94 - if (clnt == NULL) 95 - goto out; 96 - ln->nsm_clnt = clnt; 97 - } 98 - clnt = ln->nsm_clnt; 99 - ln->nsm_users++; 100 - out: 101 - spin_unlock(&ln->nsm_clnt_lock); 102 - return clnt; 103 - } 104 - 105 - static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename) 106 - { 107 - struct rpc_clnt *clnt, *new; 108 - struct lockd_net *ln = net_generic(net, lockd_net_id); 109 - 110 - clnt = nsm_client_set(ln, NULL); 111 - if (clnt != NULL) 112 - goto out; 113 - 114 - clnt = new = nsm_create(net, nodename); 115 - if (IS_ERR(clnt)) 116 - goto out; 117 - 118 - clnt = nsm_client_set(ln, new); 119 - if (clnt != new) 120 - rpc_shutdown_client(new); 121 - out: 122 - return clnt; 123 - } 124 - 125 - static void nsm_client_put(struct net *net) 126 - { 127 - struct lockd_net *ln = net_generic(net, lockd_net_id); 128 - struct rpc_clnt *clnt = NULL; 129 - 130 - spin_lock(&ln->nsm_clnt_lock); 131 - ln->nsm_users--; 132 - if (ln->nsm_users == 0) { 133 - clnt = ln->nsm_clnt; 134 - ln->nsm_clnt = NULL; 135 - } 136 - spin_unlock(&ln->nsm_clnt_lock); 137 - if (clnt != NULL) 138 - rpc_shutdown_client(clnt); 139 - } 140 - 141 90 static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, 142 - struct rpc_clnt *clnt) 91 + const struct nlm_host *host) 143 92 { 144 93 int status; 94 + struct rpc_clnt *clnt; 145 95 struct nsm_args args = { 146 96 .priv = &nsm->sm_priv, 147 97 .prog = NLM_PROGRAM, 148 98 .vers = 3, 149 99 .proc = NLMPROC_NSM_NOTIFY, 150 100 .mon_name = nsm->sm_mon_name, 151 - .nodename = clnt->cl_nodename, 101 + .nodename = host->nodename, 152 102 }; 153 103 struct rpc_message msg = { 154 104 .rpc_argp = &args, ··· 105 157 }; 106 158 107 159 memset(res, 0, sizeof(*res)); 160 + 161 + clnt = nsm_create(host->net, host->nodename); 162 + if (IS_ERR(clnt)) { 163 + dprintk("lockd: failed to create NSM upcall transport, " 164 + "status=%ld, net=%p\n", PTR_ERR(clnt), host->net); 165 + return PTR_ERR(clnt); 166 + } 108 167 109 168 msg.rpc_proc = &clnt->cl_procinfo[proc]; 110 169 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN); ··· 126 171 status); 127 172 else 128 173 status = 0; 174 + 175 + rpc_shutdown_client(clnt); 129 176 return status; 130 177 } 131 178 ··· 147 190 struct nsm_handle *nsm = host->h_nsmhandle; 148 191 struct nsm_res res; 149 192 int status; 150 - struct rpc_clnt *clnt; 151 - const char *nodename = NULL; 152 193 153 194 dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); 154 195 155 196 if (nsm->sm_monitored) 156 197 return 0; 157 - 158 - if (host->h_rpcclnt) 159 - nodename = host->h_rpcclnt->cl_nodename; 160 198 161 199 /* 162 200 * Choose whether to record the caller_name or IP address of ··· 159 207 */ 160 208 nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; 161 209 162 - clnt = nsm_client_get(host->net, nodename); 163 - if (IS_ERR(clnt)) { 164 - status = PTR_ERR(clnt); 165 - dprintk("lockd: failed to create NSM upcall transport, " 166 - "status=%d, net=%p\n", status, host->net); 167 - return status; 168 - } 169 - 170 - status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt); 210 + status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host); 171 211 if (unlikely(res.status != 0)) 172 212 status = -EIO; 173 213 if (unlikely(status < 0)) { ··· 191 247 192 248 if (atomic_read(&nsm->sm_count) == 1 193 249 && nsm->sm_monitored && !nsm->sm_sticky) { 194 - struct lockd_net *ln = net_generic(host->net, lockd_net_id); 195 - 196 250 dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); 197 251 198 - status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt); 252 + status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host); 199 253 if (res.status != 0) 200 254 status = -EIO; 201 255 if (status < 0) ··· 201 259 nsm->sm_name); 202 260 else 203 261 nsm->sm_monitored = 0; 204 - 205 - nsm_client_put(host->net); 206 262 } 207 263 } 208 264 209 - static struct nsm_handle *nsm_lookup_hostname(const char *hostname, 210 - const size_t len) 265 + static struct nsm_handle *nsm_lookup_hostname(const struct list_head *nsm_handles, 266 + const char *hostname, const size_t len) 211 267 { 212 268 struct nsm_handle *nsm; 213 269 214 - list_for_each_entry(nsm, &nsm_handles, sm_link) 270 + list_for_each_entry(nsm, nsm_handles, sm_link) 215 271 if (strlen(nsm->sm_name) == len && 216 272 memcmp(nsm->sm_name, hostname, len) == 0) 217 273 return nsm; 218 274 return NULL; 219 275 } 220 276 221 - static struct nsm_handle *nsm_lookup_addr(const struct sockaddr *sap) 277 + static struct nsm_handle *nsm_lookup_addr(const struct list_head *nsm_handles, 278 + const struct sockaddr *sap) 222 279 { 223 280 struct nsm_handle *nsm; 224 281 225 - list_for_each_entry(nsm, &nsm_handles, sm_link) 282 + list_for_each_entry(nsm, nsm_handles, sm_link) 226 283 if (rpc_cmp_addr(nsm_addr(nsm), sap)) 227 284 return nsm; 228 285 return NULL; 229 286 } 230 287 231 - static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv) 288 + static struct nsm_handle *nsm_lookup_priv(const struct list_head *nsm_handles, 289 + const struct nsm_private *priv) 232 290 { 233 291 struct nsm_handle *nsm; 234 292 235 - list_for_each_entry(nsm, &nsm_handles, sm_link) 293 + list_for_each_entry(nsm, nsm_handles, sm_link) 236 294 if (memcmp(nsm->sm_priv.data, priv->data, 237 295 sizeof(priv->data)) == 0) 238 296 return nsm; ··· 295 353 296 354 /** 297 355 * nsm_get_handle - Find or create a cached nsm_handle 356 + * @net: network namespace 298 357 * @sap: pointer to socket address of handle to find 299 358 * @salen: length of socket address 300 359 * @hostname: pointer to C string containing hostname to find ··· 308 365 * @hostname cannot be found in the handle cache. Returns NULL if 309 366 * an error occurs. 310 367 */ 311 - struct nsm_handle *nsm_get_handle(const struct sockaddr *sap, 368 + struct nsm_handle *nsm_get_handle(const struct net *net, 369 + const struct sockaddr *sap, 312 370 const size_t salen, const char *hostname, 313 371 const size_t hostname_len) 314 372 { 315 373 struct nsm_handle *cached, *new = NULL; 374 + struct lockd_net *ln = net_generic(net, lockd_net_id); 316 375 317 376 if (hostname && memchr(hostname, '/', hostname_len) != NULL) { 318 377 if (printk_ratelimit()) { ··· 329 384 spin_lock(&nsm_lock); 330 385 331 386 if (nsm_use_hostnames && hostname != NULL) 332 - cached = nsm_lookup_hostname(hostname, hostname_len); 387 + cached = nsm_lookup_hostname(&ln->nsm_handles, 388 + hostname, hostname_len); 333 389 else 334 - cached = nsm_lookup_addr(sap); 390 + cached = nsm_lookup_addr(&ln->nsm_handles, sap); 335 391 336 392 if (cached != NULL) { 337 393 atomic_inc(&cached->sm_count); ··· 346 400 } 347 401 348 402 if (new != NULL) { 349 - list_add(&new->sm_link, &nsm_handles); 403 + list_add(&new->sm_link, &ln->nsm_handles); 350 404 spin_unlock(&nsm_lock); 351 405 dprintk("lockd: created nsm_handle for %s (%s)\n", 352 406 new->sm_name, new->sm_addrbuf); ··· 363 417 364 418 /** 365 419 * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle 420 + * @net: network namespace 366 421 * @info: pointer to NLMPROC_SM_NOTIFY arguments 367 422 * 368 423 * Returns a matching nsm_handle if found in the nsm cache. The returned 369 424 * nsm_handle's reference count is bumped. Otherwise returns NULL if some 370 425 * error occurred. 371 426 */ 372 - struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info) 427 + struct nsm_handle *nsm_reboot_lookup(const struct net *net, 428 + const struct nlm_reboot *info) 373 429 { 374 430 struct nsm_handle *cached; 431 + struct lockd_net *ln = net_generic(net, lockd_net_id); 375 432 376 433 spin_lock(&nsm_lock); 377 434 378 - cached = nsm_lookup_priv(&info->priv); 435 + cached = nsm_lookup_priv(&ln->nsm_handles, &info->priv); 379 436 if (unlikely(cached == NULL)) { 380 437 spin_unlock(&nsm_lock); 381 438 dprintk("lockd: never saw rebooted peer '%.*s' before\n",
+1 -3
fs/lockd/netns.h
··· 12 12 struct delayed_work grace_period_end; 13 13 struct lock_manager lockd_manager; 14 14 15 - spinlock_t nsm_clnt_lock; 16 - unsigned int nsm_users; 17 - struct rpc_clnt *nsm_clnt; 15 + struct list_head nsm_handles; 18 16 }; 19 17 20 18 extern int lockd_net_id;
+1 -1
fs/lockd/svc.c
··· 592 592 INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); 593 593 INIT_LIST_HEAD(&ln->lockd_manager.list); 594 594 ln->lockd_manager.block_opens = false; 595 - spin_lock_init(&ln->nsm_clnt_lock); 595 + INIT_LIST_HEAD(&ln->nsm_handles); 596 596 return 0; 597 597 } 598 598
+1 -1
fs/lockd/svc4proc.c
··· 421 421 return rpc_system_err; 422 422 } 423 423 424 - nlm_host_rebooted(argp); 424 + nlm_host_rebooted(SVC_NET(rqstp), argp); 425 425 return rpc_success; 426 426 } 427 427
+1 -1
fs/lockd/svcproc.c
··· 464 464 return rpc_system_err; 465 465 } 466 466 467 - nlm_host_rebooted(argp); 467 + nlm_host_rebooted(SVC_NET(rqstp), argp); 468 468 return rpc_success; 469 469 } 470 470
+2 -2
fs/nfsd/nfs3xdr.c
··· 262 262 err = fh_getattr(fhp, &fhp->fh_post_attr); 263 263 fhp->fh_post_change = d_inode(fhp->fh_dentry)->i_version; 264 264 if (err) { 265 - fhp->fh_post_saved = 0; 265 + fhp->fh_post_saved = false; 266 266 /* Grab the ctime anyway - set_change_info might use it */ 267 267 fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime; 268 268 } else 269 - fhp->fh_post_saved = 1; 269 + fhp->fh_post_saved = true; 270 270 } 271 271 272 272 /*
+23 -11
fs/nfsd/nfs4layouts.c
··· 201 201 INIT_LIST_HEAD(&ls->ls_perfile); 202 202 spin_lock_init(&ls->ls_lock); 203 203 INIT_LIST_HEAD(&ls->ls_layouts); 204 + mutex_init(&ls->ls_mutex); 204 205 ls->ls_layout_type = layout_type; 205 206 nfsd4_init_cb(&ls->ls_recall, clp, &nfsd4_cb_layout_ops, 206 207 NFSPROC4_CLNT_CB_LAYOUT); ··· 263 262 status = nfserr_jukebox; 264 263 if (!ls) 265 264 goto out; 265 + mutex_lock(&ls->ls_mutex); 266 266 } else { 267 267 ls = container_of(stid, struct nfs4_layout_stateid, ls_stid); 268 268 269 269 status = nfserr_bad_stateid; 270 + mutex_lock(&ls->ls_mutex); 270 271 if (stateid->si_generation > stid->sc_stateid.si_generation) 271 - goto out_put_stid; 272 + goto out_unlock_stid; 272 273 if (layout_type != ls->ls_layout_type) 273 - goto out_put_stid; 274 + goto out_unlock_stid; 274 275 } 275 276 276 277 *lsp = ls; 277 278 return 0; 278 279 280 + out_unlock_stid: 281 + mutex_unlock(&ls->ls_mutex); 279 282 out_put_stid: 280 283 nfs4_put_stid(stid); 281 284 out: ··· 301 296 trace_layout_recall(&ls->ls_stid.sc_stateid); 302 297 303 298 atomic_inc(&ls->ls_stid.sc_count); 304 - update_stateid(&ls->ls_stid.sc_stateid); 305 - memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t)); 306 299 nfsd4_run_cb(&ls->ls_recall); 307 300 308 301 out_unlock: ··· 409 406 list_add_tail(&new->lo_perstate, &ls->ls_layouts); 410 407 new = NULL; 411 408 done: 412 - update_stateid(&ls->ls_stid.sc_stateid); 413 - memcpy(&lgp->lg_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t)); 409 + nfs4_inc_and_copy_stateid(&lgp->lg_sid, &ls->ls_stid); 414 410 spin_unlock(&ls->ls_lock); 415 411 out: 416 412 spin_unlock(&fp->fi_lock); ··· 483 481 } 484 482 } 485 483 if (!list_empty(&ls->ls_layouts)) { 486 - if (found) { 487 - update_stateid(&ls->ls_stid.sc_stateid); 488 - memcpy(&lrp->lr_sid, &ls->ls_stid.sc_stateid, 489 - sizeof(stateid_t)); 490 - } 484 + if (found) 485 + nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid); 491 486 lrp->lrs_present = 1; 492 487 } else { 493 488 trace_layoutstate_unhash(&ls->ls_stid.sc_stateid); ··· 493 494 } 494 495 spin_unlock(&ls->ls_lock); 495 496 497 + mutex_unlock(&ls->ls_mutex); 496 498 nfs4_put_stid(&ls->ls_stid); 497 499 nfsd4_free_layouts(&reaplist); 498 500 return nfs_ok; ··· 608 608 } 609 609 } 610 610 611 + static void 612 + nfsd4_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 + 611 621 static int 612 622 nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task) 613 623 { ··· 659 649 660 650 trace_layout_recall_release(&ls->ls_stid.sc_stateid); 661 651 652 + mutex_unlock(&ls->ls_mutex); 662 653 nfsd4_return_all_layouts(ls, &reaplist); 663 654 nfsd4_free_layouts(&reaplist); 664 655 nfs4_put_stid(&ls->ls_stid); 665 656 } 666 657 667 658 static struct nfsd4_callback_ops nfsd4_cb_layout_ops = { 659 + .prepare = nfsd4_cb_layout_prepare, 668 660 .done = nfsd4_cb_layout_done, 669 661 .release = nfsd4_cb_layout_release, 670 662 };
+4
fs/nfsd/nfs4proc.c
··· 1309 1309 nfserr = nfsd4_insert_layout(lgp, ls); 1310 1310 1311 1311 out_put_stid: 1312 + mutex_unlock(&ls->ls_mutex); 1312 1313 nfs4_put_stid(&ls->ls_stid); 1313 1314 out: 1314 1315 return nfserr; ··· 1362 1361 nfserr = nfserr_badlayout; 1363 1362 goto out; 1364 1363 } 1364 + 1365 + /* LAYOUTCOMMIT does not require any serialization */ 1366 + mutex_unlock(&ls->ls_mutex); 1365 1367 1366 1368 if (new_size > i_size_read(inode)) { 1367 1369 lcp->lc_size_chg = 1;
+204 -65
fs/nfsd/nfs4state.c
··· 575 575 stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid; 576 576 /* Will be incremented before return to client: */ 577 577 atomic_set(&stid->sc_count, 1); 578 + spin_lock_init(&stid->sc_lock); 578 579 579 580 /* 580 581 * It shouldn't be a problem to reuse an opaque stateid value. ··· 746 745 put_nfs4_file(fp); 747 746 } 748 747 748 + void 749 + nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid) 750 + { 751 + stateid_t *src = &stid->sc_stateid; 752 + 753 + spin_lock(&stid->sc_lock); 754 + if (unlikely(++src->si_generation == 0)) 755 + src->si_generation = 1; 756 + memcpy(dst, src, sizeof(*dst)); 757 + spin_unlock(&stid->sc_lock); 758 + } 759 + 749 760 static void nfs4_put_deleg_lease(struct nfs4_file *fp) 750 761 { 751 762 struct file *filp = NULL; ··· 778 765 s->sc_type = 0; 779 766 } 780 767 781 - static void 782 - hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp) 768 + /** 769 + * nfs4_get_existing_delegation - Discover if this delegation already exists 770 + * @clp: a pointer to the nfs4_client we're granting a delegation to 771 + * @fp: a pointer to the nfs4_file we're granting a delegation on 772 + * 773 + * Return: 774 + * On success: NULL if an existing delegation was not found. 775 + * 776 + * On error: -EAGAIN if one was previously granted to this nfs4_client 777 + * for this nfs4_file. 778 + * 779 + */ 780 + 781 + static int 782 + nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp) 783 783 { 784 + struct nfs4_delegation *searchdp = NULL; 785 + struct nfs4_client *searchclp = NULL; 786 + 784 787 lockdep_assert_held(&state_lock); 785 788 lockdep_assert_held(&fp->fi_lock); 786 789 790 + list_for_each_entry(searchdp, &fp->fi_delegations, dl_perfile) { 791 + searchclp = searchdp->dl_stid.sc_client; 792 + if (clp == searchclp) { 793 + return -EAGAIN; 794 + } 795 + } 796 + return 0; 797 + } 798 + 799 + /** 800 + * hash_delegation_locked - Add a delegation to the appropriate lists 801 + * @dp: a pointer to the nfs4_delegation we are adding. 802 + * @fp: a pointer to the nfs4_file we're granting a delegation on 803 + * 804 + * Return: 805 + * On success: NULL if the delegation was successfully hashed. 806 + * 807 + * On error: -EAGAIN if one was previously granted to this 808 + * nfs4_client for this nfs4_file. Delegation is not hashed. 809 + * 810 + */ 811 + 812 + static int 813 + hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp) 814 + { 815 + int status; 816 + struct nfs4_client *clp = dp->dl_stid.sc_client; 817 + 818 + lockdep_assert_held(&state_lock); 819 + lockdep_assert_held(&fp->fi_lock); 820 + 821 + status = nfs4_get_existing_delegation(clp, fp); 822 + if (status) 823 + return status; 824 + ++fp->fi_delegees; 787 825 atomic_inc(&dp->dl_stid.sc_count); 788 826 dp->dl_stid.sc_type = NFS4_DELEG_STID; 789 827 list_add(&dp->dl_perfile, &fp->fi_delegations); 790 - list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); 828 + list_add(&dp->dl_perclnt, &clp->cl_delegations); 829 + return 0; 791 830 } 792 831 793 832 static bool ··· 2321 2256 clid->flags = new->cl_exchange_flags; 2322 2257 } 2323 2258 2259 + static bool client_has_openowners(struct nfs4_client *clp) 2260 + { 2261 + struct nfs4_openowner *oo; 2262 + 2263 + list_for_each_entry(oo, &clp->cl_openowners, oo_perclient) { 2264 + if (!list_empty(&oo->oo_owner.so_stateids)) 2265 + return true; 2266 + } 2267 + return false; 2268 + } 2269 + 2324 2270 static bool client_has_state(struct nfs4_client *clp) 2325 2271 { 2326 - /* 2327 - * Note clp->cl_openowners check isn't quite right: there's no 2328 - * need to count owners without stateid's. 2329 - * 2330 - * Also note we should probably be using this in 4.0 case too. 2331 - */ 2332 - return !list_empty(&clp->cl_openowners) 2272 + return client_has_openowners(clp) 2333 2273 #ifdef CONFIG_NFSD_PNFS 2334 2274 || !list_empty(&clp->cl_lo_states) 2335 2275 #endif ··· 3119 3049 /* Cases below refer to rfc 3530 section 14.2.33: */ 3120 3050 spin_lock(&nn->client_lock); 3121 3051 conf = find_confirmed_client_by_name(&clname, nn); 3122 - if (conf) { 3052 + if (conf && client_has_state(conf)) { 3123 3053 /* case 0: */ 3124 3054 status = nfserr_clid_inuse; 3125 3055 if (clp_used_exchangeid(conf)) ··· 3206 3136 } else { /* case 3: normal case; new or rebooted client */ 3207 3137 old = find_confirmed_client_by_name(&unconf->cl_name, nn); 3208 3138 if (old) { 3139 + status = nfserr_clid_inuse; 3140 + if (client_has_state(old) 3141 + && !same_creds(&unconf->cl_cred, 3142 + &old->cl_cred)) 3143 + goto out; 3209 3144 status = mark_client_expired_locked(old); 3210 3145 if (status) { 3211 3146 old = NULL; ··· 3392 3317 .so_free = nfs4_free_openowner, 3393 3318 }; 3394 3319 3320 + static struct nfs4_ol_stateid * 3321 + nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open) 3322 + { 3323 + struct nfs4_ol_stateid *local, *ret = NULL; 3324 + struct nfs4_openowner *oo = open->op_openowner; 3325 + 3326 + lockdep_assert_held(&fp->fi_lock); 3327 + 3328 + list_for_each_entry(local, &fp->fi_stateids, st_perfile) { 3329 + /* ignore lock owners */ 3330 + if (local->st_stateowner->so_is_open_owner == 0) 3331 + continue; 3332 + if (local->st_stateowner == &oo->oo_owner) { 3333 + ret = local; 3334 + atomic_inc(&ret->st_stid.sc_count); 3335 + break; 3336 + } 3337 + } 3338 + return ret; 3339 + } 3340 + 3395 3341 static struct nfs4_openowner * 3396 3342 alloc_init_open_stateowner(unsigned int strhashval, struct nfsd4_open *open, 3397 3343 struct nfsd4_compound_state *cstate) ··· 3444 3348 return ret; 3445 3349 } 3446 3350 3447 - static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { 3448 - struct nfs4_openowner *oo = open->op_openowner; 3351 + static struct nfs4_ol_stateid * 3352 + init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, 3353 + struct nfsd4_open *open) 3354 + { 3449 3355 3356 + struct nfs4_openowner *oo = open->op_openowner; 3357 + struct nfs4_ol_stateid *retstp = NULL; 3358 + 3359 + spin_lock(&oo->oo_owner.so_client->cl_lock); 3360 + spin_lock(&fp->fi_lock); 3361 + 3362 + retstp = nfsd4_find_existing_open(fp, open); 3363 + if (retstp) 3364 + goto out_unlock; 3450 3365 atomic_inc(&stp->st_stid.sc_count); 3451 3366 stp->st_stid.sc_type = NFS4_OPEN_STID; 3452 3367 INIT_LIST_HEAD(&stp->st_locks); ··· 3467 3360 stp->st_access_bmap = 0; 3468 3361 stp->st_deny_bmap = 0; 3469 3362 stp->st_openstp = NULL; 3470 - spin_lock(&oo->oo_owner.so_client->cl_lock); 3363 + init_rwsem(&stp->st_rwsem); 3471 3364 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); 3472 - spin_lock(&fp->fi_lock); 3473 3365 list_add(&stp->st_perfile, &fp->fi_stateids); 3366 + 3367 + out_unlock: 3474 3368 spin_unlock(&fp->fi_lock); 3475 3369 spin_unlock(&oo->oo_owner.so_client->cl_lock); 3370 + return retstp; 3476 3371 } 3477 3372 3478 3373 /* ··· 3885 3776 return nfs_ok; 3886 3777 } 3887 3778 3888 - static struct nfs4_ol_stateid * 3889 - nfsd4_find_existing_open(struct nfs4_file *fp, struct nfsd4_open *open) 3890 - { 3891 - struct nfs4_ol_stateid *local, *ret = NULL; 3892 - struct nfs4_openowner *oo = open->op_openowner; 3893 - 3894 - spin_lock(&fp->fi_lock); 3895 - list_for_each_entry(local, &fp->fi_stateids, st_perfile) { 3896 - /* ignore lock owners */ 3897 - if (local->st_stateowner->so_is_open_owner == 0) 3898 - continue; 3899 - if (local->st_stateowner == &oo->oo_owner) { 3900 - ret = local; 3901 - atomic_inc(&ret->st_stid.sc_count); 3902 - break; 3903 - } 3904 - } 3905 - spin_unlock(&fp->fi_lock); 3906 - return ret; 3907 - } 3908 - 3909 3779 static inline int nfs4_access_to_access(u32 nfs4_access) 3910 3780 { 3911 3781 int flags = 0; ··· 4033 3945 return fl; 4034 3946 } 4035 3947 3948 + /** 3949 + * nfs4_setlease - Obtain a delegation by requesting lease from vfs layer 3950 + * @dp: a pointer to the nfs4_delegation we're adding. 3951 + * 3952 + * Return: 3953 + * On success: Return code will be 0 on success. 3954 + * 3955 + * On error: -EAGAIN if there was an existing delegation. 3956 + * nonzero if there is an error in other cases. 3957 + * 3958 + */ 3959 + 4036 3960 static int nfs4_setlease(struct nfs4_delegation *dp) 4037 3961 { 4038 3962 struct nfs4_file *fp = dp->dl_stid.sc_file; ··· 4076 3976 goto out_unlock; 4077 3977 /* Race breaker */ 4078 3978 if (fp->fi_deleg_file) { 4079 - status = 0; 4080 - ++fp->fi_delegees; 4081 - hash_delegation_locked(dp, fp); 3979 + status = hash_delegation_locked(dp, fp); 4082 3980 goto out_unlock; 4083 3981 } 4084 3982 fp->fi_deleg_file = filp; 4085 - fp->fi_delegees = 1; 4086 - hash_delegation_locked(dp, fp); 3983 + fp->fi_delegees = 0; 3984 + status = hash_delegation_locked(dp, fp); 4087 3985 spin_unlock(&fp->fi_lock); 4088 3986 spin_unlock(&state_lock); 3987 + if (status) { 3988 + /* Should never happen, this is a new fi_deleg_file */ 3989 + WARN_ON_ONCE(1); 3990 + goto out_fput; 3991 + } 4089 3992 return 0; 4090 3993 out_unlock: 4091 3994 spin_unlock(&fp->fi_lock); ··· 4108 4005 if (fp->fi_had_conflict) 4109 4006 return ERR_PTR(-EAGAIN); 4110 4007 4008 + spin_lock(&state_lock); 4009 + spin_lock(&fp->fi_lock); 4010 + status = nfs4_get_existing_delegation(clp, fp); 4011 + spin_unlock(&fp->fi_lock); 4012 + spin_unlock(&state_lock); 4013 + 4014 + if (status) 4015 + return ERR_PTR(status); 4016 + 4111 4017 dp = alloc_init_deleg(clp, fh, odstate); 4112 4018 if (!dp) 4113 4019 return ERR_PTR(-ENOMEM); ··· 4135 4023 status = -EAGAIN; 4136 4024 goto out_unlock; 4137 4025 } 4138 - ++fp->fi_delegees; 4139 - hash_delegation_locked(dp, fp); 4140 - status = 0; 4026 + status = hash_delegation_locked(dp, fp); 4141 4027 out_unlock: 4142 4028 spin_unlock(&fp->fi_lock); 4143 4029 spin_unlock(&state_lock); ··· 4270 4160 struct nfs4_client *cl = open->op_openowner->oo_owner.so_client; 4271 4161 struct nfs4_file *fp = NULL; 4272 4162 struct nfs4_ol_stateid *stp = NULL; 4163 + struct nfs4_ol_stateid *swapstp = NULL; 4273 4164 struct nfs4_delegation *dp = NULL; 4274 4165 __be32 status; 4275 4166 ··· 4284 4173 status = nfs4_check_deleg(cl, open, &dp); 4285 4174 if (status) 4286 4175 goto out; 4176 + spin_lock(&fp->fi_lock); 4287 4177 stp = nfsd4_find_existing_open(fp, open); 4178 + spin_unlock(&fp->fi_lock); 4288 4179 } else { 4289 4180 open->op_file = NULL; 4290 4181 status = nfserr_bad_stateid; ··· 4300 4187 */ 4301 4188 if (stp) { 4302 4189 /* Stateid was found, this is an OPEN upgrade */ 4190 + down_read(&stp->st_rwsem); 4303 4191 status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open); 4304 - if (status) 4192 + if (status) { 4193 + up_read(&stp->st_rwsem); 4305 4194 goto out; 4195 + } 4306 4196 } else { 4307 4197 stp = open->op_stp; 4308 4198 open->op_stp = NULL; 4309 - init_open_stateid(stp, fp, open); 4199 + swapstp = init_open_stateid(stp, fp, open); 4200 + if (swapstp) { 4201 + nfs4_put_stid(&stp->st_stid); 4202 + stp = swapstp; 4203 + down_read(&stp->st_rwsem); 4204 + status = nfs4_upgrade_open(rqstp, fp, current_fh, 4205 + stp, open); 4206 + if (status) { 4207 + up_read(&stp->st_rwsem); 4208 + goto out; 4209 + } 4210 + goto upgrade_out; 4211 + } 4212 + down_read(&stp->st_rwsem); 4310 4213 status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open); 4311 4214 if (status) { 4215 + up_read(&stp->st_rwsem); 4312 4216 release_open_stateid(stp); 4313 4217 goto out; 4314 4218 } ··· 4335 4205 if (stp->st_clnt_odstate == open->op_odstate) 4336 4206 open->op_odstate = NULL; 4337 4207 } 4338 - update_stateid(&stp->st_stid.sc_stateid); 4339 - memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4208 + upgrade_out: 4209 + nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid); 4210 + up_read(&stp->st_rwsem); 4340 4211 4341 4212 if (nfsd4_has_session(&resp->cstate)) { 4342 4213 if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) { ··· 4950 4819 * revoked delegations are kept only for free_stateid. 4951 4820 */ 4952 4821 return nfserr_bad_stateid; 4822 + down_write(&stp->st_rwsem); 4953 4823 status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate)); 4954 - if (status) 4955 - return status; 4956 - return nfs4_check_fh(current_fh, &stp->st_stid); 4824 + if (status == nfs_ok) 4825 + status = nfs4_check_fh(current_fh, &stp->st_stid); 4826 + if (status != nfs_ok) 4827 + up_write(&stp->st_rwsem); 4828 + return status; 4957 4829 } 4958 4830 4959 4831 /* ··· 5003 4869 return status; 5004 4870 oo = openowner(stp->st_stateowner); 5005 4871 if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) { 4872 + up_write(&stp->st_rwsem); 5006 4873 nfs4_put_stid(&stp->st_stid); 5007 4874 return nfserr_bad_stateid; 5008 4875 } ··· 5034 4899 goto out; 5035 4900 oo = openowner(stp->st_stateowner); 5036 4901 status = nfserr_bad_stateid; 5037 - if (oo->oo_flags & NFS4_OO_CONFIRMED) 4902 + if (oo->oo_flags & NFS4_OO_CONFIRMED) { 4903 + up_write(&stp->st_rwsem); 5038 4904 goto put_stateid; 4905 + } 5039 4906 oo->oo_flags |= NFS4_OO_CONFIRMED; 5040 - update_stateid(&stp->st_stid.sc_stateid); 5041 - memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4907 + nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid); 4908 + up_write(&stp->st_rwsem); 5042 4909 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", 5043 4910 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid)); 5044 4911 ··· 5112 4975 goto put_stateid; 5113 4976 } 5114 4977 nfs4_stateid_downgrade(stp, od->od_share_access); 5115 - 5116 4978 reset_union_bmap_deny(od->od_share_deny, stp); 5117 - 5118 - update_stateid(&stp->st_stid.sc_stateid); 5119 - memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4979 + nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid); 5120 4980 status = nfs_ok; 5121 4981 put_stateid: 4982 + up_write(&stp->st_rwsem); 5122 4983 nfs4_put_stid(&stp->st_stid); 5123 4984 out: 5124 4985 nfsd4_bump_seqid(cstate, status); ··· 5168 5033 nfsd4_bump_seqid(cstate, status); 5169 5034 if (status) 5170 5035 goto out; 5171 - update_stateid(&stp->st_stid.sc_stateid); 5172 - memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 5036 + nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid); 5037 + up_write(&stp->st_rwsem); 5173 5038 5174 5039 nfsd4_close_open_stateid(stp); 5175 5040 ··· 5395 5260 stp->st_access_bmap = 0; 5396 5261 stp->st_deny_bmap = open_stp->st_deny_bmap; 5397 5262 stp->st_openstp = open_stp; 5263 + init_rwsem(&stp->st_rwsem); 5398 5264 list_add(&stp->st_locks, &open_stp->st_locks); 5399 5265 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); 5400 5266 spin_lock(&fp->fi_lock); ··· 5564 5428 &open_stp, nn); 5565 5429 if (status) 5566 5430 goto out; 5431 + up_write(&open_stp->st_rwsem); 5567 5432 open_sop = openowner(open_stp->st_stateowner); 5568 5433 status = nfserr_bad_stateid; 5569 5434 if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid, ··· 5572 5435 goto out; 5573 5436 status = lookup_or_create_lock_state(cstate, open_stp, lock, 5574 5437 &lock_stp, &new); 5438 + if (status == nfs_ok) 5439 + down_write(&lock_stp->st_rwsem); 5575 5440 } else { 5576 5441 status = nfs4_preprocess_seqid_op(cstate, 5577 5442 lock->lk_old_lock_seqid, ··· 5651 5512 err = vfs_lock_file(filp, F_SETLK, file_lock, conflock); 5652 5513 switch (-err) { 5653 5514 case 0: /* success! */ 5654 - update_stateid(&lock_stp->st_stid.sc_stateid); 5655 - memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid, 5656 - sizeof(stateid_t)); 5515 + nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid); 5657 5516 status = 0; 5658 5517 break; 5659 5518 case (EAGAIN): /* conflock holds conflicting lock */ ··· 5676 5539 cstate->replay_owner != &lock_sop->lo_owner && 5677 5540 seqid_mutating_err(ntohl(status))) 5678 5541 lock_sop->lo_owner.so_seqid++; 5542 + 5543 + up_write(&lock_stp->st_rwsem); 5679 5544 5680 5545 /* 5681 5546 * If this is a new, never-before-used stateid, and we are ··· 5843 5704 dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n"); 5844 5705 goto out_nfserr; 5845 5706 } 5846 - update_stateid(&stp->st_stid.sc_stateid); 5847 - memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 5707 + nfs4_inc_and_copy_stateid(&locku->lu_stateid, &stp->st_stid); 5848 5708 fput: 5849 5709 fput(filp); 5850 5710 put_stateid: 5711 + up_write(&stp->st_rwsem); 5851 5712 nfs4_put_stid(&stp->st_stid); 5852 5713 out: 5853 5714 nfsd4_bump_seqid(cstate, status);
+2 -30
fs/nfsd/nfscache.c
··· 63 63 static unsigned int longest_chain_cachesize; 64 64 65 65 static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec); 66 - static void cache_cleaner_func(struct work_struct *unused); 67 66 static unsigned long nfsd_reply_cache_count(struct shrinker *shrink, 68 67 struct shrink_control *sc); 69 68 static unsigned long nfsd_reply_cache_scan(struct shrinker *shrink, ··· 73 74 .count_objects = nfsd_reply_cache_count, 74 75 .seeks = 1, 75 76 }; 76 - 77 - /* 78 - * locking for the reply cache: 79 - * A cache entry is "single use" if c_state == RC_INPROG 80 - * Otherwise, it when accessing _prev or _next, the lock must be held. 81 - */ 82 - static DECLARE_DELAYED_WORK(cache_cleaner, cache_cleaner_func); 83 77 84 78 /* 85 79 * Put a cap on the size of the DRC based on the amount of available ··· 195 203 unsigned int i; 196 204 197 205 unregister_shrinker(&nfsd_reply_cache_shrinker); 198 - cancel_delayed_work_sync(&cache_cleaner); 199 206 200 207 for (i = 0; i < drc_hashsize; i++) { 201 208 struct list_head *head = &drc_hashtbl[i].lru_head; ··· 208 217 drc_hashtbl = NULL; 209 218 drc_hashsize = 0; 210 219 211 - if (drc_slab) { 212 - kmem_cache_destroy(drc_slab); 213 - drc_slab = NULL; 214 - } 220 + kmem_cache_destroy(drc_slab); 221 + drc_slab = NULL; 215 222 } 216 223 217 224 /* ··· 221 232 { 222 233 rp->c_timestamp = jiffies; 223 234 list_move_tail(&rp->c_lru, &b->lru_head); 224 - schedule_delayed_work(&cache_cleaner, RC_EXPIRE); 225 235 } 226 236 227 237 static long ··· 254 266 { 255 267 unsigned int i; 256 268 long freed = 0; 257 - bool cancel = true; 258 269 259 270 for (i = 0; i < drc_hashsize; i++) { 260 271 struct nfsd_drc_bucket *b = &drc_hashtbl[i]; ··· 262 275 continue; 263 276 spin_lock(&b->cache_lock); 264 277 freed += prune_bucket(b); 265 - if (!list_empty(&b->lru_head)) 266 - cancel = false; 267 278 spin_unlock(&b->cache_lock); 268 279 } 269 - 270 - /* 271 - * Conditionally rearm the job to run in RC_EXPIRE since we just 272 - * ran the pruner. 273 - */ 274 - if (!cancel) 275 - mod_delayed_work(system_wq, &cache_cleaner, RC_EXPIRE); 276 280 return freed; 277 - } 278 - 279 - static void 280 - cache_cleaner_func(struct work_struct *unused) 281 - { 282 - prune_cache_entries(); 283 281 } 284 282 285 283 static unsigned long
+1 -4
fs/nfsd/nfsfh.c
··· 631 631 fh_unlock(fhp); 632 632 fhp->fh_dentry = NULL; 633 633 dput(dentry); 634 - #ifdef CONFIG_NFSD_V3 635 - fhp->fh_pre_saved = 0; 636 - fhp->fh_post_saved = 0; 637 - #endif 634 + fh_clear_wcc(fhp); 638 635 } 639 636 fh_drop_write(fhp); 640 637 if (exp) {
+10 -10
fs/nfsd/nfsfh.h
··· 26 26 */ 27 27 typedef struct svc_fh { 28 28 struct knfsd_fh fh_handle; /* FH data */ 29 + int fh_maxsize; /* max size for fh_handle */ 29 30 struct dentry * fh_dentry; /* validated dentry */ 30 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 */ 34 - unsigned char fh_want_write; /* remount protection taken */ 33 + bool fh_locked; /* inode locked by us */ 34 + bool fh_want_write; /* remount protection taken */ 35 35 36 36 #ifdef CONFIG_NFSD_V3 37 - unsigned char fh_post_saved; /* post-op attrs saved */ 38 - unsigned char fh_pre_saved; /* pre-op attrs saved */ 37 + bool fh_post_saved; /* post-op attrs saved */ 38 + bool fh_pre_saved; /* pre-op attrs saved */ 39 39 40 40 /* Pre-op attributes saved during fh_lock */ 41 41 __u64 fh_pre_size; /* size before operation */ ··· 213 213 static inline void 214 214 fh_clear_wcc(struct svc_fh *fhp) 215 215 { 216 - fhp->fh_post_saved = 0; 217 - fhp->fh_pre_saved = 0; 216 + fhp->fh_post_saved = false; 217 + fhp->fh_pre_saved = false; 218 218 } 219 219 220 220 /* ··· 231 231 fhp->fh_pre_ctime = inode->i_ctime; 232 232 fhp->fh_pre_size = inode->i_size; 233 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 267 inode = d_inode(dentry); 268 268 mutex_lock_nested(&inode->i_mutex, subclass); 269 269 fill_pre_wcc(fhp); 270 - fhp->fh_locked = 1; 270 + fhp->fh_locked = true; 271 271 } 272 272 273 273 static inline void ··· 285 285 if (fhp->fh_locked) { 286 286 fill_post_wcc(fhp); 287 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
+19 -24
fs/nfsd/state.h
··· 84 84 * fields that are of general use to any stateid. 85 85 */ 86 86 struct nfs4_stid { 87 - atomic_t sc_count; 87 + atomic_t sc_count; 88 88 #define NFS4_OPEN_STID 1 89 89 #define NFS4_LOCK_STID 2 90 90 #define NFS4_DELEG_STID 4 ··· 94 94 #define NFS4_REVOKED_DELEG_STID 16 95 95 #define NFS4_CLOSED_DELEG_STID 32 96 96 #define NFS4_LAYOUT_STID 64 97 - unsigned char sc_type; 98 - stateid_t sc_stateid; 99 - struct nfs4_client *sc_client; 100 - struct nfs4_file *sc_file; 101 - void (*sc_free)(struct nfs4_stid *); 97 + unsigned char sc_type; 98 + stateid_t sc_stateid; 99 + spinlock_t sc_lock; 100 + struct nfs4_client *sc_client; 101 + struct nfs4_file *sc_file; 102 + void (*sc_free)(struct nfs4_stid *); 102 103 }; 103 104 104 105 /* ··· 365 364 char cr_recdir[HEXDIR_LEN]; /* recover dir */ 366 365 }; 367 366 368 - static inline void 369 - update_stateid(stateid_t *stateid) 370 - { 371 - stateid->si_generation++; 372 - /* Wraparound recommendation from 3530bis-13 9.1.3.2: */ 373 - if (stateid->si_generation == 0) 374 - stateid->si_generation = 1; 375 - } 376 - 377 367 /* A reasonable value for REPLAY_ISIZE was estimated as follows: 378 368 * The OPEN response, typically the largest, requires 379 369 * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + ··· 526 534 * Better suggestions welcome. 527 535 */ 528 536 struct nfs4_ol_stateid { 529 - struct nfs4_stid st_stid; /* must be first field */ 530 - struct list_head st_perfile; 531 - struct list_head st_perstateowner; 532 - struct list_head st_locks; 533 - struct nfs4_stateowner * st_stateowner; 534 - struct nfs4_clnt_odstate * st_clnt_odstate; 535 - unsigned char st_access_bmap; 536 - unsigned char st_deny_bmap; 537 - struct nfs4_ol_stateid * st_openstp; 537 + struct nfs4_stid st_stid; 538 + struct list_head st_perfile; 539 + struct list_head st_perstateowner; 540 + struct list_head st_locks; 541 + struct nfs4_stateowner *st_stateowner; 542 + struct nfs4_clnt_odstate *st_clnt_odstate; 543 + unsigned char st_access_bmap; 544 + unsigned char st_deny_bmap; 545 + struct nfs4_ol_stateid *st_openstp; 546 + struct rw_semaphore st_rwsem; 538 547 }; 539 548 540 549 static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s) ··· 554 561 struct nfsd4_callback ls_recall; 555 562 stateid_t ls_recall_sid; 556 563 bool ls_recalled; 564 + struct mutex ls_mutex; 557 565 }; 558 566 559 567 static inline struct nfs4_layout_stateid *layoutstateid(struct nfs4_stid *s) ··· 587 593 struct kmem_cache *slab); 588 594 void nfs4_unhash_stid(struct nfs4_stid *s); 589 595 void nfs4_put_stid(struct nfs4_stid *s); 596 + void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid); 590 597 void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *); 591 598 extern void nfs4_release_reclaim(struct nfsd_net *); 592 599 extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
-2
fs/nfsd/trace.c
··· 1 1 2 - #include "state.h" 3 - 4 2 #define CREATE_TRACE_POINTS 5 3 #include "trace.h"
+2
fs/nfsd/trace.h
··· 9 9 10 10 #include <linux/tracepoint.h> 11 11 12 + #include "state.h" 13 + 12 14 DECLARE_EVENT_CLASS(nfsd_stateid_class, 13 15 TP_PROTO(stateid_t *stp), 14 16 TP_ARGS(stp),
+2 -2
fs/nfsd/vfs.c
··· 1631 1631 /* cannot use fh_lock as we need deadlock protective ordering 1632 1632 * so do it by hand */ 1633 1633 trap = lock_rename(tdentry, fdentry); 1634 - ffhp->fh_locked = tfhp->fh_locked = 1; 1634 + ffhp->fh_locked = tfhp->fh_locked = true; 1635 1635 fill_pre_wcc(ffhp); 1636 1636 fill_pre_wcc(tfhp); 1637 1637 ··· 1681 1681 fill_post_wcc(ffhp); 1682 1682 fill_post_wcc(tfhp); 1683 1683 unlock_rename(tdentry, fdentry); 1684 - ffhp->fh_locked = tfhp->fh_locked = 0; 1684 + ffhp->fh_locked = tfhp->fh_locked = false; 1685 1685 fh_drop_write(ffhp); 1686 1686 1687 1687 out:
+2 -2
fs/nfsd/vfs.h
··· 112 112 int ret = mnt_want_write(fh->fh_export->ex_path.mnt); 113 113 114 114 if (!ret) 115 - fh->fh_want_write = 1; 115 + fh->fh_want_write = true; 116 116 return ret; 117 117 } 118 118 119 119 static inline void fh_drop_write(struct svc_fh *fh) 120 120 { 121 121 if (fh->fh_want_write) { 122 - fh->fh_want_write = 0; 122 + fh->fh_want_write = false; 123 123 mnt_drop_write(fh->fh_export->ex_path.mnt); 124 124 } 125 125 }
+1 -1
fs/nfsd/xdr4.h
··· 632 632 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) 633 633 { 634 634 BUG_ON(!fhp->fh_pre_saved); 635 - cinfo->atomic = fhp->fh_post_saved; 635 + cinfo->atomic = (u32)fhp->fh_post_saved; 636 636 cinfo->change_supported = IS_I_VERSION(d_inode(fhp->fh_dentry)); 637 637 638 638 cinfo->before_change = fhp->fh_pre_change;
+7 -3
include/linux/lockd/lockd.h
··· 68 68 struct nsm_handle *h_nsmhandle; /* NSM status handle */ 69 69 char *h_addrbuf; /* address eyecatcher */ 70 70 struct net *net; /* host net */ 71 + char nodename[UNX_MAXNODENAME + 1]; 71 72 }; 72 73 73 74 /* ··· 236 235 struct nlm_host * nlm_get_host(struct nlm_host *); 237 236 void nlm_shutdown_hosts(void); 238 237 void nlm_shutdown_hosts_net(struct net *net); 239 - void nlm_host_rebooted(const struct nlm_reboot *); 238 + void nlm_host_rebooted(const struct net *net, 239 + const struct nlm_reboot *); 240 240 241 241 /* 242 242 * Host monitoring ··· 245 243 int nsm_monitor(const struct nlm_host *host); 246 244 void nsm_unmonitor(const struct nlm_host *host); 247 245 248 - struct nsm_handle *nsm_get_handle(const struct sockaddr *sap, 246 + struct nsm_handle *nsm_get_handle(const struct net *net, 247 + const struct sockaddr *sap, 249 248 const size_t salen, 250 249 const char *hostname, 251 250 const size_t hostname_len); 252 - struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info); 251 + struct nsm_handle *nsm_reboot_lookup(const struct net *net, 252 + const struct nlm_reboot *info); 253 253 void nsm_release(struct nsm_handle *nsm); 254 254 255 255 /*
+11 -5
include/linux/sunrpc/cache.h
··· 48 48 struct cache_head { 49 49 struct hlist_node cache_list; 50 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 52 - * was sent, else this is when update was received 51 + time_t last_refresh; /* If CACHE_PENDING, this is when upcall was 52 + * sent, else this is when update was 53 + * received, though it is alway set to 54 + * be *after* ->flush_time. 53 55 */ 54 56 struct kref ref; 55 57 unsigned long flags; ··· 107 105 /* fields below this comment are for internal use 108 106 * and should not be touched by cache owners 109 107 */ 110 - time_t flush_time; /* flush all cache items with last_refresh 111 - * earlier than this */ 108 + time_t flush_time; /* flush all cache items with 109 + * last_refresh at or earlier 110 + * than this. last_refresh 111 + * is never set at or earlier 112 + * than this. 113 + */ 112 114 struct list_head others; 113 115 time_t nextcheck; 114 116 int entries; ··· 209 203 static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) 210 204 { 211 205 return (h->expiry_time < seconds_since_boot()) || 212 - (detail->flush_time > h->last_refresh); 206 + (detail->flush_time >= h->last_refresh); 213 207 } 214 208 215 209 extern int cache_check(struct cache_detail *detail,
+6 -7
net/sunrpc/auth_gss/auth_gss.c
··· 1411 1411 { 1412 1412 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 1413 1413 struct gss_cl_ctx *ctx; 1414 - unsigned long now = jiffies; 1415 - unsigned long expire; 1414 + unsigned long timeout = jiffies + (gss_key_expire_timeo * HZ); 1415 + int ret = 0; 1416 1416 1417 1417 rcu_read_lock(); 1418 1418 ctx = rcu_dereference(gss_cred->gc_ctx); 1419 - if (ctx) 1420 - expire = ctx->gc_expiry - (gss_key_expire_timeo * HZ); 1419 + if (!ctx || time_after(timeout, ctx->gc_expiry)) 1420 + ret = -EACCES; 1421 1421 rcu_read_unlock(); 1422 - if (!ctx || time_after(now, expire)) 1423 - return -EACCES; 1424 - return 0; 1422 + 1423 + return ret; 1425 1424 } 1426 1425 1427 1426 static int
+40 -13
net/sunrpc/cache.c
··· 41 41 static bool cache_defer_req(struct cache_req *req, struct cache_head *item); 42 42 static void cache_revisit_request(struct cache_head *item); 43 43 44 - static void cache_init(struct cache_head *h) 44 + static void cache_init(struct cache_head *h, struct cache_detail *detail) 45 45 { 46 46 time_t now = seconds_since_boot(); 47 47 INIT_HLIST_NODE(&h->cache_list); 48 48 h->flags = 0; 49 49 kref_init(&h->ref); 50 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 54 h->last_refresh = now; 52 55 } 53 56 ··· 84 81 * we might get lose if we need to 85 82 * cache_put it soon. 86 83 */ 87 - cache_init(new); 84 + cache_init(new, detail); 88 85 detail->init(new, key); 89 86 90 87 write_lock(&detail->hash_lock); ··· 119 116 120 117 static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch); 121 118 122 - static void cache_fresh_locked(struct cache_head *head, time_t expiry) 119 + static void cache_fresh_locked(struct cache_head *head, time_t expiry, 120 + struct cache_detail *detail) 123 121 { 122 + time_t now = seconds_since_boot(); 123 + if (now <= detail->flush_time) 124 + /* ensure it isn't immediately treated as expired */ 125 + now = detail->flush_time + 1; 124 126 head->expiry_time = expiry; 125 - head->last_refresh = seconds_since_boot(); 127 + head->last_refresh = now; 126 128 smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */ 127 129 set_bit(CACHE_VALID, &head->flags); 128 130 } ··· 157 149 set_bit(CACHE_NEGATIVE, &old->flags); 158 150 else 159 151 detail->update(old, new); 160 - cache_fresh_locked(old, new->expiry_time); 152 + cache_fresh_locked(old, new->expiry_time, detail); 161 153 write_unlock(&detail->hash_lock); 162 154 cache_fresh_unlocked(old, detail); 163 155 return old; ··· 170 162 cache_put(old, detail); 171 163 return NULL; 172 164 } 173 - cache_init(tmp); 165 + cache_init(tmp, detail); 174 166 detail->init(tmp, old); 175 167 176 168 write_lock(&detail->hash_lock); ··· 181 173 hlist_add_head(&tmp->cache_list, &detail->hash_table[hash]); 182 174 detail->entries++; 183 175 cache_get(tmp); 184 - cache_fresh_locked(tmp, new->expiry_time); 185 - cache_fresh_locked(old, 0); 176 + cache_fresh_locked(tmp, new->expiry_time, detail); 177 + cache_fresh_locked(old, 0, detail); 186 178 write_unlock(&detail->hash_lock); 187 179 cache_fresh_unlocked(tmp, detail); 188 180 cache_fresh_unlocked(old, detail); ··· 227 219 rv = cache_is_valid(h); 228 220 if (rv == -EAGAIN) { 229 221 set_bit(CACHE_NEGATIVE, &h->flags); 230 - cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); 222 + cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY, 223 + detail); 231 224 rv = -ENOENT; 232 225 } 233 226 write_unlock(&detail->hash_lock); ··· 496 487 497 488 void cache_purge(struct cache_detail *detail) 498 489 { 499 - detail->flush_time = LONG_MAX; 490 + time_t now = seconds_since_boot(); 491 + if (detail->flush_time >= now) 492 + now = detail->flush_time + 1; 493 + /* 'now' is the maximum value any 'last_refresh' can have */ 494 + detail->flush_time = now; 500 495 detail->nextcheck = seconds_since_boot(); 501 496 cache_flush(); 502 - detail->flush_time = 1; 503 497 } 504 498 EXPORT_SYMBOL_GPL(cache_purge); 505 499 ··· 1448 1436 { 1449 1437 char tbuf[20]; 1450 1438 char *bp, *ep; 1439 + time_t then, now; 1451 1440 1452 1441 if (*ppos || count > sizeof(tbuf)-1) 1453 1442 return -EINVAL; ··· 1460 1447 return -EINVAL; 1461 1448 1462 1449 bp = tbuf; 1463 - cd->flush_time = get_expiry(&bp); 1464 - cd->nextcheck = seconds_since_boot(); 1450 + then = get_expiry(&bp); 1451 + now = seconds_since_boot(); 1452 + cd->nextcheck = now; 1453 + /* Can only set flush_time to 1 second beyond "now", or 1454 + * possibly 1 second beyond flushtime. This is because 1455 + * flush_time never goes backwards so it mustn't get too far 1456 + * ahead of time. 1457 + */ 1458 + if (then >= now) { 1459 + /* Want to flush everything, so behave like cache_purge() */ 1460 + if (cd->flush_time >= now) 1461 + now = cd->flush_time + 1; 1462 + then = now; 1463 + } 1464 + 1465 + cd->flush_time = then; 1465 1466 cache_flush(); 1466 1467 1467 1468 *ppos += count;
+32 -8
net/sunrpc/svcsock.c
··· 181 181 struct page **ppage = xdr->pages; 182 182 size_t base = xdr->page_base; 183 183 unsigned int pglen = xdr->page_len; 184 - unsigned int flags = MSG_MORE; 184 + unsigned int flags = MSG_MORE | MSG_SENDPAGE_NOTLAST; 185 185 int slen; 186 186 int len = 0; 187 187 ··· 399 399 return svc_port_is_privileged(svc_addr(rqstp)); 400 400 } 401 401 402 + static 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 428 * INET callback when data has been received on the socket. 404 429 */ ··· 439 414 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 440 415 svc_xprt_enqueue(&svsk->sk_xprt); 441 416 } 442 - if (wq && waitqueue_active(wq)) 417 + if (sunrpc_waitqueue_active(wq)) 443 418 wake_up_interruptible(wq); 444 419 } 445 420 ··· 457 432 svc_xprt_enqueue(&svsk->sk_xprt); 458 433 } 459 434 460 - if (wq && waitqueue_active(wq)) { 435 + if (sunrpc_waitqueue_active(wq)) { 461 436 dprintk("RPC svc_write_space: someone sleeping on %p\n", 462 437 svsk); 463 438 wake_up_interruptible(wq); ··· 812 787 } 813 788 814 789 wq = sk_sleep(sk); 815 - if (wq && waitqueue_active(wq)) 790 + if (sunrpc_waitqueue_active(wq)) 816 791 wake_up_interruptible_all(wq); 817 792 } 818 793 ··· 833 808 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 834 809 svc_xprt_enqueue(&svsk->sk_xprt); 835 810 } 836 - if (wq && waitqueue_active(wq)) 811 + if (sunrpc_waitqueue_active(wq)) 837 812 wake_up_interruptible_all(wq); 838 813 } 839 814 ··· 848 823 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 849 824 svc_xprt_enqueue(&svsk->sk_xprt); 850 825 } 851 - if (wq && waitqueue_active(wq)) 826 + if (sunrpc_waitqueue_active(wq)) 852 827 wake_up_interruptible(wq); 853 828 } 854 829 ··· 1392 1367 1393 1368 /* 1394 1369 * Initialize socket for RPC use and create svc_sock struct 1395 - * XXX: May want to setsockopt SO_SNDBUF and SO_RCVBUF. 1396 1370 */ 1397 1371 static struct svc_sock *svc_setup_socket(struct svc_serv *serv, 1398 1372 struct socket *sock, ··· 1618 1594 sk->sk_write_space = svsk->sk_owspace; 1619 1595 1620 1596 wq = sk_sleep(sk); 1621 - if (wq && waitqueue_active(wq)) 1597 + if (sunrpc_waitqueue_active(wq)) 1622 1598 wake_up_interruptible(wq); 1623 1599 } 1624 1600