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

Merge tag 'nfs-for-3.13-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client updates from Trond Myklebust:
"Highlights include:

- Changes to the RPC socket code to allow NFSv4 to turn off
timeout+retry:
* Detect TCP connection breakage through the "keepalive" mechanism
- Add client side support for NFSv4.x migration (Chuck Lever)
- Add support for multiple security flavour arguments to the "sec="
mount option (Dros Adamson)
- fs-cache bugfixes from David Howells:
* Fix an issue whereby caching can be enabled on a file that is
open for writing
- More NFSv4 open code stable bugfixes
- Various Labeled NFS (selinux) bugfixes, including one stable fix
- Fix buffer overflow checking in the RPCSEC_GSS upcall encoding"

* tag 'nfs-for-3.13-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (68 commits)
NFSv4.2: Remove redundant checks in nfs_setsecurity+nfs4_label_init_security
NFSv4: Sanity check the server reply in _nfs4_server_capabilities
NFSv4.2: encode_readdir - only ask for labels when doing readdirplus
nfs: set security label when revalidating inode
NFSv4.2: Fix a mismatch between Linux labeled NFS and the NFSv4.2 spec
NFS: Fix a missing initialisation when reading the SELinux label
nfs: fix oops when trying to set SELinux label
nfs: fix inverted test for delegation in nfs4_reclaim_open_state
SUNRPC: Cleanup xs_destroy()
SUNRPC: close a rare race in xs_tcp_setup_socket.
SUNRPC: remove duplicated include from clnt.c
nfs: use IS_ROOT not DCACHE_DISCONNECTED
SUNRPC: Fix buffer overflow checking in gss_encode_v0_msg/gss_encode_v1_msg
SUNRPC: gss_alloc_msg - choose _either_ a v0 message or a v1 message
SUNRPC: remove an unnecessary if statement
nfs: Use PTR_ERR_OR_ZERO in 'nfs/nfs4super.c'
nfs: Use PTR_ERR_OR_ZERO in 'nfs41_callback_up' function
nfs: Remove useless 'error' assignment
sunrpc: comment typo fix
SUNRPC: Add correct rcu_dereference annotation in rpc_clnt_set_transport
...

+1944 -598
+60 -13
Documentation/filesystems/caching/netfs-api.txt
··· 29 29 (6) Index registration 30 30 (7) Data file registration 31 31 (8) Miscellaneous object registration 32 - (9) Setting the data file size 32 + (9) Setting the data file size 33 33 (10) Page alloc/read/write 34 34 (11) Page uncaching 35 35 (12) Index and data file consistency 36 - (13) Miscellaneous cookie operations 37 - (14) Cookie unregistration 38 - (15) Index invalidation 39 - (16) Data file invalidation 40 - (17) FS-Cache specific page flags. 36 + (13) Cookie enablement 37 + (14) Miscellaneous cookie operations 38 + (15) Cookie unregistration 39 + (16) Index invalidation 40 + (17) Data file invalidation 41 + (18) FS-Cache specific page flags. 41 42 42 43 43 44 ============================= ··· 335 334 struct fscache_cookie * 336 335 fscache_acquire_cookie(struct fscache_cookie *parent, 337 336 const struct fscache_object_def *def, 338 - void *netfs_data); 337 + void *netfs_data, 338 + bool enable); 339 339 340 340 This function creates an index entry in the index represented by parent, 341 341 filling in the index entry by calling the operations pointed to by def. ··· 352 350 may be created in several different caches independently at different times. 353 351 This is all handled transparently, and the netfs doesn't see any of it. 354 352 353 + A cookie will be created in the disabled state if enabled is false. A cookie 354 + must be enabled to do anything with it. A disabled cookie can be enabled by 355 + calling fscache_enable_cookie() (see below). 356 + 355 357 For example, with AFS, a cell would be added to the primary index. This index 356 358 entry would have a dependent inode containing a volume location index for the 357 359 volume mappings within this cell: ··· 363 357 cell->cache = 364 358 fscache_acquire_cookie(afs_cache_netfs.primary_index, 365 359 &afs_cell_cache_index_def, 366 - cell); 360 + cell, true); 367 361 368 362 Then when a volume location was accessed, it would be entered into the cell's 369 363 index and an inode would be allocated that acts as a volume type and hash chain ··· 372 366 vlocation->cache = 373 367 fscache_acquire_cookie(cell->cache, 374 368 &afs_vlocation_cache_index_def, 375 - vlocation); 369 + vlocation, true); 376 370 377 371 And then a particular flavour of volume (R/O for example) could be added to 378 372 that index, creating another index for vnodes (AFS inode equivalents): ··· 380 374 volume->cache = 381 375 fscache_acquire_cookie(vlocation->cache, 382 376 &afs_volume_cache_index_def, 383 - volume); 377 + volume, true); 384 378 385 379 386 380 ====================== ··· 394 388 vnode->cache = 395 389 fscache_acquire_cookie(volume->cache, 396 390 &afs_vnode_cache_object_def, 397 - vnode); 391 + vnode, true); 398 392 399 393 400 394 ================================= ··· 410 404 xattr->cache = 411 405 fscache_acquire_cookie(vnode->cache, 412 406 &afs_xattr_cache_object_def, 413 - xattr); 407 + xattr, true); 414 408 415 409 Miscellaneous objects might be used to store extended attributes or directory 416 410 entries for example. ··· 739 733 data blocks are added to a data file object. 740 734 741 735 736 + ================= 737 + COOKIE ENABLEMENT 738 + ================= 739 + 740 + Cookies exist in one of two states: enabled and disabled. If a cookie is 741 + disabled, it ignores all attempts to acquire child cookies; check, update or 742 + invalidate its state; allocate, read or write backing pages - though it is 743 + still possible to uncache pages and relinquish the cookie. 744 + 745 + The initial enablement state is set by fscache_acquire_cookie(), but the cookie 746 + can be enabled or disabled later. To disable a cookie, call: 747 + 748 + void fscache_disable_cookie(struct fscache_cookie *cookie, 749 + bool invalidate); 750 + 751 + If the cookie is not already disabled, this locks the cookie against other 752 + enable and disable ops, marks the cookie as being disabled, discards or 753 + invalidates any backing objects and waits for cessation of activity on any 754 + associated object before unlocking the cookie. 755 + 756 + All possible failures are handled internally. The caller should consider 757 + calling fscache_uncache_all_inode_pages() afterwards to make sure all page 758 + markings are cleared up. 759 + 760 + Cookies can be enabled or reenabled with: 761 + 762 + void fscache_enable_cookie(struct fscache_cookie *cookie, 763 + bool (*can_enable)(void *data), 764 + void *data) 765 + 766 + If the cookie is not already enabled, this locks the cookie against other 767 + enable and disable ops, invokes can_enable() and, if the cookie is not an index 768 + cookie, will begin the procedure of acquiring backing objects. 769 + 770 + The optional can_enable() function is passed the data argument and returns a 771 + ruling as to whether or not enablement should actually be permitted to begin. 772 + 773 + All possible failures are handled internally. The cookie will only be marked 774 + as enabled if provisional backing objects are allocated. 775 + 776 + 742 777 =============================== 743 778 MISCELLANEOUS COOKIE OPERATIONS 744 779 =============================== ··· 825 778 To get rid of a cookie, this function should be called. 826 779 827 780 void fscache_relinquish_cookie(struct fscache_cookie *cookie, 828 - int retire); 781 + bool retire); 829 782 830 783 If retire is non-zero, then the object will be marked for recycling, and all 831 784 copies of it will be removed from all active caches in which it is present.
+3 -3
fs/9p/cache.c
··· 90 90 91 91 v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index, 92 92 &v9fs_cache_session_index_def, 93 - v9ses); 93 + v9ses, true); 94 94 p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n", 95 95 v9ses, v9ses->fscache); 96 96 } ··· 204 204 v9ses = v9fs_inode2v9ses(inode); 205 205 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, 206 206 &v9fs_cache_inode_index_def, 207 - v9inode); 207 + v9inode, true); 208 208 209 209 p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", 210 210 inode, v9inode->fscache); ··· 271 271 v9ses = v9fs_inode2v9ses(inode); 272 272 v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, 273 273 &v9fs_cache_inode_index_def, 274 - v9inode); 274 + v9inode, true); 275 275 p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n", 276 276 inode, old, v9inode->fscache); 277 277
+1 -1
fs/afs/cell.c
··· 179 179 /* put it up for caching (this never returns an error) */ 180 180 cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index, 181 181 &afs_cell_cache_index_def, 182 - cell); 182 + cell, true); 183 183 #endif 184 184 185 185 /* add to the cell lists */
+1 -1
fs/afs/inode.c
··· 259 259 #ifdef CONFIG_AFS_FSCACHE 260 260 vnode->cache = fscache_acquire_cookie(vnode->volume->cache, 261 261 &afs_vnode_cache_index_def, 262 - vnode); 262 + vnode, true); 263 263 #endif 264 264 265 265 ret = afs_inode_map_status(vnode, key);
+2 -1
fs/afs/vlocation.c
··· 308 308 /* see if we have an in-cache copy (will set vl->valid if there is) */ 309 309 #ifdef CONFIG_AFS_FSCACHE 310 310 vl->cache = fscache_acquire_cookie(vl->cell->cache, 311 - &afs_vlocation_cache_index_def, vl); 311 + &afs_vlocation_cache_index_def, vl, 312 + true); 312 313 #endif 313 314 314 315 if (vl->valid) {
+1 -1
fs/afs/volume.c
··· 131 131 #ifdef CONFIG_AFS_FSCACHE 132 132 volume->cache = fscache_acquire_cookie(vlocation->cache, 133 133 &afs_volume_cache_index_def, 134 - volume); 134 + volume, true); 135 135 #endif 136 136 afs_get_vlocation(vlocation); 137 137 volume->vlocation = vlocation;
+1 -1
fs/cachefiles/interface.c
··· 270 270 #endif 271 271 272 272 /* delete retired objects */ 273 - if (test_bit(FSCACHE_COOKIE_RETIRED, &object->fscache.cookie->flags) && 273 + if (test_bit(FSCACHE_OBJECT_RETIRED, &object->fscache.flags) && 274 274 _object != cache->cache.fsdef 275 275 ) { 276 276 _debug("- retire object OBJ%x", object->fscache.debug_id);
+2 -2
fs/ceph/cache.c
··· 68 68 { 69 69 fsc->fscache = fscache_acquire_cookie(ceph_cache_netfs.primary_index, 70 70 &ceph_fscache_fsid_object_def, 71 - fsc); 71 + fsc, true); 72 72 73 73 if (fsc->fscache == NULL) { 74 74 pr_err("Unable to resgister fsid: %p fscache cookie", fsc); ··· 204 204 205 205 ci->fscache = fscache_acquire_cookie(fsc->fscache, 206 206 &ceph_fscache_inode_object_def, 207 - ci); 207 + ci, true); 208 208 done: 209 209 mutex_unlock(&inode->i_mutex); 210 210
+4 -4
fs/cifs/fscache.c
··· 27 27 { 28 28 server->fscache = 29 29 fscache_acquire_cookie(cifs_fscache_netfs.primary_index, 30 - &cifs_fscache_server_index_def, server); 30 + &cifs_fscache_server_index_def, server, true); 31 31 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 32 32 __func__, server, server->fscache); 33 33 } ··· 46 46 47 47 tcon->fscache = 48 48 fscache_acquire_cookie(server->fscache, 49 - &cifs_fscache_super_index_def, tcon); 49 + &cifs_fscache_super_index_def, tcon, true); 50 50 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", 51 51 __func__, server->fscache, tcon->fscache); 52 52 } ··· 69 69 70 70 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) { 71 71 cifsi->fscache = fscache_acquire_cookie(tcon->fscache, 72 - &cifs_fscache_inode_object_def, cifsi); 72 + &cifs_fscache_inode_object_def, cifsi, true); 73 73 cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n", 74 74 __func__, tcon->fscache, cifsi->fscache); 75 75 } ··· 119 119 cifsi->fscache = fscache_acquire_cookie( 120 120 cifs_sb_master_tcon(cifs_sb)->fscache, 121 121 &cifs_fscache_inode_object_def, 122 - cifsi); 122 + cifsi, true); 123 123 cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n", 124 124 __func__, cifsi->fscache, old); 125 125 }
+142 -51
fs/fscache/cookie.c
··· 58 58 struct fscache_cookie *__fscache_acquire_cookie( 59 59 struct fscache_cookie *parent, 60 60 const struct fscache_cookie_def *def, 61 - void *netfs_data) 61 + void *netfs_data, 62 + bool enable) 62 63 { 63 64 struct fscache_cookie *cookie; 64 65 65 66 BUG_ON(!def); 66 67 67 - _enter("{%s},{%s},%p", 68 + _enter("{%s},{%s},%p,%u", 68 69 parent ? (char *) parent->def->name : "<no-parent>", 69 - def->name, netfs_data); 70 + def->name, netfs_data, enable); 70 71 71 72 fscache_stat(&fscache_n_acquires); 72 73 ··· 107 106 cookie->def = def; 108 107 cookie->parent = parent; 109 108 cookie->netfs_data = netfs_data; 110 - cookie->flags = 0; 109 + cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET); 111 110 112 111 /* radix tree insertion won't use the preallocation pool unless it's 113 112 * told it may not wait */ ··· 125 124 break; 126 125 } 127 126 128 - /* if the object is an index then we need do nothing more here - we 129 - * create indices on disk when we need them as an index may exist in 130 - * multiple caches */ 131 - if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) { 132 - if (fscache_acquire_non_index_cookie(cookie) < 0) { 133 - atomic_dec(&parent->n_children); 134 - __fscache_cookie_put(cookie); 135 - fscache_stat(&fscache_n_acquires_nobufs); 136 - _leave(" = NULL"); 137 - return NULL; 127 + if (enable) { 128 + /* if the object is an index then we need do nothing more here 129 + * - we create indices on disk when we need them as an index 130 + * may exist in multiple caches */ 131 + if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) { 132 + if (fscache_acquire_non_index_cookie(cookie) == 0) { 133 + set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 134 + } else { 135 + atomic_dec(&parent->n_children); 136 + __fscache_cookie_put(cookie); 137 + fscache_stat(&fscache_n_acquires_nobufs); 138 + _leave(" = NULL"); 139 + return NULL; 140 + } 141 + } else { 142 + set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 138 143 } 139 144 } 140 145 ··· 149 142 return cookie; 150 143 } 151 144 EXPORT_SYMBOL(__fscache_acquire_cookie); 145 + 146 + /* 147 + * Enable a cookie to permit it to accept new operations. 148 + */ 149 + void __fscache_enable_cookie(struct fscache_cookie *cookie, 150 + bool (*can_enable)(void *data), 151 + void *data) 152 + { 153 + _enter("%p", cookie); 154 + 155 + wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK, 156 + fscache_wait_bit, TASK_UNINTERRUPTIBLE); 157 + 158 + if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags)) 159 + goto out_unlock; 160 + 161 + if (can_enable && !can_enable(data)) { 162 + /* The netfs decided it didn't want to enable after all */ 163 + } else if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) { 164 + /* Wait for outstanding disablement to complete */ 165 + __fscache_wait_on_invalidate(cookie); 166 + 167 + if (fscache_acquire_non_index_cookie(cookie) == 0) 168 + set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 169 + } else { 170 + set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 171 + } 172 + 173 + out_unlock: 174 + clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags); 175 + wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK); 176 + } 177 + EXPORT_SYMBOL(__fscache_enable_cookie); 152 178 153 179 /* 154 180 * acquire a non-index cookie ··· 197 157 198 158 _enter(""); 199 159 200 - cookie->flags = 1 << FSCACHE_COOKIE_UNAVAILABLE; 160 + set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); 201 161 202 162 /* now we need to see whether the backing objects for this cookie yet 203 163 * exist, if not there'll be nothing to search */ ··· 220 180 221 181 _debug("cache %s", cache->tag->name); 222 182 223 - cookie->flags = 224 - (1 << FSCACHE_COOKIE_LOOKING_UP) | 225 - (1 << FSCACHE_COOKIE_NO_DATA_YET); 183 + set_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags); 226 184 227 185 /* ask the cache to allocate objects for this cookie and its parent 228 186 * chain */ ··· 436 398 if (!hlist_empty(&cookie->backing_objects)) { 437 399 spin_lock(&cookie->lock); 438 400 439 - if (!hlist_empty(&cookie->backing_objects) && 401 + if (fscache_cookie_enabled(cookie) && 402 + !hlist_empty(&cookie->backing_objects) && 440 403 !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING, 441 404 &cookie->flags)) { 442 405 object = hlist_entry(cookie->backing_objects.first, ··· 491 452 492 453 spin_lock(&cookie->lock); 493 454 494 - /* update the index entry on disk in each cache backing this cookie */ 495 - hlist_for_each_entry(object, 496 - &cookie->backing_objects, cookie_link) { 497 - fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE); 455 + if (fscache_cookie_enabled(cookie)) { 456 + /* update the index entry on disk in each cache backing this 457 + * cookie. 458 + */ 459 + hlist_for_each_entry(object, 460 + &cookie->backing_objects, cookie_link) { 461 + fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE); 462 + } 498 463 } 499 464 500 465 spin_unlock(&cookie->lock); ··· 507 464 EXPORT_SYMBOL(__fscache_update_cookie); 508 465 509 466 /* 467 + * Disable a cookie to stop it from accepting new requests from the netfs. 468 + */ 469 + void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) 470 + { 471 + struct fscache_object *object; 472 + bool awaken = false; 473 + 474 + _enter("%p,%u", cookie, invalidate); 475 + 476 + ASSERTCMP(atomic_read(&cookie->n_active), >, 0); 477 + 478 + if (atomic_read(&cookie->n_children) != 0) { 479 + printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n", 480 + cookie->def->name); 481 + BUG(); 482 + } 483 + 484 + wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK, 485 + fscache_wait_bit, TASK_UNINTERRUPTIBLE); 486 + if (!test_and_clear_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags)) 487 + goto out_unlock_enable; 488 + 489 + /* If the cookie is being invalidated, wait for that to complete first 490 + * so that we can reuse the flag. 491 + */ 492 + __fscache_wait_on_invalidate(cookie); 493 + 494 + /* Dispose of the backing objects */ 495 + set_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags); 496 + 497 + spin_lock(&cookie->lock); 498 + if (!hlist_empty(&cookie->backing_objects)) { 499 + hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) { 500 + if (invalidate) 501 + set_bit(FSCACHE_OBJECT_RETIRED, &object->flags); 502 + fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL); 503 + } 504 + } else { 505 + if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags)) 506 + awaken = true; 507 + } 508 + spin_unlock(&cookie->lock); 509 + if (awaken) 510 + wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING); 511 + 512 + /* Wait for cessation of activity requiring access to the netfs (when 513 + * n_active reaches 0). This makes sure outstanding reads and writes 514 + * have completed. 515 + */ 516 + if (!atomic_dec_and_test(&cookie->n_active)) 517 + wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t, 518 + TASK_UNINTERRUPTIBLE); 519 + 520 + /* Reset the cookie state if it wasn't relinquished */ 521 + if (!test_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) { 522 + atomic_inc(&cookie->n_active); 523 + set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 524 + } 525 + 526 + out_unlock_enable: 527 + clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags); 528 + wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK); 529 + _leave(""); 530 + } 531 + EXPORT_SYMBOL(__fscache_disable_cookie); 532 + 533 + /* 510 534 * release a cookie back to the cache 511 535 * - the object will be marked as recyclable on disk if retire is true 512 536 * - all dependents of this cookie must have already been unregistered 513 537 * (indices/files/pages) 514 538 */ 515 - void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) 539 + void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) 516 540 { 517 - struct fscache_object *object; 518 - 519 541 fscache_stat(&fscache_n_relinquishes); 520 542 if (retire) 521 543 fscache_stat(&fscache_n_relinquishes_retire); ··· 595 487 cookie, cookie->def->name, cookie->netfs_data, 596 488 atomic_read(&cookie->n_active), retire); 597 489 598 - ASSERTCMP(atomic_read(&cookie->n_active), >, 0); 599 - 600 - if (atomic_read(&cookie->n_children) != 0) { 601 - printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n", 602 - cookie->def->name); 603 - BUG(); 604 - } 605 - 606 490 /* No further netfs-accessing operations on this cookie permitted */ 607 491 set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags); 608 - if (retire) 609 - set_bit(FSCACHE_COOKIE_RETIRED, &cookie->flags); 610 492 611 - spin_lock(&cookie->lock); 612 - hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) { 613 - fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL); 614 - } 615 - spin_unlock(&cookie->lock); 616 - 617 - /* Wait for cessation of activity requiring access to the netfs (when 618 - * n_active reaches 0). 619 - */ 620 - if (!atomic_dec_and_test(&cookie->n_active)) 621 - wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t, 622 - TASK_UNINTERRUPTIBLE); 493 + __fscache_disable_cookie(cookie, retire); 623 494 624 495 /* Clear pointers back to the netfs */ 625 496 cookie->netfs_data = NULL; ··· 655 568 { 656 569 struct fscache_operation *op; 657 570 struct fscache_object *object; 571 + bool wake_cookie = false; 658 572 int ret; 659 573 660 574 _enter("%p,", cookie); ··· 679 591 680 592 spin_lock(&cookie->lock); 681 593 682 - if (hlist_empty(&cookie->backing_objects)) 594 + if (!fscache_cookie_enabled(cookie) || 595 + hlist_empty(&cookie->backing_objects)) 683 596 goto inconsistent; 684 597 object = hlist_entry(cookie->backing_objects.first, 685 598 struct fscache_object, cookie_link); ··· 689 600 690 601 op->debug_id = atomic_inc_return(&fscache_op_debug_id); 691 602 692 - atomic_inc(&cookie->n_active); 603 + __fscache_use_cookie(cookie); 693 604 if (fscache_submit_op(object, op) < 0) 694 605 goto submit_failed; 695 606 ··· 711 622 return ret; 712 623 713 624 submit_failed: 714 - atomic_dec(&cookie->n_active); 625 + wake_cookie = __fscache_unuse_cookie(cookie); 715 626 inconsistent: 716 627 spin_unlock(&cookie->lock); 628 + if (wake_cookie) 629 + __fscache_wake_unused_cookie(cookie); 717 630 kfree(op); 718 631 _leave(" = -ESTALE"); 719 632 return -ESTALE;
+1
fs/fscache/fsdef.c
··· 59 59 .lock = __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock), 60 60 .backing_objects = HLIST_HEAD_INIT, 61 61 .def = &fscache_fsdef_index_def, 62 + .flags = 1 << FSCACHE_COOKIE_ENABLED, 62 63 }; 63 64 EXPORT_SYMBOL(fscache_fsdef_index); 64 65
+1
fs/fscache/netfs.c
··· 45 45 netfs->primary_index->def = &fscache_fsdef_netfs_def; 46 46 netfs->primary_index->parent = &fscache_fsdef_index; 47 47 netfs->primary_index->netfs_data = netfs; 48 + netfs->primary_index->flags = 1 << FSCACHE_COOKIE_ENABLED; 48 49 49 50 atomic_inc(&netfs->primary_index->parent->usage); 50 51 atomic_inc(&netfs->primary_index->parent->n_children);
+5 -2
fs/fscache/object.c
··· 495 495 * returning ENODATA. 496 496 */ 497 497 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 498 + clear_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); 498 499 499 500 _debug("wake up lookup %p", &cookie->flags); 500 501 clear_bit_unlock(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags); ··· 528 527 529 528 /* We do (presumably) have data */ 530 529 clear_bit_unlock(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); 530 + clear_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); 531 531 532 532 /* Allow write requests to begin stacking up and read requests 533 533 * to begin shovelling data. ··· 681 679 */ 682 680 spin_lock(&cookie->lock); 683 681 hlist_del_init(&object->cookie_link); 684 - if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags)) 682 + if (hlist_empty(&cookie->backing_objects) && 683 + test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags)) 685 684 awaken = true; 686 685 spin_unlock(&cookie->lock); 687 686 ··· 930 927 */ 931 928 if (!fscache_use_cookie(object)) { 932 929 ASSERT(object->cookie->stores.rnode == NULL); 933 - set_bit(FSCACHE_COOKIE_RETIRED, &cookie->flags); 930 + set_bit(FSCACHE_OBJECT_RETIRED, &object->flags); 934 931 _leave(" [no cookie]"); 935 932 return transit_to(KILL_OBJECT); 936 933 }
+42 -17
fs/fscache/page.c
··· 163 163 164 164 fscache_stat(&fscache_n_attr_changed_calls); 165 165 166 - if (fscache_object_is_active(object) && 167 - fscache_use_cookie(object)) { 166 + if (fscache_object_is_active(object)) { 168 167 fscache_stat(&fscache_n_cop_attr_changed); 169 168 ret = object->cache->ops->attr_changed(object); 170 169 fscache_stat_d(&fscache_n_cop_attr_changed); 171 - fscache_unuse_cookie(object); 172 170 if (ret < 0) 173 171 fscache_abort_object(object); 174 172 } ··· 182 184 { 183 185 struct fscache_operation *op; 184 186 struct fscache_object *object; 187 + bool wake_cookie; 185 188 186 189 _enter("%p", cookie); 187 190 ··· 198 199 } 199 200 200 201 fscache_operation_init(op, fscache_attr_changed_op, NULL); 201 - op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE); 202 + op->flags = FSCACHE_OP_ASYNC | 203 + (1 << FSCACHE_OP_EXCLUSIVE) | 204 + (1 << FSCACHE_OP_UNUSE_COOKIE); 202 205 203 206 spin_lock(&cookie->lock); 204 207 205 - if (hlist_empty(&cookie->backing_objects)) 208 + if (!fscache_cookie_enabled(cookie) || 209 + hlist_empty(&cookie->backing_objects)) 206 210 goto nobufs; 207 211 object = hlist_entry(cookie->backing_objects.first, 208 212 struct fscache_object, cookie_link); 209 213 214 + __fscache_use_cookie(cookie); 210 215 if (fscache_submit_exclusive_op(object, op) < 0) 211 216 goto nobufs; 212 217 spin_unlock(&cookie->lock); ··· 220 217 return 0; 221 218 222 219 nobufs: 220 + wake_cookie = __fscache_unuse_cookie(cookie); 223 221 spin_unlock(&cookie->lock); 224 222 kfree(op); 223 + if (wake_cookie) 224 + __fscache_wake_unused_cookie(cookie); 225 225 fscache_stat(&fscache_n_attr_changed_nobufs); 226 226 _leave(" = %d", -ENOBUFS); 227 227 return -ENOBUFS; ··· 269 263 } 270 264 271 265 fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op); 272 - atomic_inc(&cookie->n_active); 273 266 op->op.flags = FSCACHE_OP_MYTHREAD | 274 267 (1UL << FSCACHE_OP_WAITING) | 275 268 (1UL << FSCACHE_OP_UNUSE_COOKIE); ··· 389 384 { 390 385 struct fscache_retrieval *op; 391 386 struct fscache_object *object; 387 + bool wake_cookie = false; 392 388 int ret; 393 389 394 390 _enter("%p,%p,,,", cookie, page); ··· 411 405 return -ERESTARTSYS; 412 406 413 407 op = fscache_alloc_retrieval(cookie, page->mapping, 414 - end_io_func,context); 408 + end_io_func, context); 415 409 if (!op) { 416 410 _leave(" = -ENOMEM"); 417 411 return -ENOMEM; ··· 420 414 421 415 spin_lock(&cookie->lock); 422 416 423 - if (hlist_empty(&cookie->backing_objects)) 417 + if (!fscache_cookie_enabled(cookie) || 418 + hlist_empty(&cookie->backing_objects)) 424 419 goto nobufs_unlock; 425 420 object = hlist_entry(cookie->backing_objects.first, 426 421 struct fscache_object, cookie_link); 427 422 428 423 ASSERT(test_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags)); 429 424 425 + __fscache_use_cookie(cookie); 430 426 atomic_inc(&object->n_reads); 431 427 __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); 432 428 ··· 483 475 484 476 nobufs_unlock_dec: 485 477 atomic_dec(&object->n_reads); 478 + wake_cookie = __fscache_unuse_cookie(cookie); 486 479 nobufs_unlock: 487 480 spin_unlock(&cookie->lock); 488 - atomic_dec(&cookie->n_active); 481 + if (wake_cookie) 482 + __fscache_wake_unused_cookie(cookie); 489 483 kfree(op); 490 484 nobufs: 491 485 fscache_stat(&fscache_n_retrievals_nobufs); ··· 524 514 { 525 515 struct fscache_retrieval *op; 526 516 struct fscache_object *object; 517 + bool wake_cookie = false; 527 518 int ret; 528 519 529 520 _enter("%p,,%d,,,", cookie, *nr_pages); ··· 553 542 554 543 spin_lock(&cookie->lock); 555 544 556 - if (hlist_empty(&cookie->backing_objects)) 545 + if (!fscache_cookie_enabled(cookie) || 546 + hlist_empty(&cookie->backing_objects)) 557 547 goto nobufs_unlock; 558 548 object = hlist_entry(cookie->backing_objects.first, 559 549 struct fscache_object, cookie_link); 560 550 551 + __fscache_use_cookie(cookie); 561 552 atomic_inc(&object->n_reads); 562 553 __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); 563 554 ··· 614 601 615 602 nobufs_unlock_dec: 616 603 atomic_dec(&object->n_reads); 604 + wake_cookie = __fscache_unuse_cookie(cookie); 617 605 nobufs_unlock: 618 606 spin_unlock(&cookie->lock); 619 - atomic_dec(&cookie->n_active); 620 607 kfree(op); 608 + if (wake_cookie) 609 + __fscache_wake_unused_cookie(cookie); 621 610 nobufs: 622 611 fscache_stat(&fscache_n_retrievals_nobufs); 623 612 _leave(" = -ENOBUFS"); ··· 641 626 { 642 627 struct fscache_retrieval *op; 643 628 struct fscache_object *object; 629 + bool wake_cookie = false; 644 630 int ret; 645 631 646 632 _enter("%p,%p,,,", cookie, page); ··· 669 653 670 654 spin_lock(&cookie->lock); 671 655 672 - if (hlist_empty(&cookie->backing_objects)) 656 + if (!fscache_cookie_enabled(cookie) || 657 + hlist_empty(&cookie->backing_objects)) 673 658 goto nobufs_unlock; 674 659 object = hlist_entry(cookie->backing_objects.first, 675 660 struct fscache_object, cookie_link); 676 661 662 + __fscache_use_cookie(cookie); 677 663 if (fscache_submit_op(object, &op->op) < 0) 678 - goto nobufs_unlock; 664 + goto nobufs_unlock_dec; 679 665 spin_unlock(&cookie->lock); 680 666 681 667 fscache_stat(&fscache_n_alloc_ops); ··· 707 689 _leave(" = %d", ret); 708 690 return ret; 709 691 692 + nobufs_unlock_dec: 693 + wake_cookie = __fscache_unuse_cookie(cookie); 710 694 nobufs_unlock: 711 695 spin_unlock(&cookie->lock); 712 - atomic_dec(&cookie->n_active); 713 696 kfree(op); 697 + if (wake_cookie) 698 + __fscache_wake_unused_cookie(cookie); 714 699 nobufs: 715 700 fscache_stat(&fscache_n_allocs_nobufs); 716 701 _leave(" = -ENOBUFS"); ··· 910 889 { 911 890 struct fscache_storage *op; 912 891 struct fscache_object *object; 892 + bool wake_cookie = false; 913 893 int ret; 914 894 915 895 _enter("%p,%x,", cookie, (u32) page->flags); ··· 942 920 ret = -ENOBUFS; 943 921 spin_lock(&cookie->lock); 944 922 945 - if (hlist_empty(&cookie->backing_objects)) 923 + if (!fscache_cookie_enabled(cookie) || 924 + hlist_empty(&cookie->backing_objects)) 946 925 goto nobufs; 947 926 object = hlist_entry(cookie->backing_objects.first, 948 927 struct fscache_object, cookie_link); ··· 980 957 op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); 981 958 op->store_limit = object->store_limit; 982 959 983 - atomic_inc(&cookie->n_active); 960 + __fscache_use_cookie(cookie); 984 961 if (fscache_submit_op(object, &op->op) < 0) 985 962 goto submit_failed; 986 963 ··· 1007 984 return 0; 1008 985 1009 986 submit_failed: 1010 - atomic_dec(&cookie->n_active); 1011 987 spin_lock(&cookie->stores_lock); 1012 988 radix_tree_delete(&cookie->stores, page->index); 1013 989 spin_unlock(&cookie->stores_lock); 990 + wake_cookie = __fscache_unuse_cookie(cookie); 1014 991 page_cache_release(page); 1015 992 ret = -ENOBUFS; 1016 993 goto nobufs; ··· 1022 999 spin_unlock(&cookie->lock); 1023 1000 radix_tree_preload_end(); 1024 1001 kfree(op); 1002 + if (wake_cookie) 1003 + __fscache_wake_unused_cookie(cookie); 1025 1004 fscache_stat(&fscache_n_stores_nobufs); 1026 1005 _leave(" = -ENOBUFS"); 1027 1006 return -ENOBUFS;
+11
fs/nfs/Kconfig
··· 140 140 If the NFS client is unchanged from the upstream kernel, this 141 141 option should be set to the default "kernel.org". 142 142 143 + config NFS_V4_1_MIGRATION 144 + bool "NFSv4.1 client support for migration" 145 + depends on NFS_V4_1 146 + default n 147 + help 148 + This option makes the NFS client advertise to NFSv4.1 servers that 149 + it can support NFSv4 migration. 150 + 151 + The NFSv4.1 pieces of the Linux NFSv4 migration implementation are 152 + still experimental. If you are not an NFSv4 developer, say N here. 153 + 143 154 config NFS_V4_SECURITY_LABEL 144 155 bool 145 156 depends on NFS_V4_2 && SECURITY
+1 -2
fs/nfs/callback.c
··· 164 164 svc_xprt_put(serv->sv_bc_xprt); 165 165 serv->sv_bc_xprt = NULL; 166 166 } 167 - dprintk("--> %s return %ld\n", __func__, 168 - IS_ERR(rqstp) ? PTR_ERR(rqstp) : 0); 167 + dprintk("--> %s return %d\n", __func__, PTR_ERR_OR_ZERO(rqstp)); 169 168 return rqstp; 170 169 } 171 170
+8 -2
fs/nfs/client.c
··· 590 590 591 591 if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags)) 592 592 args.flags |= RPC_CLNT_CREATE_DISCRTRY; 593 + if (test_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags)) 594 + args.flags |= RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT; 593 595 if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags)) 594 596 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; 595 597 if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags)) ··· 786 784 goto error; 787 785 788 786 server->port = data->nfs_server.port; 787 + server->auth_info = data->auth_info; 789 788 790 - error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); 789 + error = nfs_init_server_rpcclient(server, &timeparms, 790 + data->selected_flavor); 791 791 if (error < 0) 792 792 goto error; 793 793 ··· 930 926 target->acdirmax = source->acdirmax; 931 927 target->caps = source->caps; 932 928 target->options = source->options; 929 + target->auth_info = source->auth_info; 933 930 } 934 931 EXPORT_SYMBOL_GPL(nfs_server_copy_userdata); 935 932 ··· 948 943 } 949 944 EXPORT_SYMBOL_GPL(nfs_server_insert_lists); 950 945 951 - static void nfs_server_remove_lists(struct nfs_server *server) 946 + void nfs_server_remove_lists(struct nfs_server *server) 952 947 { 953 948 struct nfs_client *clp = server->nfs_client; 954 949 struct nfs_net *nn; ··· 965 960 966 961 synchronize_rcu(); 967 962 } 963 + EXPORT_SYMBOL_GPL(nfs_server_remove_lists); 968 964 969 965 /* 970 966 * Allocate and initialise a server record
+8 -2
fs/nfs/dir.c
··· 1139 1139 if (inode && S_ISDIR(inode->i_mode)) { 1140 1140 /* Purge readdir caches. */ 1141 1141 nfs_zap_caches(inode); 1142 - if (dentry->d_flags & DCACHE_DISCONNECTED) 1142 + /* 1143 + * We can't d_drop the root of a disconnected tree: 1144 + * its d_hash is on the s_anon list and d_drop() would hide 1145 + * it from shrink_dcache_for_unmount(), leading to busy 1146 + * inodes on unmount and further oopses. 1147 + */ 1148 + if (IS_ROOT(dentry)) 1143 1149 goto out_valid; 1144 1150 } 1145 1151 /* If we have submounts, don't unhash ! */ ··· 1387 1381 1388 1382 static int do_open(struct inode *inode, struct file *filp) 1389 1383 { 1390 - nfs_fscache_set_inode_cookie(inode, filp); 1384 + nfs_fscache_open_file(inode, filp); 1391 1385 return 0; 1392 1386 } 1393 1387
+59 -145
fs/nfs/fscache.c
··· 39 39 /* create a cache index for looking up filehandles */ 40 40 clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index, 41 41 &nfs_fscache_server_index_def, 42 - clp); 42 + clp, true); 43 43 dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n", 44 44 clp, clp->fscache); 45 45 } ··· 139 139 /* create a cache index for looking up filehandles */ 140 140 nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache, 141 141 &nfs_fscache_super_index_def, 142 - nfss); 142 + nfss, true); 143 143 dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n", 144 144 nfss, nfss->fscache); 145 145 return; ··· 178 178 /* 179 179 * Initialise the per-inode cache cookie pointer for an NFS inode. 180 180 */ 181 - void nfs_fscache_init_inode_cookie(struct inode *inode) 181 + void nfs_fscache_init_inode(struct inode *inode) 182 182 { 183 - NFS_I(inode)->fscache = NULL; 184 - if (S_ISREG(inode->i_mode)) 185 - set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); 186 - } 187 - 188 - /* 189 - * Get the per-inode cache cookie for an NFS inode. 190 - */ 191 - static void nfs_fscache_enable_inode_cookie(struct inode *inode) 192 - { 193 - struct super_block *sb = inode->i_sb; 194 183 struct nfs_inode *nfsi = NFS_I(inode); 195 184 196 - if (nfsi->fscache || !NFS_FSCACHE(inode)) 185 + nfsi->fscache = NULL; 186 + if (!S_ISREG(inode->i_mode)) 197 187 return; 198 - 199 - if ((NFS_SB(sb)->options & NFS_OPTION_FSCACHE)) { 200 - nfsi->fscache = fscache_acquire_cookie( 201 - NFS_SB(sb)->fscache, 202 - &nfs_fscache_inode_object_def, 203 - nfsi); 204 - 205 - dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n", 206 - sb, nfsi, nfsi->fscache); 207 - } 188 + nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache, 189 + &nfs_fscache_inode_object_def, 190 + nfsi, false); 208 191 } 209 192 210 193 /* 211 194 * Release a per-inode cookie. 212 195 */ 213 - void nfs_fscache_release_inode_cookie(struct inode *inode) 196 + void nfs_fscache_clear_inode(struct inode *inode) 214 197 { 215 198 struct nfs_inode *nfsi = NFS_I(inode); 199 + struct fscache_cookie *cookie = nfs_i_fscache(inode); 216 200 217 - dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", 218 - nfsi, nfsi->fscache); 201 + dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie); 219 202 220 - fscache_relinquish_cookie(nfsi->fscache, 0); 203 + fscache_relinquish_cookie(cookie, false); 221 204 nfsi->fscache = NULL; 222 205 } 223 206 224 - /* 225 - * Retire a per-inode cookie, destroying the data attached to it. 226 - */ 227 - void nfs_fscache_zap_inode_cookie(struct inode *inode) 207 + static bool nfs_fscache_can_enable(void *data) 228 208 { 229 - struct nfs_inode *nfsi = NFS_I(inode); 209 + struct inode *inode = data; 230 210 231 - dfprintk(FSCACHE, "NFS: zapping cookie (0x%p/0x%p)\n", 232 - nfsi, nfsi->fscache); 233 - 234 - fscache_relinquish_cookie(nfsi->fscache, 1); 235 - nfsi->fscache = NULL; 211 + return !inode_is_open_for_write(inode); 236 212 } 237 213 238 214 /* 239 - * Turn off the cache with regard to a per-inode cookie if opened for writing, 240 - * invalidating all the pages in the page cache relating to the associated 241 - * inode to clear the per-page caching. 215 + * Enable or disable caching for a file that is being opened as appropriate. 216 + * The cookie is allocated when the inode is initialised, but is not enabled at 217 + * that time. Enablement is deferred to file-open time to avoid stat() and 218 + * access() thrashing the cache. 219 + * 220 + * For now, with NFS, only regular files that are open read-only will be able 221 + * to use the cache. 222 + * 223 + * We enable the cache for an inode if we open it read-only and it isn't 224 + * currently open for writing. We disable the cache if the inode is open 225 + * write-only. 226 + * 227 + * The caller uses the file struct to pin i_writecount on the inode before 228 + * calling us when a file is opened for writing, so we can make use of that. 229 + * 230 + * Note that this may be invoked multiple times in parallel by parallel 231 + * nfs_open() functions. 242 232 */ 243 - static void nfs_fscache_disable_inode_cookie(struct inode *inode) 233 + void nfs_fscache_open_file(struct inode *inode, struct file *filp) 244 234 { 245 - clear_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); 235 + struct nfs_inode *nfsi = NFS_I(inode); 236 + struct fscache_cookie *cookie = nfs_i_fscache(inode); 246 237 247 - if (NFS_I(inode)->fscache) { 248 - dfprintk(FSCACHE, 249 - "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); 238 + if (!fscache_cookie_valid(cookie)) 239 + return; 250 240 251 - /* Need to uncache any pages attached to this inode that 252 - * fscache knows about before turning off the cache. 253 - */ 254 - fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode); 255 - nfs_fscache_zap_inode_cookie(inode); 241 + if (inode_is_open_for_write(inode)) { 242 + dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi); 243 + clear_bit(NFS_INO_FSCACHE, &nfsi->flags); 244 + fscache_disable_cookie(cookie, true); 245 + fscache_uncache_all_inode_pages(cookie, inode); 246 + } else { 247 + dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi); 248 + fscache_enable_cookie(cookie, nfs_fscache_can_enable, inode); 249 + if (fscache_cookie_enabled(cookie)) 250 + set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); 256 251 } 257 252 } 258 - 259 - /* 260 - * wait_on_bit() sleep function for uninterruptible waiting 261 - */ 262 - static int nfs_fscache_wait_bit(void *flags) 263 - { 264 - schedule(); 265 - return 0; 266 - } 267 - 268 - /* 269 - * Lock against someone else trying to also acquire or relinquish a cookie 270 - */ 271 - static inline void nfs_fscache_inode_lock(struct inode *inode) 272 - { 273 - struct nfs_inode *nfsi = NFS_I(inode); 274 - 275 - while (test_and_set_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags)) 276 - wait_on_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK, 277 - nfs_fscache_wait_bit, TASK_UNINTERRUPTIBLE); 278 - } 279 - 280 - /* 281 - * Unlock cookie management lock 282 - */ 283 - static inline void nfs_fscache_inode_unlock(struct inode *inode) 284 - { 285 - struct nfs_inode *nfsi = NFS_I(inode); 286 - 287 - smp_mb__before_clear_bit(); 288 - clear_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags); 289 - smp_mb__after_clear_bit(); 290 - wake_up_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK); 291 - } 292 - 293 - /* 294 - * Decide if we should enable or disable local caching for this inode. 295 - * - For now, with NFS, only regular files that are open read-only will be able 296 - * to use the cache. 297 - * - May be invoked multiple times in parallel by parallel nfs_open() functions. 298 - */ 299 - void nfs_fscache_set_inode_cookie(struct inode *inode, struct file *filp) 300 - { 301 - if (NFS_FSCACHE(inode)) { 302 - nfs_fscache_inode_lock(inode); 303 - if ((filp->f_flags & O_ACCMODE) != O_RDONLY) 304 - nfs_fscache_disable_inode_cookie(inode); 305 - else 306 - nfs_fscache_enable_inode_cookie(inode); 307 - nfs_fscache_inode_unlock(inode); 308 - } 309 - } 310 - EXPORT_SYMBOL_GPL(nfs_fscache_set_inode_cookie); 311 - 312 - /* 313 - * Replace a per-inode cookie due to revalidation detecting a file having 314 - * changed on the server. 315 - */ 316 - void nfs_fscache_reset_inode_cookie(struct inode *inode) 317 - { 318 - struct nfs_inode *nfsi = NFS_I(inode); 319 - struct nfs_server *nfss = NFS_SERVER(inode); 320 - NFS_IFDEBUG(struct fscache_cookie *old = nfsi->fscache); 321 - 322 - nfs_fscache_inode_lock(inode); 323 - if (nfsi->fscache) { 324 - /* retire the current fscache cache and get a new one */ 325 - fscache_relinquish_cookie(nfsi->fscache, 1); 326 - 327 - nfsi->fscache = fscache_acquire_cookie( 328 - nfss->nfs_client->fscache, 329 - &nfs_fscache_inode_object_def, 330 - nfsi); 331 - 332 - dfprintk(FSCACHE, 333 - "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n", 334 - nfss, nfsi, old, nfsi->fscache); 335 - } 336 - nfs_fscache_inode_unlock(inode); 337 - } 253 + EXPORT_SYMBOL_GPL(nfs_fscache_open_file); 338 254 339 255 /* 340 256 * Release the caching state associated with a page, if the page isn't busy ··· 260 344 int nfs_fscache_release_page(struct page *page, gfp_t gfp) 261 345 { 262 346 if (PageFsCache(page)) { 263 - struct nfs_inode *nfsi = NFS_I(page->mapping->host); 264 - struct fscache_cookie *cookie = nfsi->fscache; 347 + struct fscache_cookie *cookie = nfs_i_fscache(page->mapping->host); 265 348 266 349 BUG_ON(!cookie); 267 350 dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", 268 - cookie, page, nfsi); 351 + cookie, page, NFS_I(page->mapping->host)); 269 352 270 353 if (!fscache_maybe_release_page(cookie, page, gfp)) 271 354 return 0; ··· 282 367 */ 283 368 void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode) 284 369 { 285 - struct nfs_inode *nfsi = NFS_I(inode); 286 - struct fscache_cookie *cookie = nfsi->fscache; 370 + struct fscache_cookie *cookie = nfs_i_fscache(inode); 287 371 288 372 BUG_ON(!cookie); 289 373 290 374 dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n", 291 - cookie, page, nfsi); 375 + cookie, page, NFS_I(inode)); 292 376 293 377 fscache_wait_on_page_write(cookie, page); 294 378 ··· 331 417 332 418 dfprintk(FSCACHE, 333 419 "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n", 334 - NFS_I(inode)->fscache, page, page->index, page->flags, inode); 420 + nfs_i_fscache(inode), page, page->index, page->flags, inode); 335 421 336 - ret = fscache_read_or_alloc_page(NFS_I(inode)->fscache, 422 + ret = fscache_read_or_alloc_page(nfs_i_fscache(inode), 337 423 page, 338 424 nfs_readpage_from_fscache_complete, 339 425 ctx, ··· 373 459 int ret; 374 460 375 461 dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n", 376 - NFS_I(inode)->fscache, npages, inode); 462 + nfs_i_fscache(inode), npages, inode); 377 463 378 - ret = fscache_read_or_alloc_pages(NFS_I(inode)->fscache, 464 + ret = fscache_read_or_alloc_pages(nfs_i_fscache(inode), 379 465 mapping, pages, nr_pages, 380 466 nfs_readpage_from_fscache_complete, 381 467 ctx, ··· 420 506 421 507 dfprintk(FSCACHE, 422 508 "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n", 423 - NFS_I(inode)->fscache, page, page->index, page->flags, sync); 509 + nfs_i_fscache(inode), page, page->index, page->flags, sync); 424 510 425 - ret = fscache_write_page(NFS_I(inode)->fscache, page, GFP_KERNEL); 511 + ret = fscache_write_page(nfs_i_fscache(inode), page, GFP_KERNEL); 426 512 dfprintk(FSCACHE, 427 513 "NFS: readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n", 428 514 page, page->index, page->flags, ret); 429 515 430 516 if (ret != 0) { 431 - fscache_uncache_page(NFS_I(inode)->fscache, page); 517 + fscache_uncache_page(nfs_i_fscache(inode), page); 432 518 nfs_add_fscache_stats(inode, 433 519 NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1); 434 520 nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
+7 -11
fs/nfs/fscache.h
··· 76 76 extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int); 77 77 extern void nfs_fscache_release_super_cookie(struct super_block *); 78 78 79 - extern void nfs_fscache_init_inode_cookie(struct inode *); 80 - extern void nfs_fscache_release_inode_cookie(struct inode *); 81 - extern void nfs_fscache_zap_inode_cookie(struct inode *); 82 - extern void nfs_fscache_set_inode_cookie(struct inode *, struct file *); 83 - extern void nfs_fscache_reset_inode_cookie(struct inode *); 79 + extern void nfs_fscache_init_inode(struct inode *); 80 + extern void nfs_fscache_clear_inode(struct inode *); 81 + extern void nfs_fscache_open_file(struct inode *, struct file *); 84 82 85 83 extern void __nfs_fscache_invalidate_page(struct page *, struct inode *); 86 84 extern int nfs_fscache_release_page(struct page *, gfp_t); ··· 185 187 186 188 static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} 187 189 188 - static inline void nfs_fscache_init_inode_cookie(struct inode *inode) {} 189 - static inline void nfs_fscache_release_inode_cookie(struct inode *inode) {} 190 - static inline void nfs_fscache_zap_inode_cookie(struct inode *inode) {} 191 - static inline void nfs_fscache_set_inode_cookie(struct inode *inode, 192 - struct file *filp) {} 193 - static inline void nfs_fscache_reset_inode_cookie(struct inode *inode) {} 190 + static inline void nfs_fscache_init_inode(struct inode *inode) {} 191 + static inline void nfs_fscache_clear_inode(struct inode *inode) {} 192 + static inline void nfs_fscache_open_file(struct inode *inode, 193 + struct file *filp) {} 194 194 195 195 static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp) 196 196 {
+7 -9
fs/nfs/inode.c
··· 122 122 WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files)); 123 123 nfs_zap_acl_cache(inode); 124 124 nfs_access_zap_cache(inode); 125 - nfs_fscache_release_inode_cookie(inode); 125 + nfs_fscache_clear_inode(inode); 126 126 } 127 127 EXPORT_SYMBOL_GPL(nfs_clear_inode); 128 128 ··· 272 272 int error; 273 273 274 274 if (label == NULL) 275 - return; 276 - 277 - if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL) == 0) 278 - return; 279 - 280 - if (NFS_SERVER(inode)->nfs_client->cl_minorversion < 2) 281 275 return; 282 276 283 277 if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) { ··· 453 459 nfsi->attrtimeo_timestamp = now; 454 460 nfsi->access_cache = RB_ROOT; 455 461 456 - nfs_fscache_init_inode_cookie(inode); 462 + nfs_fscache_init_inode(inode); 457 463 458 464 unlock_new_inode(inode); 459 465 } else ··· 848 854 return PTR_ERR(ctx); 849 855 nfs_file_set_open_context(filp, ctx); 850 856 put_nfs_open_context(ctx); 851 - nfs_fscache_set_inode_cookie(inode, filp); 857 + nfs_fscache_open_file(inode, filp); 852 858 return 0; 853 859 } 854 860 ··· 916 922 917 923 if (nfsi->cache_validity & NFS_INO_INVALID_ACL) 918 924 nfs_zap_acl_cache(inode); 925 + 926 + nfs_setsecurity(inode, fattr, label); 919 927 920 928 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", 921 929 inode->i_sb->s_id, ··· 1205 1209 * not on the result */ 1206 1210 return nfs_fhandle_hash(fh); 1207 1211 } 1212 + EXPORT_SYMBOL_GPL(_nfs_display_fhandle_hash); 1208 1213 1209 1214 /* 1210 1215 * _nfs_display_fhandle - display an NFS file handle on the console ··· 1250 1253 } 1251 1254 } 1252 1255 } 1256 + EXPORT_SYMBOL_GPL(_nfs_display_fhandle); 1253 1257 #endif 1254 1258 1255 1259 /**
+6 -2
fs/nfs/internal.h
··· 88 88 unsigned int namlen; 89 89 unsigned int options; 90 90 unsigned int bsize; 91 - unsigned int auth_flavor_len; 92 - rpc_authflavor_t auth_flavors[1]; 91 + struct nfs_auth_info auth_info; 92 + rpc_authflavor_t selected_flavor; 93 93 char *client_address; 94 94 unsigned int version; 95 95 unsigned int minorversion; ··· 154 154 rpc_authflavor_t); 155 155 int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *); 156 156 void nfs_server_insert_lists(struct nfs_server *); 157 + void nfs_server_remove_lists(struct nfs_server *); 157 158 void nfs_init_timeout_values(struct rpc_timeout *, int, unsigned int, unsigned int); 158 159 int nfs_init_server_rpcclient(struct nfs_server *, const struct rpc_timeout *t, 159 160 rpc_authflavor_t); ··· 175 174 struct nfs_subversion *); 176 175 extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, 177 176 struct nfs_fh *); 177 + extern int nfs4_update_server(struct nfs_server *server, const char *hostname, 178 + struct sockaddr *sap, size_t salen); 178 179 extern void nfs_free_server(struct nfs_server *server); 179 180 extern struct nfs_server *nfs_clone_server(struct nfs_server *, 180 181 struct nfs_fh *, ··· 326 323 extern struct file_system_type nfs4_xdev_fs_type; 327 324 extern struct file_system_type nfs4_referral_fs_type; 328 325 #endif 326 + bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t); 329 327 struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *, 330 328 struct nfs_subversion *); 331 329 void nfs_initialise_sb(struct super_block *);
+16 -1
fs/nfs/nfs4_fs.h
··· 29 29 NFS4CLNT_SERVER_SCOPE_MISMATCH, 30 30 NFS4CLNT_PURGE_STATE, 31 31 NFS4CLNT_BIND_CONN_TO_SESSION, 32 + NFS4CLNT_MOVED, 33 + NFS4CLNT_LEASE_MOVED, 32 34 }; 33 35 34 36 #define NFS4_RENEW_TIMEOUT 0x01 ··· 52 50 const struct nfs4_state_recovery_ops *reboot_recovery_ops; 53 51 const struct nfs4_state_recovery_ops *nograce_recovery_ops; 54 52 const struct nfs4_state_maintenance_ops *state_renewal_ops; 53 + const struct nfs4_mig_recovery_ops *mig_recovery_ops; 55 54 }; 56 55 57 56 #define NFS_SEQID_CONFIRMED 1 ··· 206 203 int (*renew_lease)(struct nfs_client *, struct rpc_cred *); 207 204 }; 208 205 206 + struct nfs4_mig_recovery_ops { 207 + int (*get_locations)(struct inode *, struct nfs4_fs_locations *, 208 + struct page *, struct rpc_cred *); 209 + int (*fsid_present)(struct inode *, struct rpc_cred *); 210 + }; 211 + 209 212 extern const struct dentry_operations nfs4_dentry_operations; 210 213 211 214 /* dir.c */ ··· 222 213 extern struct file_system_type nfs4_fs_type; 223 214 224 215 /* nfs4namespace.c */ 225 - rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); 226 216 struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); 227 217 struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *, 228 218 struct nfs_fh *, struct nfs_fattr *); 219 + int nfs4_replace_transport(struct nfs_server *server, 220 + const struct nfs4_fs_locations *locations); 229 221 230 222 /* nfs4proc.c */ 231 223 extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); ··· 241 231 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); 242 232 extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *, 243 233 struct nfs4_fs_locations *, struct page *); 234 + extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *, 235 + struct page *page, struct rpc_cred *); 236 + extern int nfs4_proc_fsid_present(struct inode *, struct rpc_cred *); 244 237 extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *, 245 238 struct nfs_fh *, struct nfs_fattr *); 246 239 extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); ··· 424 411 extern void nfs4_schedule_state_manager(struct nfs_client *); 425 412 extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); 426 413 extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); 414 + extern int nfs4_schedule_migration_recovery(const struct nfs_server *); 415 + extern void nfs4_schedule_lease_moved_recovery(struct nfs_client *); 427 416 extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); 428 417 extern void nfs41_handle_server_scope(struct nfs_client *, 429 418 struct nfs41_server_scope **);
+128 -10
fs/nfs/nfs4client.c
··· 197 197 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 198 198 clp->cl_minorversion = cl_init->minorversion; 199 199 clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; 200 + clp->cl_mig_gen = 1; 200 201 return clp; 201 202 202 203 error: ··· 369 368 if (clp->cl_minorversion != 0) 370 369 __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags); 371 370 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); 371 + __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); 372 372 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); 373 373 if (error == -EINVAL) 374 374 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); ··· 926 924 dprintk("Server FSID: %llx:%llx\n", 927 925 (unsigned long long) server->fsid.major, 928 926 (unsigned long long) server->fsid.minor); 929 - dprintk("Mount FH: %d\n", mntfh->size); 927 + nfs_display_fhandle(mntfh, "Pseudo-fs root FH"); 930 928 931 929 nfs4_session_set_rwsize(server); 932 930 ··· 949 947 * Create a version 4 volume record 950 948 */ 951 949 static int nfs4_init_server(struct nfs_server *server, 952 - const struct nfs_parsed_mount_data *data) 950 + struct nfs_parsed_mount_data *data) 953 951 { 954 - rpc_authflavor_t pseudoflavor = RPC_AUTH_UNIX; 955 952 struct rpc_timeout timeparms; 956 953 int error; 957 954 ··· 962 961 /* Initialise the client representation from the mount data */ 963 962 server->flags = data->flags; 964 963 server->options = data->options; 964 + server->auth_info = data->auth_info; 965 965 966 - if (data->auth_flavor_len >= 1) 967 - pseudoflavor = data->auth_flavors[0]; 966 + /* Use the first specified auth flavor. If this flavor isn't 967 + * allowed by the server, use the SECINFO path to try the 968 + * other specified flavors */ 969 + if (data->auth_info.flavor_len >= 1) 970 + data->selected_flavor = data->auth_info.flavors[0]; 971 + else 972 + data->selected_flavor = RPC_AUTH_UNIX; 968 973 969 974 /* Get a client record */ 970 975 error = nfs4_set_client(server, ··· 978 971 (const struct sockaddr *)&data->nfs_server.address, 979 972 data->nfs_server.addrlen, 980 973 data->client_address, 981 - pseudoflavor, 974 + data->selected_flavor, 982 975 data->nfs_server.protocol, 983 976 &timeparms, 984 977 data->minorversion, ··· 998 991 999 992 server->port = data->nfs_server.port; 1000 993 1001 - error = nfs_init_server_rpcclient(server, &timeparms, pseudoflavor); 994 + error = nfs_init_server_rpcclient(server, &timeparms, 995 + data->selected_flavor); 1002 996 1003 997 error: 1004 998 /* Done */ ··· 1026 1018 if (!server) 1027 1019 return ERR_PTR(-ENOMEM); 1028 1020 1029 - auth_probe = mount_info->parsed->auth_flavor_len < 1; 1021 + auth_probe = mount_info->parsed->auth_info.flavor_len < 1; 1030 1022 1031 1023 /* set up the general RPC client */ 1032 1024 error = nfs4_init_server(server, mount_info->parsed); ··· 1054 1046 { 1055 1047 struct nfs_client *parent_client; 1056 1048 struct nfs_server *server, *parent_server; 1049 + bool auth_probe; 1057 1050 int error; 1058 1051 1059 1052 dprintk("--> nfs4_create_referral_server()\n"); ··· 1087 1078 if (error < 0) 1088 1079 goto error; 1089 1080 1090 - error = nfs4_server_common_setup(server, mntfh, 1091 - !(parent_server->flags & NFS_MOUNT_SECFLAVOUR)); 1081 + auth_probe = parent_server->auth_info.flavor_len < 1; 1082 + 1083 + error = nfs4_server_common_setup(server, mntfh, auth_probe); 1092 1084 if (error < 0) 1093 1085 goto error; 1094 1086 ··· 1100 1090 nfs_free_server(server); 1101 1091 dprintk("<-- nfs4_create_referral_server() = error %d\n", error); 1102 1092 return ERR_PTR(error); 1093 + } 1094 + 1095 + /* 1096 + * Grab the destination's particulars, including lease expiry time. 1097 + * 1098 + * Returns zero if probe succeeded and retrieved FSID matches the FSID 1099 + * we have cached. 1100 + */ 1101 + static int nfs_probe_destination(struct nfs_server *server) 1102 + { 1103 + struct inode *inode = server->super->s_root->d_inode; 1104 + struct nfs_fattr *fattr; 1105 + int error; 1106 + 1107 + fattr = nfs_alloc_fattr(); 1108 + if (fattr == NULL) 1109 + return -ENOMEM; 1110 + 1111 + /* Sanity: the probe won't work if the destination server 1112 + * does not recognize the migrated FH. */ 1113 + error = nfs_probe_fsinfo(server, NFS_FH(inode), fattr); 1114 + 1115 + nfs_free_fattr(fattr); 1116 + return error; 1117 + } 1118 + 1119 + /** 1120 + * nfs4_update_server - Move an nfs_server to a different nfs_client 1121 + * 1122 + * @server: represents FSID to be moved 1123 + * @hostname: new end-point's hostname 1124 + * @sap: new end-point's socket address 1125 + * @salen: size of "sap" 1126 + * 1127 + * The nfs_server must be quiescent before this function is invoked. 1128 + * Either its session is drained (NFSv4.1+), or its transport is 1129 + * plugged and drained (NFSv4.0). 1130 + * 1131 + * Returns zero on success, or a negative errno value. 1132 + */ 1133 + int nfs4_update_server(struct nfs_server *server, const char *hostname, 1134 + struct sockaddr *sap, size_t salen) 1135 + { 1136 + struct nfs_client *clp = server->nfs_client; 1137 + struct rpc_clnt *clnt = server->client; 1138 + struct xprt_create xargs = { 1139 + .ident = clp->cl_proto, 1140 + .net = &init_net, 1141 + .dstaddr = sap, 1142 + .addrlen = salen, 1143 + .servername = hostname, 1144 + }; 1145 + char buf[INET6_ADDRSTRLEN + 1]; 1146 + struct sockaddr_storage address; 1147 + struct sockaddr *localaddr = (struct sockaddr *)&address; 1148 + int error; 1149 + 1150 + dprintk("--> %s: move FSID %llx:%llx to \"%s\")\n", __func__, 1151 + (unsigned long long)server->fsid.major, 1152 + (unsigned long long)server->fsid.minor, 1153 + hostname); 1154 + 1155 + error = rpc_switch_client_transport(clnt, &xargs, clnt->cl_timeout); 1156 + if (error != 0) { 1157 + dprintk("<-- %s(): rpc_switch_client_transport returned %d\n", 1158 + __func__, error); 1159 + goto out; 1160 + } 1161 + 1162 + error = rpc_localaddr(clnt, localaddr, sizeof(address)); 1163 + if (error != 0) { 1164 + dprintk("<-- %s(): rpc_localaddr returned %d\n", 1165 + __func__, error); 1166 + goto out; 1167 + } 1168 + 1169 + error = -EAFNOSUPPORT; 1170 + if (rpc_ntop(localaddr, buf, sizeof(buf)) == 0) { 1171 + dprintk("<-- %s(): rpc_ntop returned %d\n", 1172 + __func__, error); 1173 + goto out; 1174 + } 1175 + 1176 + nfs_server_remove_lists(server); 1177 + error = nfs4_set_client(server, hostname, sap, salen, buf, 1178 + clp->cl_rpcclient->cl_auth->au_flavor, 1179 + clp->cl_proto, clnt->cl_timeout, 1180 + clp->cl_minorversion, clp->cl_net); 1181 + nfs_put_client(clp); 1182 + if (error != 0) { 1183 + nfs_server_insert_lists(server); 1184 + dprintk("<-- %s(): nfs4_set_client returned %d\n", 1185 + __func__, error); 1186 + goto out; 1187 + } 1188 + 1189 + if (server->nfs_client->cl_hostname == NULL) 1190 + server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL); 1191 + nfs_server_insert_lists(server); 1192 + 1193 + error = nfs_probe_destination(server); 1194 + if (error < 0) 1195 + goto out; 1196 + 1197 + dprintk("<-- %s() succeeded\n", __func__); 1198 + 1199 + out: 1200 + return error; 1103 1201 }
+1 -1
fs/nfs/nfs4file.c
··· 75 75 76 76 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 77 77 nfs_file_set_open_context(filp, ctx); 78 - nfs_fscache_set_inode_cookie(inode, filp); 78 + nfs_fscache_open_file(inode, filp); 79 79 err = 0; 80 80 81 81 out_put_ctx:
+114 -4
fs/nfs/nfs4namespace.c
··· 137 137 138 138 /** 139 139 * nfs_find_best_sec - Find a security mechanism supported locally 140 + * @server: NFS server struct 140 141 * @flavors: List of security tuples returned by SECINFO procedure 141 142 * 142 143 * Return the pseudoflavor of the first security mechanism in ··· 146 145 * is searched in the order returned from the server, per RFC 3530 147 146 * recommendation. 148 147 */ 149 - rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) 148 + static rpc_authflavor_t nfs_find_best_sec(struct nfs_server *server, 149 + struct nfs4_secinfo_flavors *flavors) 150 150 { 151 151 rpc_authflavor_t pseudoflavor; 152 152 struct nfs4_secinfo4 *secinfo; ··· 162 160 case RPC_AUTH_GSS: 163 161 pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor, 164 162 &secinfo->flavor_info); 165 - if (pseudoflavor != RPC_AUTH_MAXFLAVOR) 163 + /* make sure pseudoflavor matches sec= mount opt */ 164 + if (pseudoflavor != RPC_AUTH_MAXFLAVOR && 165 + nfs_auth_info_match(&server->auth_info, 166 + pseudoflavor)) 166 167 return pseudoflavor; 167 168 break; 168 169 } 169 170 } 171 + 172 + /* if there were any sec= options then nothing matched */ 173 + if (server->auth_info.flavor_len > 0) 174 + return -EPERM; 170 175 171 176 return RPC_AUTH_UNIX; 172 177 } ··· 196 187 goto out; 197 188 } 198 189 199 - flavor = nfs_find_best_sec(flavors); 190 + flavor = nfs_find_best_sec(NFS_SERVER(inode), flavors); 200 191 201 192 out: 202 193 put_page(page); ··· 399 390 400 391 if (client->cl_auth->au_flavor != flavor) 401 392 flavor = client->cl_auth->au_flavor; 402 - else if (!(server->flags & NFS_MOUNT_SECFLAVOUR)) { 393 + else { 403 394 rpc_authflavor_t new = nfs4_negotiate_security(dir, name); 404 395 if ((int)new >= 0) 405 396 flavor = new; ··· 408 399 out: 409 400 rpc_shutdown_client(client); 410 401 return mnt; 402 + } 403 + 404 + /* 405 + * Try one location from the fs_locations array. 406 + * 407 + * Returns zero on success, or a negative errno value. 408 + */ 409 + static int nfs4_try_replacing_one_location(struct nfs_server *server, 410 + char *page, char *page2, 411 + const struct nfs4_fs_location *location) 412 + { 413 + const size_t addr_bufsize = sizeof(struct sockaddr_storage); 414 + struct sockaddr *sap; 415 + unsigned int s; 416 + size_t salen; 417 + int error; 418 + 419 + sap = kmalloc(addr_bufsize, GFP_KERNEL); 420 + if (sap == NULL) 421 + return -ENOMEM; 422 + 423 + error = -ENOENT; 424 + for (s = 0; s < location->nservers; s++) { 425 + const struct nfs4_string *buf = &location->servers[s]; 426 + char *hostname; 427 + 428 + if (buf->len <= 0 || buf->len > PAGE_SIZE) 429 + continue; 430 + 431 + if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len) != NULL) 432 + continue; 433 + 434 + salen = nfs_parse_server_name(buf->data, buf->len, 435 + sap, addr_bufsize, server); 436 + if (salen == 0) 437 + continue; 438 + rpc_set_port(sap, NFS_PORT); 439 + 440 + error = -ENOMEM; 441 + hostname = kstrndup(buf->data, buf->len, GFP_KERNEL); 442 + if (hostname == NULL) 443 + break; 444 + 445 + error = nfs4_update_server(server, hostname, sap, salen); 446 + kfree(hostname); 447 + if (error == 0) 448 + break; 449 + } 450 + 451 + kfree(sap); 452 + return error; 453 + } 454 + 455 + /** 456 + * nfs4_replace_transport - set up transport to destination server 457 + * 458 + * @server: export being migrated 459 + * @locations: fs_locations array 460 + * 461 + * Returns zero on success, or a negative errno value. 462 + * 463 + * The client tries all the entries in the "locations" array, in the 464 + * order returned by the server, until one works or the end of the 465 + * array is reached. 466 + */ 467 + int nfs4_replace_transport(struct nfs_server *server, 468 + const struct nfs4_fs_locations *locations) 469 + { 470 + char *page = NULL, *page2 = NULL; 471 + int loc, error; 472 + 473 + error = -ENOENT; 474 + if (locations == NULL || locations->nlocations <= 0) 475 + goto out; 476 + 477 + error = -ENOMEM; 478 + page = (char *) __get_free_page(GFP_USER); 479 + if (!page) 480 + goto out; 481 + page2 = (char *) __get_free_page(GFP_USER); 482 + if (!page2) 483 + goto out; 484 + 485 + for (loc = 0; loc < locations->nlocations; loc++) { 486 + const struct nfs4_fs_location *location = 487 + &locations->locations[loc]; 488 + 489 + if (location == NULL || location->nservers <= 0 || 490 + location->rootpath.ncomponents == 0) 491 + continue; 492 + 493 + error = nfs4_try_replacing_one_location(server, page, 494 + page2, location); 495 + if (error == 0) 496 + break; 497 + } 498 + 499 + out: 500 + free_page((unsigned long)page); 501 + free_page((unsigned long)page2); 502 + return error; 411 503 }
+416 -54
fs/nfs/nfs4proc.c
··· 105 105 if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0) 106 106 return NULL; 107 107 108 - if (NFS_SERVER(dir)->nfs_client->cl_minorversion < 2) 109 - return NULL; 110 - 111 108 err = security_dentry_init_security(dentry, sattr->ia_mode, 112 109 &dentry->d_name, (void **)&label->label, &label->len); 113 110 if (err == 0) ··· 381 384 case -NFS4ERR_STALE_CLIENTID: 382 385 nfs4_schedule_lease_recovery(clp); 383 386 goto wait_on_recovery; 387 + case -NFS4ERR_MOVED: 388 + ret = nfs4_schedule_migration_recovery(server); 389 + if (ret < 0) 390 + break; 391 + goto wait_on_recovery; 392 + case -NFS4ERR_LEASE_MOVED: 393 + nfs4_schedule_lease_moved_recovery(clp); 394 + goto wait_on_recovery; 384 395 #if defined(CONFIG_NFS_V4_1) 385 396 case -NFS4ERR_BADSESSION: 386 397 case -NFS4ERR_BADSLOT: ··· 436 431 return nfs4_map_errors(ret); 437 432 wait_on_recovery: 438 433 ret = nfs4_wait_clnt_recover(clp); 434 + if (test_bit(NFS_MIG_FAILED, &server->mig_status)) 435 + return -EIO; 439 436 if (ret == 0) 440 437 exception->retry = 1; 441 438 return ret; ··· 1325 1318 int ret; 1326 1319 1327 1320 if (!data->rpc_done) { 1328 - ret = data->rpc_status; 1329 - goto err; 1321 + if (data->rpc_status) { 1322 + ret = data->rpc_status; 1323 + goto err; 1324 + } 1325 + /* cached opens have already been processed */ 1326 + goto update; 1330 1327 } 1331 - 1332 - ret = -ESTALE; 1333 - if (!(data->f_attr.valid & NFS_ATTR_FATTR_TYPE) || 1334 - !(data->f_attr.valid & NFS_ATTR_FATTR_FILEID) || 1335 - !(data->f_attr.valid & NFS_ATTR_FATTR_CHANGE)) 1336 - goto err; 1337 - 1338 - ret = -ENOMEM; 1339 - state = nfs4_get_open_state(inode, data->owner); 1340 - if (state == NULL) 1341 - goto err; 1342 1328 1343 1329 ret = nfs_refresh_inode(inode, &data->f_attr); 1344 1330 if (ret) 1345 1331 goto err; 1346 1332 1347 - nfs_setsecurity(inode, &data->f_attr, data->f_label); 1348 - 1349 1333 if (data->o_res.delegation_type != 0) 1350 1334 nfs4_opendata_check_deleg(data, state); 1335 + update: 1351 1336 update_open_stateid(state, &data->o_res.stateid, NULL, 1352 1337 data->o_arg.fmode); 1338 + atomic_inc(&state->count); 1353 1339 1354 1340 return state; 1355 1341 err: ··· 1574 1574 case -NFS4ERR_EXPIRED: 1575 1575 /* Don't recall a delegation if it was lost */ 1576 1576 nfs4_schedule_lease_recovery(server->nfs_client); 1577 + return -EAGAIN; 1578 + case -NFS4ERR_MOVED: 1579 + nfs4_schedule_migration_recovery(server); 1580 + return -EAGAIN; 1581 + case -NFS4ERR_LEASE_MOVED: 1582 + nfs4_schedule_lease_moved_recovery(server->nfs_client); 1577 1583 return -EAGAIN; 1578 1584 case -NFS4ERR_DELEG_REVOKED: 1579 1585 case -NFS4ERR_ADMIN_REVOKED: ··· 2703 2697 nfs4_close_state(ctx->state, ctx->mode); 2704 2698 } 2705 2699 2700 + #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) 2701 + #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL) 2702 + #define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_CHANGE_SECURITY_LABEL - 1UL) 2703 + 2706 2704 static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) 2707 2705 { 2708 2706 struct nfs4_server_caps_arg args = { ··· 2722 2712 2723 2713 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 2724 2714 if (status == 0) { 2715 + /* Sanity check the server answers */ 2716 + switch (server->nfs_client->cl_minorversion) { 2717 + case 0: 2718 + res.attr_bitmask[1] &= FATTR4_WORD1_NFS40_MASK; 2719 + res.attr_bitmask[2] = 0; 2720 + break; 2721 + case 1: 2722 + res.attr_bitmask[2] &= FATTR4_WORD2_NFS41_MASK; 2723 + break; 2724 + case 2: 2725 + res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; 2726 + } 2725 2727 memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); 2726 2728 server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| 2727 2729 NFS_CAP_SYMLINKS|NFS_CAP_FILEID| 2728 2730 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| 2729 2731 NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| 2730 - NFS_CAP_CTIME|NFS_CAP_MTIME); 2732 + NFS_CAP_CTIME|NFS_CAP_MTIME| 2733 + NFS_CAP_SECURITY_LABEL); 2731 2734 if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) 2732 2735 server->caps |= NFS_CAP_ACLS; 2733 2736 if (res.has_links != 0) ··· 2769 2746 #endif 2770 2747 memcpy(server->attr_bitmask_nl, res.attr_bitmask, 2771 2748 sizeof(server->attr_bitmask)); 2749 + server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 2772 2750 2773 - if (server->caps & NFS_CAP_SECURITY_LABEL) { 2774 - server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 2775 - res.attr_bitmask[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 2776 - } 2777 2751 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask)); 2778 2752 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; 2779 2753 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 2754 + server->cache_consistency_bitmask[2] = 0; 2780 2755 server->acl_bitmask = res.acl_bitmask; 2781 2756 server->fh_expire_type = res.fh_expire_type; 2782 2757 } ··· 2885 2864 int status = -EPERM; 2886 2865 size_t i; 2887 2866 2888 - for (i = 0; i < ARRAY_SIZE(flav_array); i++) { 2889 - status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); 2890 - if (status == -NFS4ERR_WRONGSEC || status == -EACCES) 2891 - continue; 2892 - break; 2867 + if (server->auth_info.flavor_len > 0) { 2868 + /* try each flavor specified by user */ 2869 + for (i = 0; i < server->auth_info.flavor_len; i++) { 2870 + status = nfs4_lookup_root_sec(server, fhandle, info, 2871 + server->auth_info.flavors[i]); 2872 + if (status == -NFS4ERR_WRONGSEC || status == -EACCES) 2873 + continue; 2874 + break; 2875 + } 2876 + } else { 2877 + /* no flavors specified by user, try default list */ 2878 + for (i = 0; i < ARRAY_SIZE(flav_array); i++) { 2879 + status = nfs4_lookup_root_sec(server, fhandle, info, 2880 + flav_array[i]); 2881 + if (status == -NFS4ERR_WRONGSEC || status == -EACCES) 2882 + continue; 2883 + break; 2884 + } 2893 2885 } 2894 2886 2895 2887 /* ··· 2943 2909 case false: 2944 2910 status = nfs4_lookup_root(server, fhandle, info); 2945 2911 if (status != -NFS4ERR_WRONGSEC) 2946 - break; 2947 - /* Did user force a 'sec=' mount option? */ 2948 - if (server->flags & NFS_MOUNT_SECFLAVOUR) 2949 2912 break; 2950 2913 default: 2951 2914 status = nfs4_do_find_root_sec(server, fhandle, info); ··· 3012 2981 status = nfs4_proc_fs_locations(client, dir, name, locations, page); 3013 2982 if (status != 0) 3014 2983 goto out; 3015 - /* Make sure server returned a different fsid for the referral */ 2984 + 2985 + /* 2986 + * If the fsid didn't change, this is a migration event, not a 2987 + * referral. Cause us to drop into the exception handler, which 2988 + * will kick off migration recovery. 2989 + */ 3016 2990 if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { 3017 2991 dprintk("%s: server did not return a different fsid for" 3018 2992 " a referral at %s\n", __func__, name->name); 3019 - status = -EIO; 2993 + status = -NFS4ERR_MOVED; 3020 2994 goto out; 3021 2995 } 3022 2996 /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */ ··· 3200 3164 case -NFS4ERR_WRONGSEC: 3201 3165 err = -EPERM; 3202 3166 if (client != *clnt) 3203 - goto out; 3204 - /* No security negotiation if the user specified 'sec=' */ 3205 - if (NFS_SERVER(dir)->flags & NFS_MOUNT_SECFLAVOUR) 3206 3167 goto out; 3207 3168 client = nfs4_create_sec_client(client, dir, name); 3208 3169 if (IS_ERR(client)) ··· 4254 4221 unsigned long timestamp = data->timestamp; 4255 4222 4256 4223 trace_nfs4_renew_async(clp, task->tk_status); 4257 - if (task->tk_status < 0) { 4224 + switch (task->tk_status) { 4225 + case 0: 4226 + break; 4227 + case -NFS4ERR_LEASE_MOVED: 4228 + nfs4_schedule_lease_moved_recovery(clp); 4229 + break; 4230 + default: 4258 4231 /* Unless we're shutting down, schedule state recovery! */ 4259 4232 if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0) 4260 4233 return; ··· 4614 4575 struct nfs4_label label = {0, 0, buflen, buf}; 4615 4576 4616 4577 u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL }; 4617 - struct nfs4_getattr_arg args = { 4578 + struct nfs4_getattr_arg arg = { 4618 4579 .fh = NFS_FH(inode), 4619 4580 .bitmask = bitmask, 4620 4581 }; ··· 4625 4586 }; 4626 4587 struct rpc_message msg = { 4627 4588 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETATTR], 4628 - .rpc_argp = &args, 4589 + .rpc_argp = &arg, 4629 4590 .rpc_resp = &res, 4630 4591 }; 4631 4592 int ret; 4632 4593 4633 4594 nfs_fattr_init(&fattr); 4634 4595 4635 - ret = rpc_call_sync(server->client, &msg, 0); 4596 + ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 0); 4636 4597 if (ret) 4637 4598 return ret; 4638 4599 if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL)) ··· 4669 4630 struct iattr sattr = {0}; 4670 4631 struct nfs_server *server = NFS_SERVER(inode); 4671 4632 const u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL }; 4672 - struct nfs_setattrargs args = { 4633 + struct nfs_setattrargs arg = { 4673 4634 .fh = NFS_FH(inode), 4674 4635 .iap = &sattr, 4675 4636 .server = server, ··· 4683 4644 }; 4684 4645 struct rpc_message msg = { 4685 4646 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR], 4686 - .rpc_argp = &args, 4647 + .rpc_argp = &arg, 4687 4648 .rpc_resp = &res, 4688 4649 }; 4689 4650 int status; 4690 4651 4691 - nfs4_stateid_copy(&args.stateid, &zero_stateid); 4652 + nfs4_stateid_copy(&arg.stateid, &zero_stateid); 4692 4653 4693 - status = rpc_call_sync(server->client, &msg, 0); 4654 + status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 4694 4655 if (status) 4695 4656 dprintk("%s failed: %d\n", __func__, status); 4696 4657 ··· 4774 4735 if (state == NULL) 4775 4736 break; 4776 4737 if (nfs4_schedule_stateid_recovery(server, state) < 0) 4777 - goto stateid_invalid; 4738 + goto recovery_failed; 4778 4739 goto wait_on_recovery; 4779 4740 case -NFS4ERR_EXPIRED: 4780 4741 if (state != NULL) { 4781 4742 if (nfs4_schedule_stateid_recovery(server, state) < 0) 4782 - goto stateid_invalid; 4743 + goto recovery_failed; 4783 4744 } 4784 4745 case -NFS4ERR_STALE_STATEID: 4785 4746 case -NFS4ERR_STALE_CLIENTID: 4786 4747 nfs4_schedule_lease_recovery(clp); 4748 + goto wait_on_recovery; 4749 + case -NFS4ERR_MOVED: 4750 + if (nfs4_schedule_migration_recovery(server) < 0) 4751 + goto recovery_failed; 4752 + goto wait_on_recovery; 4753 + case -NFS4ERR_LEASE_MOVED: 4754 + nfs4_schedule_lease_moved_recovery(clp); 4787 4755 goto wait_on_recovery; 4788 4756 #if defined(CONFIG_NFS_V4_1) 4789 4757 case -NFS4ERR_BADSESSION: ··· 4803 4757 dprintk("%s ERROR %d, Reset session\n", __func__, 4804 4758 task->tk_status); 4805 4759 nfs4_schedule_session_recovery(clp->cl_session, task->tk_status); 4806 - task->tk_status = 0; 4807 - return -EAGAIN; 4760 + goto restart_call; 4808 4761 #endif /* CONFIG_NFS_V4_1 */ 4809 4762 case -NFS4ERR_DELAY: 4810 4763 nfs_inc_server_stats(server, NFSIOS_DELAY); 4811 4764 case -NFS4ERR_GRACE: 4812 4765 rpc_delay(task, NFS4_POLL_RETRY_MAX); 4813 - task->tk_status = 0; 4814 - return -EAGAIN; 4815 4766 case -NFS4ERR_RETRY_UNCACHED_REP: 4816 4767 case -NFS4ERR_OLD_STATEID: 4817 - task->tk_status = 0; 4818 - return -EAGAIN; 4768 + goto restart_call; 4819 4769 } 4820 4770 task->tk_status = nfs4_map_errors(task->tk_status); 4821 4771 return 0; 4822 - stateid_invalid: 4772 + recovery_failed: 4823 4773 task->tk_status = -EIO; 4824 4774 return 0; 4825 4775 wait_on_recovery: 4826 4776 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); 4827 4777 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) 4828 4778 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); 4779 + if (test_bit(NFS_MIG_FAILED, &server->mig_status)) 4780 + goto recovery_failed; 4781 + restart_call: 4829 4782 task->tk_status = 0; 4830 4783 return -EAGAIN; 4831 4784 } ··· 5151 5106 status = 0; 5152 5107 } 5153 5108 request->fl_ops->fl_release_private(request); 5109 + request->fl_ops = NULL; 5154 5110 out: 5155 5111 return status; 5156 5112 } ··· 5825 5779 struct nfs_release_lockowner_args args; 5826 5780 struct nfs4_sequence_args seq_args; 5827 5781 struct nfs4_sequence_res seq_res; 5782 + unsigned long timestamp; 5828 5783 }; 5829 5784 5830 5785 static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata) ··· 5833 5786 struct nfs_release_lockowner_data *data = calldata; 5834 5787 nfs40_setup_sequence(data->server, 5835 5788 &data->seq_args, &data->seq_res, task); 5789 + data->timestamp = jiffies; 5836 5790 } 5837 5791 5838 5792 static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata) 5839 5793 { 5840 5794 struct nfs_release_lockowner_data *data = calldata; 5795 + struct nfs_server *server = data->server; 5796 + 5841 5797 nfs40_sequence_done(task, &data->seq_res); 5798 + 5799 + switch (task->tk_status) { 5800 + case 0: 5801 + renew_lease(server, data->timestamp); 5802 + break; 5803 + case -NFS4ERR_STALE_CLIENTID: 5804 + case -NFS4ERR_EXPIRED: 5805 + case -NFS4ERR_LEASE_MOVED: 5806 + case -NFS4ERR_DELAY: 5807 + if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) 5808 + rpc_restart_call_prepare(task); 5809 + } 5842 5810 } 5843 5811 5844 5812 static void nfs4_release_lockowner_release(void *calldata) ··· 6050 5988 &exception); 6051 5989 } while (exception.retry); 6052 5990 return err; 5991 + } 5992 + 5993 + /* 5994 + * This operation also signals the server that this client is 5995 + * performing migration recovery. The server can stop returning 5996 + * NFS4ERR_LEASE_MOVED to this client. A RENEW operation is 5997 + * appended to this compound to identify the client ID which is 5998 + * performing recovery. 5999 + */ 6000 + static int _nfs40_proc_get_locations(struct inode *inode, 6001 + struct nfs4_fs_locations *locations, 6002 + struct page *page, struct rpc_cred *cred) 6003 + { 6004 + struct nfs_server *server = NFS_SERVER(inode); 6005 + struct rpc_clnt *clnt = server->client; 6006 + u32 bitmask[2] = { 6007 + [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, 6008 + }; 6009 + struct nfs4_fs_locations_arg args = { 6010 + .clientid = server->nfs_client->cl_clientid, 6011 + .fh = NFS_FH(inode), 6012 + .page = page, 6013 + .bitmask = bitmask, 6014 + .migration = 1, /* skip LOOKUP */ 6015 + .renew = 1, /* append RENEW */ 6016 + }; 6017 + struct nfs4_fs_locations_res res = { 6018 + .fs_locations = locations, 6019 + .migration = 1, 6020 + .renew = 1, 6021 + }; 6022 + struct rpc_message msg = { 6023 + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS], 6024 + .rpc_argp = &args, 6025 + .rpc_resp = &res, 6026 + .rpc_cred = cred, 6027 + }; 6028 + unsigned long now = jiffies; 6029 + int status; 6030 + 6031 + nfs_fattr_init(&locations->fattr); 6032 + locations->server = server; 6033 + locations->nlocations = 0; 6034 + 6035 + nfs4_init_sequence(&args.seq_args, &res.seq_res, 0); 6036 + nfs4_set_sequence_privileged(&args.seq_args); 6037 + status = nfs4_call_sync_sequence(clnt, server, &msg, 6038 + &args.seq_args, &res.seq_res); 6039 + if (status) 6040 + return status; 6041 + 6042 + renew_lease(server, now); 6043 + return 0; 6044 + } 6045 + 6046 + #ifdef CONFIG_NFS_V4_1 6047 + 6048 + /* 6049 + * This operation also signals the server that this client is 6050 + * performing migration recovery. The server can stop asserting 6051 + * SEQ4_STATUS_LEASE_MOVED for this client. The client ID 6052 + * performing this operation is identified in the SEQUENCE 6053 + * operation in this compound. 6054 + * 6055 + * When the client supports GETATTR(fs_locations_info), it can 6056 + * be plumbed in here. 6057 + */ 6058 + static int _nfs41_proc_get_locations(struct inode *inode, 6059 + struct nfs4_fs_locations *locations, 6060 + struct page *page, struct rpc_cred *cred) 6061 + { 6062 + struct nfs_server *server = NFS_SERVER(inode); 6063 + struct rpc_clnt *clnt = server->client; 6064 + u32 bitmask[2] = { 6065 + [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, 6066 + }; 6067 + struct nfs4_fs_locations_arg args = { 6068 + .fh = NFS_FH(inode), 6069 + .page = page, 6070 + .bitmask = bitmask, 6071 + .migration = 1, /* skip LOOKUP */ 6072 + }; 6073 + struct nfs4_fs_locations_res res = { 6074 + .fs_locations = locations, 6075 + .migration = 1, 6076 + }; 6077 + struct rpc_message msg = { 6078 + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS], 6079 + .rpc_argp = &args, 6080 + .rpc_resp = &res, 6081 + .rpc_cred = cred, 6082 + }; 6083 + int status; 6084 + 6085 + nfs_fattr_init(&locations->fattr); 6086 + locations->server = server; 6087 + locations->nlocations = 0; 6088 + 6089 + nfs4_init_sequence(&args.seq_args, &res.seq_res, 0); 6090 + nfs4_set_sequence_privileged(&args.seq_args); 6091 + status = nfs4_call_sync_sequence(clnt, server, &msg, 6092 + &args.seq_args, &res.seq_res); 6093 + if (status == NFS4_OK && 6094 + res.seq_res.sr_status_flags & SEQ4_STATUS_LEASE_MOVED) 6095 + status = -NFS4ERR_LEASE_MOVED; 6096 + return status; 6097 + } 6098 + 6099 + #endif /* CONFIG_NFS_V4_1 */ 6100 + 6101 + /** 6102 + * nfs4_proc_get_locations - discover locations for a migrated FSID 6103 + * @inode: inode on FSID that is migrating 6104 + * @locations: result of query 6105 + * @page: buffer 6106 + * @cred: credential to use for this operation 6107 + * 6108 + * Returns NFS4_OK on success, a negative NFS4ERR status code if the 6109 + * operation failed, or a negative errno if a local error occurred. 6110 + * 6111 + * On success, "locations" is filled in, but if the server has 6112 + * no locations information, NFS_ATTR_FATTR_V4_LOCATIONS is not 6113 + * asserted. 6114 + * 6115 + * -NFS4ERR_LEASE_MOVED is returned if the server still has leases 6116 + * from this client that require migration recovery. 6117 + */ 6118 + int nfs4_proc_get_locations(struct inode *inode, 6119 + struct nfs4_fs_locations *locations, 6120 + struct page *page, struct rpc_cred *cred) 6121 + { 6122 + struct nfs_server *server = NFS_SERVER(inode); 6123 + struct nfs_client *clp = server->nfs_client; 6124 + const struct nfs4_mig_recovery_ops *ops = 6125 + clp->cl_mvops->mig_recovery_ops; 6126 + struct nfs4_exception exception = { }; 6127 + int status; 6128 + 6129 + dprintk("%s: FSID %llx:%llx on \"%s\"\n", __func__, 6130 + (unsigned long long)server->fsid.major, 6131 + (unsigned long long)server->fsid.minor, 6132 + clp->cl_hostname); 6133 + nfs_display_fhandle(NFS_FH(inode), __func__); 6134 + 6135 + do { 6136 + status = ops->get_locations(inode, locations, page, cred); 6137 + if (status != -NFS4ERR_DELAY) 6138 + break; 6139 + nfs4_handle_exception(server, status, &exception); 6140 + } while (exception.retry); 6141 + return status; 6142 + } 6143 + 6144 + /* 6145 + * This operation also signals the server that this client is 6146 + * performing "lease moved" recovery. The server can stop 6147 + * returning NFS4ERR_LEASE_MOVED to this client. A RENEW operation 6148 + * is appended to this compound to identify the client ID which is 6149 + * performing recovery. 6150 + */ 6151 + static int _nfs40_proc_fsid_present(struct inode *inode, struct rpc_cred *cred) 6152 + { 6153 + struct nfs_server *server = NFS_SERVER(inode); 6154 + struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 6155 + struct rpc_clnt *clnt = server->client; 6156 + struct nfs4_fsid_present_arg args = { 6157 + .fh = NFS_FH(inode), 6158 + .clientid = clp->cl_clientid, 6159 + .renew = 1, /* append RENEW */ 6160 + }; 6161 + struct nfs4_fsid_present_res res = { 6162 + .renew = 1, 6163 + }; 6164 + struct rpc_message msg = { 6165 + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSID_PRESENT], 6166 + .rpc_argp = &args, 6167 + .rpc_resp = &res, 6168 + .rpc_cred = cred, 6169 + }; 6170 + unsigned long now = jiffies; 6171 + int status; 6172 + 6173 + res.fh = nfs_alloc_fhandle(); 6174 + if (res.fh == NULL) 6175 + return -ENOMEM; 6176 + 6177 + nfs4_init_sequence(&args.seq_args, &res.seq_res, 0); 6178 + nfs4_set_sequence_privileged(&args.seq_args); 6179 + status = nfs4_call_sync_sequence(clnt, server, &msg, 6180 + &args.seq_args, &res.seq_res); 6181 + nfs_free_fhandle(res.fh); 6182 + if (status) 6183 + return status; 6184 + 6185 + do_renew_lease(clp, now); 6186 + return 0; 6187 + } 6188 + 6189 + #ifdef CONFIG_NFS_V4_1 6190 + 6191 + /* 6192 + * This operation also signals the server that this client is 6193 + * performing "lease moved" recovery. The server can stop asserting 6194 + * SEQ4_STATUS_LEASE_MOVED for this client. The client ID performing 6195 + * this operation is identified in the SEQUENCE operation in this 6196 + * compound. 6197 + */ 6198 + static int _nfs41_proc_fsid_present(struct inode *inode, struct rpc_cred *cred) 6199 + { 6200 + struct nfs_server *server = NFS_SERVER(inode); 6201 + struct rpc_clnt *clnt = server->client; 6202 + struct nfs4_fsid_present_arg args = { 6203 + .fh = NFS_FH(inode), 6204 + }; 6205 + struct nfs4_fsid_present_res res = { 6206 + }; 6207 + struct rpc_message msg = { 6208 + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSID_PRESENT], 6209 + .rpc_argp = &args, 6210 + .rpc_resp = &res, 6211 + .rpc_cred = cred, 6212 + }; 6213 + int status; 6214 + 6215 + res.fh = nfs_alloc_fhandle(); 6216 + if (res.fh == NULL) 6217 + return -ENOMEM; 6218 + 6219 + nfs4_init_sequence(&args.seq_args, &res.seq_res, 0); 6220 + nfs4_set_sequence_privileged(&args.seq_args); 6221 + status = nfs4_call_sync_sequence(clnt, server, &msg, 6222 + &args.seq_args, &res.seq_res); 6223 + nfs_free_fhandle(res.fh); 6224 + if (status == NFS4_OK && 6225 + res.seq_res.sr_status_flags & SEQ4_STATUS_LEASE_MOVED) 6226 + status = -NFS4ERR_LEASE_MOVED; 6227 + return status; 6228 + } 6229 + 6230 + #endif /* CONFIG_NFS_V4_1 */ 6231 + 6232 + /** 6233 + * nfs4_proc_fsid_present - Is this FSID present or absent on server? 6234 + * @inode: inode on FSID to check 6235 + * @cred: credential to use for this operation 6236 + * 6237 + * Server indicates whether the FSID is present, moved, or not 6238 + * recognized. This operation is necessary to clear a LEASE_MOVED 6239 + * condition for this client ID. 6240 + * 6241 + * Returns NFS4_OK if the FSID is present on this server, 6242 + * -NFS4ERR_MOVED if the FSID is no longer present, a negative 6243 + * NFS4ERR code if some error occurred on the server, or a 6244 + * negative errno if a local failure occurred. 6245 + */ 6246 + int nfs4_proc_fsid_present(struct inode *inode, struct rpc_cred *cred) 6247 + { 6248 + struct nfs_server *server = NFS_SERVER(inode); 6249 + struct nfs_client *clp = server->nfs_client; 6250 + const struct nfs4_mig_recovery_ops *ops = 6251 + clp->cl_mvops->mig_recovery_ops; 6252 + struct nfs4_exception exception = { }; 6253 + int status; 6254 + 6255 + dprintk("%s: FSID %llx:%llx on \"%s\"\n", __func__, 6256 + (unsigned long long)server->fsid.major, 6257 + (unsigned long long)server->fsid.minor, 6258 + clp->cl_hostname); 6259 + nfs_display_fhandle(NFS_FH(inode), __func__); 6260 + 6261 + do { 6262 + status = ops->fsid_present(inode, cred); 6263 + if (status != -NFS4ERR_DELAY) 6264 + break; 6265 + nfs4_handle_exception(server, status, &exception); 6266 + } while (exception.retry); 6267 + return status; 6053 6268 } 6054 6269 6055 6270 /** ··· 6615 6276 struct nfs41_exchange_id_args args = { 6616 6277 .verifier = &verifier, 6617 6278 .client = clp, 6279 + #ifdef CONFIG_NFS_V4_1_MIGRATION 6618 6280 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER | 6619 - EXCHGID4_FLAG_BIND_PRINC_STATEID, 6281 + EXCHGID4_FLAG_BIND_PRINC_STATEID | 6282 + EXCHGID4_FLAG_SUPP_MOVED_MIGR, 6283 + #else 6284 + .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER | 6285 + EXCHGID4_FLAG_BIND_PRINC_STATEID, 6286 + #endif 6620 6287 }; 6621 6288 struct nfs41_exchange_id_res res = { 6622 6289 0 ··· 7961 7616 break; 7962 7617 } 7963 7618 7619 + if (!nfs_auth_info_match(&server->auth_info, flavor)) 7620 + flavor = RPC_AUTH_MAXFLAVOR; 7621 + 7964 7622 if (flavor != RPC_AUTH_MAXFLAVOR) { 7965 7623 err = nfs4_lookup_root_sec(server, fhandle, 7966 7624 info, flavor); ··· 8235 7887 }; 8236 7888 #endif 8237 7889 7890 + static const struct nfs4_mig_recovery_ops nfs40_mig_recovery_ops = { 7891 + .get_locations = _nfs40_proc_get_locations, 7892 + .fsid_present = _nfs40_proc_fsid_present, 7893 + }; 7894 + 7895 + #if defined(CONFIG_NFS_V4_1) 7896 + static const struct nfs4_mig_recovery_ops nfs41_mig_recovery_ops = { 7897 + .get_locations = _nfs41_proc_get_locations, 7898 + .fsid_present = _nfs41_proc_fsid_present, 7899 + }; 7900 + #endif /* CONFIG_NFS_V4_1 */ 7901 + 8238 7902 static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = { 8239 7903 .minor_version = 0, 8240 7904 .init_caps = NFS_CAP_READDIRPLUS ··· 8262 7902 .reboot_recovery_ops = &nfs40_reboot_recovery_ops, 8263 7903 .nograce_recovery_ops = &nfs40_nograce_recovery_ops, 8264 7904 .state_renewal_ops = &nfs40_state_renewal_ops, 7905 + .mig_recovery_ops = &nfs40_mig_recovery_ops, 8265 7906 }; 8266 7907 8267 7908 #if defined(CONFIG_NFS_V4_1) ··· 8283 7922 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 8284 7923 .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 8285 7924 .state_renewal_ops = &nfs41_state_renewal_ops, 7925 + .mig_recovery_ops = &nfs41_mig_recovery_ops, 8286 7926 }; 8287 7927 #endif 8288 7928
+245 -19
fs/nfs/nfs4state.c
··· 239 239 } 240 240 } 241 241 242 - #if defined(CONFIG_NFS_V4_1) 243 - 244 242 static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl) 245 243 { 246 244 set_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); ··· 267 269 /* fore channel */ 268 270 return nfs4_drain_slot_tbl(&ses->fc_slot_table); 269 271 } 272 + 273 + #if defined(CONFIG_NFS_V4_1) 270 274 271 275 static int nfs41_setup_state_renewal(struct nfs_client *clp) 272 276 { ··· 1197 1197 } 1198 1198 EXPORT_SYMBOL_GPL(nfs4_schedule_lease_recovery); 1199 1199 1200 + /** 1201 + * nfs4_schedule_migration_recovery - trigger migration recovery 1202 + * 1203 + * @server: FSID that is migrating 1204 + * 1205 + * Returns zero if recovery has started, otherwise a negative NFS4ERR 1206 + * value is returned. 1207 + */ 1208 + int nfs4_schedule_migration_recovery(const struct nfs_server *server) 1209 + { 1210 + struct nfs_client *clp = server->nfs_client; 1211 + 1212 + if (server->fh_expire_type != NFS4_FH_PERSISTENT) { 1213 + pr_err("NFS: volatile file handles not supported (server %s)\n", 1214 + clp->cl_hostname); 1215 + return -NFS4ERR_IO; 1216 + } 1217 + 1218 + if (test_bit(NFS_MIG_FAILED, &server->mig_status)) 1219 + return -NFS4ERR_IO; 1220 + 1221 + dprintk("%s: scheduling migration recovery for (%llx:%llx) on %s\n", 1222 + __func__, 1223 + (unsigned long long)server->fsid.major, 1224 + (unsigned long long)server->fsid.minor, 1225 + clp->cl_hostname); 1226 + 1227 + set_bit(NFS_MIG_IN_TRANSITION, 1228 + &((struct nfs_server *)server)->mig_status); 1229 + set_bit(NFS4CLNT_MOVED, &clp->cl_state); 1230 + 1231 + nfs4_schedule_state_manager(clp); 1232 + return 0; 1233 + } 1234 + EXPORT_SYMBOL_GPL(nfs4_schedule_migration_recovery); 1235 + 1236 + /** 1237 + * nfs4_schedule_lease_moved_recovery - start lease-moved recovery 1238 + * 1239 + * @clp: server to check for moved leases 1240 + * 1241 + */ 1242 + void nfs4_schedule_lease_moved_recovery(struct nfs_client *clp) 1243 + { 1244 + dprintk("%s: scheduling lease-moved recovery for client ID %llx on %s\n", 1245 + __func__, clp->cl_clientid, clp->cl_hostname); 1246 + 1247 + set_bit(NFS4CLNT_LEASE_MOVED, &clp->cl_state); 1248 + nfs4_schedule_state_manager(clp); 1249 + } 1250 + EXPORT_SYMBOL_GPL(nfs4_schedule_lease_moved_recovery); 1251 + 1200 1252 int nfs4_wait_clnt_recover(struct nfs_client *clp) 1201 1253 { 1202 1254 int res; 1203 1255 1204 1256 might_sleep(); 1205 1257 1258 + atomic_inc(&clp->cl_count); 1206 1259 res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING, 1207 1260 nfs_wait_bit_killable, TASK_KILLABLE); 1208 1261 if (res) 1209 - return res; 1210 - 1262 + goto out; 1211 1263 if (clp->cl_cons_state < 0) 1212 - return clp->cl_cons_state; 1213 - return 0; 1264 + res = clp->cl_cons_state; 1265 + out: 1266 + nfs_put_client(clp); 1267 + return res; 1214 1268 } 1215 1269 1216 1270 int nfs4_client_recover_expired_lease(struct nfs_client *clp) ··· 1429 1375 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 1430 1376 goto out; 1431 1377 default: 1432 - printk(KERN_ERR "NFS: %s: unhandled error %d. " 1433 - "Zeroing state\n", __func__, status); 1378 + printk(KERN_ERR "NFS: %s: unhandled error %d\n", 1379 + __func__, status); 1434 1380 case -ENOMEM: 1435 1381 case -NFS4ERR_DENIED: 1436 1382 case -NFS4ERR_RECLAIM_BAD: ··· 1476 1422 if (status >= 0) { 1477 1423 status = nfs4_reclaim_locks(state, ops); 1478 1424 if (status >= 0) { 1479 - if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) { 1425 + if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) { 1480 1426 spin_lock(&state->state_lock); 1481 1427 list_for_each_entry(lock, &state->lock_states, ls_locks) { 1482 1428 if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags)) ··· 1493 1439 } 1494 1440 switch (status) { 1495 1441 default: 1496 - printk(KERN_ERR "NFS: %s: unhandled error %d. " 1497 - "Zeroing state\n", __func__, status); 1442 + printk(KERN_ERR "NFS: %s: unhandled error %d\n", 1443 + __func__, status); 1498 1444 case -ENOENT: 1499 1445 case -ENOMEM: 1500 1446 case -ESTALE: 1501 - /* 1502 - * Open state on this file cannot be recovered 1503 - * All we can do is revert to using the zero stateid. 1504 - */ 1447 + /* Open state on this file cannot be recovered */ 1505 1448 nfs4_state_mark_recovery_failed(state, status); 1506 1449 break; 1507 1450 case -EAGAIN: ··· 1679 1628 nfs4_state_end_reclaim_reboot(clp); 1680 1629 break; 1681 1630 case -NFS4ERR_STALE_CLIENTID: 1682 - case -NFS4ERR_LEASE_MOVED: 1683 1631 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1684 1632 nfs4_state_clear_reclaim_reboot(clp); 1685 1633 nfs4_state_start_reclaim_reboot(clp); ··· 1879 1829 return 0; 1880 1830 } 1881 1831 1832 + /* 1833 + * Try remote migration of one FSID from a source server to a 1834 + * destination server. The source server provides a list of 1835 + * potential destinations. 1836 + * 1837 + * Returns zero or a negative NFS4ERR status code. 1838 + */ 1839 + static int nfs4_try_migration(struct nfs_server *server, struct rpc_cred *cred) 1840 + { 1841 + struct nfs_client *clp = server->nfs_client; 1842 + struct nfs4_fs_locations *locations = NULL; 1843 + struct inode *inode; 1844 + struct page *page; 1845 + int status, result; 1846 + 1847 + dprintk("--> %s: FSID %llx:%llx on \"%s\"\n", __func__, 1848 + (unsigned long long)server->fsid.major, 1849 + (unsigned long long)server->fsid.minor, 1850 + clp->cl_hostname); 1851 + 1852 + result = 0; 1853 + page = alloc_page(GFP_KERNEL); 1854 + locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); 1855 + if (page == NULL || locations == NULL) { 1856 + dprintk("<-- %s: no memory\n", __func__); 1857 + goto out; 1858 + } 1859 + 1860 + inode = server->super->s_root->d_inode; 1861 + result = nfs4_proc_get_locations(inode, locations, page, cred); 1862 + if (result) { 1863 + dprintk("<-- %s: failed to retrieve fs_locations: %d\n", 1864 + __func__, result); 1865 + goto out; 1866 + } 1867 + 1868 + result = -NFS4ERR_NXIO; 1869 + if (!(locations->fattr.valid & NFS_ATTR_FATTR_V4_LOCATIONS)) { 1870 + dprintk("<-- %s: No fs_locations data, migration skipped\n", 1871 + __func__); 1872 + goto out; 1873 + } 1874 + 1875 + nfs4_begin_drain_session(clp); 1876 + 1877 + status = nfs4_replace_transport(server, locations); 1878 + if (status != 0) { 1879 + dprintk("<-- %s: failed to replace transport: %d\n", 1880 + __func__, status); 1881 + goto out; 1882 + } 1883 + 1884 + result = 0; 1885 + dprintk("<-- %s: migration succeeded\n", __func__); 1886 + 1887 + out: 1888 + if (page != NULL) 1889 + __free_page(page); 1890 + kfree(locations); 1891 + if (result) { 1892 + pr_err("NFS: migration recovery failed (server %s)\n", 1893 + clp->cl_hostname); 1894 + set_bit(NFS_MIG_FAILED, &server->mig_status); 1895 + } 1896 + return result; 1897 + } 1898 + 1899 + /* 1900 + * Returns zero or a negative NFS4ERR status code. 1901 + */ 1902 + static int nfs4_handle_migration(struct nfs_client *clp) 1903 + { 1904 + const struct nfs4_state_maintenance_ops *ops = 1905 + clp->cl_mvops->state_renewal_ops; 1906 + struct nfs_server *server; 1907 + struct rpc_cred *cred; 1908 + 1909 + dprintk("%s: migration reported on \"%s\"\n", __func__, 1910 + clp->cl_hostname); 1911 + 1912 + spin_lock(&clp->cl_lock); 1913 + cred = ops->get_state_renewal_cred_locked(clp); 1914 + spin_unlock(&clp->cl_lock); 1915 + if (cred == NULL) 1916 + return -NFS4ERR_NOENT; 1917 + 1918 + clp->cl_mig_gen++; 1919 + restart: 1920 + rcu_read_lock(); 1921 + list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { 1922 + int status; 1923 + 1924 + if (server->mig_gen == clp->cl_mig_gen) 1925 + continue; 1926 + server->mig_gen = clp->cl_mig_gen; 1927 + 1928 + if (!test_and_clear_bit(NFS_MIG_IN_TRANSITION, 1929 + &server->mig_status)) 1930 + continue; 1931 + 1932 + rcu_read_unlock(); 1933 + status = nfs4_try_migration(server, cred); 1934 + if (status < 0) { 1935 + put_rpccred(cred); 1936 + return status; 1937 + } 1938 + goto restart; 1939 + } 1940 + rcu_read_unlock(); 1941 + put_rpccred(cred); 1942 + return 0; 1943 + } 1944 + 1945 + /* 1946 + * Test each nfs_server on the clp's cl_superblocks list to see 1947 + * if it's moved to another server. Stop when the server no longer 1948 + * returns NFS4ERR_LEASE_MOVED. 1949 + */ 1950 + static int nfs4_handle_lease_moved(struct nfs_client *clp) 1951 + { 1952 + const struct nfs4_state_maintenance_ops *ops = 1953 + clp->cl_mvops->state_renewal_ops; 1954 + struct nfs_server *server; 1955 + struct rpc_cred *cred; 1956 + 1957 + dprintk("%s: lease moved reported on \"%s\"\n", __func__, 1958 + clp->cl_hostname); 1959 + 1960 + spin_lock(&clp->cl_lock); 1961 + cred = ops->get_state_renewal_cred_locked(clp); 1962 + spin_unlock(&clp->cl_lock); 1963 + if (cred == NULL) 1964 + return -NFS4ERR_NOENT; 1965 + 1966 + clp->cl_mig_gen++; 1967 + restart: 1968 + rcu_read_lock(); 1969 + list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { 1970 + struct inode *inode; 1971 + int status; 1972 + 1973 + if (server->mig_gen == clp->cl_mig_gen) 1974 + continue; 1975 + server->mig_gen = clp->cl_mig_gen; 1976 + 1977 + rcu_read_unlock(); 1978 + 1979 + inode = server->super->s_root->d_inode; 1980 + status = nfs4_proc_fsid_present(inode, cred); 1981 + if (status != -NFS4ERR_MOVED) 1982 + goto restart; /* wasn't this one */ 1983 + if (nfs4_try_migration(server, cred) == -NFS4ERR_LEASE_MOVED) 1984 + goto restart; /* there are more */ 1985 + goto out; 1986 + } 1987 + rcu_read_unlock(); 1988 + 1989 + out: 1990 + put_rpccred(cred); 1991 + return 0; 1992 + } 1993 + 1882 1994 /** 1883 1995 * nfs4_discover_server_trunking - Detect server IP address trunking 1884 1996 * ··· 2229 2017 nfs41_handle_server_reboot(clp); 2230 2018 if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED | 2231 2019 SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED | 2232 - SEQ4_STATUS_ADMIN_STATE_REVOKED | 2233 - SEQ4_STATUS_LEASE_MOVED)) 2020 + SEQ4_STATUS_ADMIN_STATE_REVOKED)) 2234 2021 nfs41_handle_state_revoked(clp); 2022 + if (flags & SEQ4_STATUS_LEASE_MOVED) 2023 + nfs4_schedule_lease_moved_recovery(clp); 2235 2024 if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED) 2236 2025 nfs41_handle_recallable_state_revoked(clp); 2237 2026 if (flags & SEQ4_STATUS_BACKCHANNEL_FAULT) ··· 2370 2157 status = nfs4_check_lease(clp); 2371 2158 if (status < 0) 2372 2159 goto out_error; 2373 - continue; 2160 + } 2161 + 2162 + if (test_and_clear_bit(NFS4CLNT_MOVED, &clp->cl_state)) { 2163 + section = "migration"; 2164 + status = nfs4_handle_migration(clp); 2165 + if (status < 0) 2166 + goto out_error; 2167 + } 2168 + 2169 + if (test_and_clear_bit(NFS4CLNT_LEASE_MOVED, &clp->cl_state)) { 2170 + section = "lease moved"; 2171 + status = nfs4_handle_lease_moved(clp); 2172 + if (status < 0) 2173 + goto out_error; 2374 2174 } 2375 2175 2376 2176 /* First recover reboot state... */
+6 -6
fs/nfs/nfs4super.c
··· 261 261 262 262 res = nfs_follow_remote_path(root_mnt, export_path); 263 263 264 - dfprintk(MOUNT, "<-- nfs4_try_mount() = %ld%s\n", 265 - IS_ERR(res) ? PTR_ERR(res) : 0, 266 - IS_ERR(res) ? " [error]" : ""); 264 + dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", 265 + PTR_ERR_OR_ZERO(res), 266 + IS_ERR(res) ? " [error]" : ""); 267 267 return res; 268 268 } 269 269 ··· 319 319 data->mnt_path = export_path; 320 320 321 321 res = nfs_follow_remote_path(root_mnt, export_path); 322 - dprintk("<-- nfs4_referral_mount() = %ld%s\n", 323 - IS_ERR(res) ? PTR_ERR(res) : 0, 324 - IS_ERR(res) ? " [error]" : ""); 322 + dprintk("<-- nfs4_referral_mount() = %d%s\n", 323 + PTR_ERR_OR_ZERO(res), 324 + IS_ERR(res) ? " [error]" : ""); 325 325 return res; 326 326 } 327 327
+112 -26
fs/nfs/nfs4xdr.c
··· 105 105 #ifdef CONFIG_NFS_V4_SECURITY_LABEL 106 106 /* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */ 107 107 #define nfs4_label_maxsz (4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN)) 108 - #define encode_readdir_space 24 109 - #define encode_readdir_bitmask_sz 3 110 108 #else 111 109 #define nfs4_label_maxsz 0 112 - #define encode_readdir_space 20 113 - #define encode_readdir_bitmask_sz 2 114 110 #endif 115 111 /* We support only one layout type per file system */ 116 112 #define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) ··· 591 595 #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ 592 596 encode_sequence_maxsz + \ 593 597 encode_putfh_maxsz + \ 594 - encode_getattr_maxsz) 598 + encode_getattr_maxsz + \ 599 + encode_renew_maxsz) 595 600 #define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ 596 601 decode_sequence_maxsz + \ 597 602 decode_putfh_maxsz + \ 598 - decode_getattr_maxsz) 603 + decode_getattr_maxsz + \ 604 + decode_renew_maxsz) 599 605 #define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ 600 606 encode_sequence_maxsz + \ 601 607 encode_putfh_maxsz + \ ··· 734 736 encode_sequence_maxsz + \ 735 737 encode_putfh_maxsz + \ 736 738 encode_lookup_maxsz + \ 737 - encode_fs_locations_maxsz) 739 + encode_fs_locations_maxsz + \ 740 + encode_renew_maxsz) 738 741 #define NFS4_dec_fs_locations_sz \ 739 742 (compound_decode_hdr_maxsz + \ 740 743 decode_sequence_maxsz + \ 741 744 decode_putfh_maxsz + \ 742 745 decode_lookup_maxsz + \ 743 - decode_fs_locations_maxsz) 746 + decode_fs_locations_maxsz + \ 747 + decode_renew_maxsz) 744 748 #define NFS4_enc_secinfo_sz (compound_encode_hdr_maxsz + \ 745 749 encode_sequence_maxsz + \ 746 750 encode_putfh_maxsz + \ ··· 751 751 decode_sequence_maxsz + \ 752 752 decode_putfh_maxsz + \ 753 753 decode_secinfo_maxsz) 754 + #define NFS4_enc_fsid_present_sz \ 755 + (compound_encode_hdr_maxsz + \ 756 + encode_sequence_maxsz + \ 757 + encode_putfh_maxsz + \ 758 + encode_getfh_maxsz + \ 759 + encode_renew_maxsz) 760 + #define NFS4_dec_fsid_present_sz \ 761 + (compound_decode_hdr_maxsz + \ 762 + decode_sequence_maxsz + \ 763 + decode_putfh_maxsz + \ 764 + decode_getfh_maxsz + \ 765 + decode_renew_maxsz) 754 766 #if defined(CONFIG_NFS_V4_1) 755 767 #define NFS4_enc_bind_conn_to_session_sz \ 756 768 (compound_encode_hdr_maxsz + \ ··· 1577 1565 }; 1578 1566 uint32_t dircount = readdir->count >> 1; 1579 1567 __be32 *p, verf[2]; 1568 + uint32_t attrlen = 0; 1569 + unsigned int i; 1580 1570 1581 1571 if (readdir->plus) { 1582 1572 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| ··· 1587 1573 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| 1588 1574 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| 1589 1575 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 1576 + attrs[2] |= FATTR4_WORD2_SECURITY_LABEL; 1590 1577 dircount >>= 1; 1591 1578 } 1592 1579 /* Use mounted_on_fileid only if the server supports it */ 1593 1580 if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) 1594 1581 attrs[0] |= FATTR4_WORD0_FILEID; 1582 + for (i = 0; i < ARRAY_SIZE(attrs); i++) { 1583 + attrs[i] &= readdir->bitmask[i]; 1584 + if (attrs[i] != 0) 1585 + attrlen = i+1; 1586 + } 1595 1587 1596 1588 encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr); 1597 1589 encode_uint64(xdr, readdir->cookie); 1598 1590 encode_nfs4_verifier(xdr, &readdir->verifier); 1599 - p = reserve_space(xdr, encode_readdir_space); 1591 + p = reserve_space(xdr, 12 + (attrlen << 2)); 1600 1592 *p++ = cpu_to_be32(dircount); 1601 1593 *p++ = cpu_to_be32(readdir->count); 1602 - *p++ = cpu_to_be32(encode_readdir_bitmask_sz); 1603 - *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); 1604 - *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); 1605 - if (encode_readdir_bitmask_sz > 2) { 1606 - if (hdr->minorversion > 1) 1607 - attrs[2] |= FATTR4_WORD2_SECURITY_LABEL; 1608 - p++, *p++ = cpu_to_be32(attrs[2] & readdir->bitmask[2]); 1609 - } 1594 + *p++ = cpu_to_be32(attrlen); 1595 + for (i = 0; i < attrlen; i++) 1596 + *p++ = cpu_to_be32(attrs[i]); 1610 1597 memcpy(verf, readdir->verifier.data, sizeof(verf)); 1611 1598 1612 1599 dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n", ··· 2702 2687 2703 2688 encode_compound_hdr(xdr, req, &hdr); 2704 2689 encode_sequence(xdr, &args->seq_args, &hdr); 2705 - encode_putfh(xdr, args->dir_fh, &hdr); 2706 - encode_lookup(xdr, args->name, &hdr); 2707 - replen = hdr.replen; /* get the attribute into args->page */ 2708 - encode_fs_locations(xdr, args->bitmask, &hdr); 2690 + if (args->migration) { 2691 + encode_putfh(xdr, args->fh, &hdr); 2692 + replen = hdr.replen; 2693 + encode_fs_locations(xdr, args->bitmask, &hdr); 2694 + if (args->renew) 2695 + encode_renew(xdr, args->clientid, &hdr); 2696 + } else { 2697 + encode_putfh(xdr, args->dir_fh, &hdr); 2698 + encode_lookup(xdr, args->name, &hdr); 2699 + replen = hdr.replen; 2700 + encode_fs_locations(xdr, args->bitmask, &hdr); 2701 + } 2709 2702 2703 + /* Set up reply kvec to capture returned fs_locations array. */ 2710 2704 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page, 2711 2705 0, PAGE_SIZE); 2712 2706 encode_nops(&hdr); ··· 2736 2712 encode_sequence(xdr, &args->seq_args, &hdr); 2737 2713 encode_putfh(xdr, args->dir_fh, &hdr); 2738 2714 encode_secinfo(xdr, args->name, &hdr); 2715 + encode_nops(&hdr); 2716 + } 2717 + 2718 + /* 2719 + * Encode FSID_PRESENT request 2720 + */ 2721 + static void nfs4_xdr_enc_fsid_present(struct rpc_rqst *req, 2722 + struct xdr_stream *xdr, 2723 + struct nfs4_fsid_present_arg *args) 2724 + { 2725 + struct compound_hdr hdr = { 2726 + .minorversion = nfs4_xdr_minorversion(&args->seq_args), 2727 + }; 2728 + 2729 + encode_compound_hdr(xdr, req, &hdr); 2730 + encode_sequence(xdr, &args->seq_args, &hdr); 2731 + encode_putfh(xdr, args->fh, &hdr); 2732 + encode_getfh(xdr, &hdr); 2733 + if (args->renew) 2734 + encode_renew(xdr, args->clientid, &hdr); 2739 2735 encode_nops(&hdr); 2740 2736 } 2741 2737 ··· 6868 6824 status = decode_putfh(xdr); 6869 6825 if (status) 6870 6826 goto out; 6871 - status = decode_lookup(xdr); 6872 - if (status) 6873 - goto out; 6874 - xdr_enter_page(xdr, PAGE_SIZE); 6875 - status = decode_getfattr_generic(xdr, &res->fs_locations->fattr, 6827 + if (res->migration) { 6828 + xdr_enter_page(xdr, PAGE_SIZE); 6829 + status = decode_getfattr_generic(xdr, 6830 + &res->fs_locations->fattr, 6876 6831 NULL, res->fs_locations, 6877 6832 NULL, res->fs_locations->server); 6833 + if (status) 6834 + goto out; 6835 + if (res->renew) 6836 + status = decode_renew(xdr); 6837 + } else { 6838 + status = decode_lookup(xdr); 6839 + if (status) 6840 + goto out; 6841 + xdr_enter_page(xdr, PAGE_SIZE); 6842 + status = decode_getfattr_generic(xdr, 6843 + &res->fs_locations->fattr, 6844 + NULL, res->fs_locations, 6845 + NULL, res->fs_locations->server); 6846 + } 6878 6847 out: 6879 6848 return status; 6880 6849 } ··· 6912 6855 if (status) 6913 6856 goto out; 6914 6857 status = decode_secinfo(xdr, res); 6858 + out: 6859 + return status; 6860 + } 6861 + 6862 + /* 6863 + * Decode FSID_PRESENT response 6864 + */ 6865 + static int nfs4_xdr_dec_fsid_present(struct rpc_rqst *rqstp, 6866 + struct xdr_stream *xdr, 6867 + struct nfs4_fsid_present_res *res) 6868 + { 6869 + struct compound_hdr hdr; 6870 + int status; 6871 + 6872 + status = decode_compound_hdr(xdr, &hdr); 6873 + if (status) 6874 + goto out; 6875 + status = decode_sequence(xdr, &res->seq_res, rqstp); 6876 + if (status) 6877 + goto out; 6878 + status = decode_putfh(xdr); 6879 + if (status) 6880 + goto out; 6881 + status = decode_getfh(xdr, res->fh); 6882 + if (status) 6883 + goto out; 6884 + if (res->renew) 6885 + status = decode_renew(xdr); 6915 6886 out: 6916 6887 return status; 6917 6888 } ··· 7458 7373 PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), 7459 7374 PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner), 7460 7375 PROC(SECINFO, enc_secinfo, dec_secinfo), 7376 + PROC(FSID_PRESENT, enc_fsid_present, dec_fsid_present), 7461 7377 #if defined(CONFIG_NFS_V4_1) 7462 7378 PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), 7463 7379 PROC(CREATE_SESSION, enc_create_session, dec_create_session),
+124 -74
fs/nfs/super.c
··· 497 497 static const struct { 498 498 rpc_authflavor_t flavour; 499 499 const char *str; 500 - } sec_flavours[] = { 500 + } sec_flavours[NFS_AUTH_INFO_MAX_FLAVORS] = { 501 + /* update NFS_AUTH_INFO_MAX_FLAVORS when this list changes! */ 501 502 { RPC_AUTH_NULL, "null" }, 502 503 { RPC_AUTH_UNIX, "sys" }, 503 504 { RPC_AUTH_GSS_KRB5, "krb5" }, ··· 924 923 data->mount_server.port = NFS_UNSPEC_PORT; 925 924 data->nfs_server.port = NFS_UNSPEC_PORT; 926 925 data->nfs_server.protocol = XPRT_TRANSPORT_TCP; 927 - data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR; 928 - data->auth_flavor_len = 0; 926 + data->selected_flavor = RPC_AUTH_MAXFLAVOR; 929 927 data->minorversion = 0; 930 928 data->need_mount = true; 931 929 data->net = current->nsproxy->net_ns; ··· 1019 1019 } 1020 1020 } 1021 1021 1022 - static void nfs_set_auth_parsed_mount_data(struct nfs_parsed_mount_data *data, 1023 - rpc_authflavor_t pseudoflavor) 1022 + /* 1023 + * Add 'flavor' to 'auth_info' if not already present. 1024 + * Returns true if 'flavor' ends up in the list, false otherwise 1025 + */ 1026 + static bool nfs_auth_info_add(struct nfs_auth_info *auth_info, 1027 + rpc_authflavor_t flavor) 1024 1028 { 1025 - data->auth_flavors[0] = pseudoflavor; 1026 - data->auth_flavor_len = 1; 1029 + unsigned int i; 1030 + unsigned int max_flavor_len = (sizeof(auth_info->flavors) / 1031 + sizeof(auth_info->flavors[0])); 1032 + 1033 + /* make sure this flavor isn't already in the list */ 1034 + for (i = 0; i < auth_info->flavor_len; i++) { 1035 + if (flavor == auth_info->flavors[i]) 1036 + return true; 1037 + } 1038 + 1039 + if (auth_info->flavor_len + 1 >= max_flavor_len) { 1040 + dfprintk(MOUNT, "NFS: too many sec= flavors\n"); 1041 + return false; 1042 + } 1043 + 1044 + auth_info->flavors[auth_info->flavor_len++] = flavor; 1045 + return true; 1027 1046 } 1047 + 1048 + /* 1049 + * Return true if 'match' is in auth_info or auth_info is empty. 1050 + * Return false otherwise. 1051 + */ 1052 + bool nfs_auth_info_match(const struct nfs_auth_info *auth_info, 1053 + rpc_authflavor_t match) 1054 + { 1055 + int i; 1056 + 1057 + if (!auth_info->flavor_len) 1058 + return true; 1059 + 1060 + for (i = 0; i < auth_info->flavor_len; i++) { 1061 + if (auth_info->flavors[i] == match) 1062 + return true; 1063 + } 1064 + return false; 1065 + } 1066 + EXPORT_SYMBOL_GPL(nfs_auth_info_match); 1028 1067 1029 1068 /* 1030 1069 * Parse the value of the 'sec=' option. ··· 1073 1034 { 1074 1035 substring_t args[MAX_OPT_ARGS]; 1075 1036 rpc_authflavor_t pseudoflavor; 1037 + char *p; 1076 1038 1077 1039 dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); 1078 1040 1079 - switch (match_token(value, nfs_secflavor_tokens, args)) { 1080 - case Opt_sec_none: 1081 - pseudoflavor = RPC_AUTH_NULL; 1082 - break; 1083 - case Opt_sec_sys: 1084 - pseudoflavor = RPC_AUTH_UNIX; 1085 - break; 1086 - case Opt_sec_krb5: 1087 - pseudoflavor = RPC_AUTH_GSS_KRB5; 1088 - break; 1089 - case Opt_sec_krb5i: 1090 - pseudoflavor = RPC_AUTH_GSS_KRB5I; 1091 - break; 1092 - case Opt_sec_krb5p: 1093 - pseudoflavor = RPC_AUTH_GSS_KRB5P; 1094 - break; 1095 - case Opt_sec_lkey: 1096 - pseudoflavor = RPC_AUTH_GSS_LKEY; 1097 - break; 1098 - case Opt_sec_lkeyi: 1099 - pseudoflavor = RPC_AUTH_GSS_LKEYI; 1100 - break; 1101 - case Opt_sec_lkeyp: 1102 - pseudoflavor = RPC_AUTH_GSS_LKEYP; 1103 - break; 1104 - case Opt_sec_spkm: 1105 - pseudoflavor = RPC_AUTH_GSS_SPKM; 1106 - break; 1107 - case Opt_sec_spkmi: 1108 - pseudoflavor = RPC_AUTH_GSS_SPKMI; 1109 - break; 1110 - case Opt_sec_spkmp: 1111 - pseudoflavor = RPC_AUTH_GSS_SPKMP; 1112 - break; 1113 - default: 1114 - return 0; 1041 + while ((p = strsep(&value, ":")) != NULL) { 1042 + switch (match_token(p, nfs_secflavor_tokens, args)) { 1043 + case Opt_sec_none: 1044 + pseudoflavor = RPC_AUTH_NULL; 1045 + break; 1046 + case Opt_sec_sys: 1047 + pseudoflavor = RPC_AUTH_UNIX; 1048 + break; 1049 + case Opt_sec_krb5: 1050 + pseudoflavor = RPC_AUTH_GSS_KRB5; 1051 + break; 1052 + case Opt_sec_krb5i: 1053 + pseudoflavor = RPC_AUTH_GSS_KRB5I; 1054 + break; 1055 + case Opt_sec_krb5p: 1056 + pseudoflavor = RPC_AUTH_GSS_KRB5P; 1057 + break; 1058 + case Opt_sec_lkey: 1059 + pseudoflavor = RPC_AUTH_GSS_LKEY; 1060 + break; 1061 + case Opt_sec_lkeyi: 1062 + pseudoflavor = RPC_AUTH_GSS_LKEYI; 1063 + break; 1064 + case Opt_sec_lkeyp: 1065 + pseudoflavor = RPC_AUTH_GSS_LKEYP; 1066 + break; 1067 + case Opt_sec_spkm: 1068 + pseudoflavor = RPC_AUTH_GSS_SPKM; 1069 + break; 1070 + case Opt_sec_spkmi: 1071 + pseudoflavor = RPC_AUTH_GSS_SPKMI; 1072 + break; 1073 + case Opt_sec_spkmp: 1074 + pseudoflavor = RPC_AUTH_GSS_SPKMP; 1075 + break; 1076 + default: 1077 + dfprintk(MOUNT, 1078 + "NFS: sec= option '%s' not recognized\n", p); 1079 + return 0; 1080 + } 1081 + 1082 + if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor)) 1083 + return 0; 1115 1084 } 1116 1085 1117 - mnt->flags |= NFS_MOUNT_SECFLAVOUR; 1118 - nfs_set_auth_parsed_mount_data(mnt, pseudoflavor); 1119 1086 return 1; 1120 1087 } 1121 1088 ··· 1668 1623 } 1669 1624 1670 1625 /* 1671 - * Ensure that the specified authtype in args->auth_flavors[0] is supported by 1672 - * the server. Returns 0 if it's ok, and -EACCES if not. 1626 + * Ensure that a specified authtype in args->auth_info is supported by 1627 + * the server. Returns 0 and sets args->selected_flavor if it's ok, and 1628 + * -EACCES if not. 1673 1629 */ 1674 - static int nfs_verify_authflavor(struct nfs_parsed_mount_data *args, 1630 + static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, 1675 1631 rpc_authflavor_t *server_authlist, unsigned int count) 1676 1632 { 1633 + rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR; 1677 1634 unsigned int i; 1678 1635 1679 1636 /* ··· 1687 1640 * can be used. 1688 1641 */ 1689 1642 for (i = 0; i < count; i++) { 1690 - if (args->auth_flavors[0] == server_authlist[i] || 1691 - server_authlist[i] == RPC_AUTH_NULL) 1643 + flavor = server_authlist[i]; 1644 + 1645 + if (nfs_auth_info_match(&args->auth_info, flavor) || 1646 + flavor == RPC_AUTH_NULL) 1692 1647 goto out; 1693 1648 } 1694 1649 1695 - dfprintk(MOUNT, "NFS: auth flavor %u not supported by server\n", 1696 - args->auth_flavors[0]); 1650 + dfprintk(MOUNT, 1651 + "NFS: specified auth flavors not supported by server\n"); 1697 1652 return -EACCES; 1698 1653 1699 1654 out: 1700 - dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]); 1655 + args->selected_flavor = flavor; 1656 + dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->selected_flavor); 1701 1657 return 0; 1702 1658 } 1703 1659 ··· 1788 1738 * Was a sec= authflavor specified in the options? First, verify 1789 1739 * whether the server supports it, and then just try to use it if so. 1790 1740 */ 1791 - if (args->auth_flavor_len > 0) { 1792 - status = nfs_verify_authflavor(args, authlist, authlist_len); 1793 - dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]); 1741 + if (args->auth_info.flavor_len > 0) { 1742 + status = nfs_verify_authflavors(args, authlist, authlist_len); 1743 + dfprintk(MOUNT, "NFS: using auth flavor %u\n", 1744 + args->selected_flavor); 1794 1745 if (status) 1795 1746 return ERR_PTR(status); 1796 1747 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); ··· 1820 1769 /* Fallthrough */ 1821 1770 } 1822 1771 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor); 1823 - nfs_set_auth_parsed_mount_data(args, flavor); 1772 + args->selected_flavor = flavor; 1824 1773 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1825 1774 if (!IS_ERR(server)) 1826 1775 return server; ··· 1836 1785 1837 1786 /* Last chance! Try AUTH_UNIX */ 1838 1787 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX); 1839 - nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX); 1788 + args->selected_flavor = RPC_AUTH_UNIX; 1840 1789 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1841 1790 } 1842 1791 ··· 2023 1972 args->bsize = data->bsize; 2024 1973 2025 1974 if (data->flags & NFS_MOUNT_SECFLAVOUR) 2026 - nfs_set_auth_parsed_mount_data(args, data->pseudoflavor); 1975 + args->selected_flavor = data->pseudoflavor; 2027 1976 else 2028 - nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX); 1977 + args->selected_flavor = RPC_AUTH_UNIX; 2029 1978 if (!args->nfs_server.hostname) 2030 1979 goto out_nomem; 2031 1980 ··· 2159 2108 2160 2109 nfs_set_port(sap, &args->nfs_server.port, port); 2161 2110 2162 - if (args->auth_flavor_len > 1) 2163 - goto out_bad_auth; 2164 - 2165 2111 return nfs_parse_devname(dev_name, 2166 2112 &args->nfs_server.hostname, 2167 2113 max_namelen, ··· 2178 2130 out_no_address: 2179 2131 dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); 2180 2132 return -EINVAL; 2181 - 2182 - out_bad_auth: 2183 - dfprintk(MOUNT, "NFS: Too many RPC auth flavours specified\n"); 2184 - return -EINVAL; 2185 2133 } 2186 2134 2187 2135 static int ··· 2187 2143 if (data->flags != nfss->flags || 2188 2144 data->rsize != nfss->rsize || 2189 2145 data->wsize != nfss->wsize || 2146 + data->version != nfss->nfs_client->rpc_ops->version || 2147 + data->minorversion != nfss->nfs_client->cl_minorversion || 2190 2148 data->retrans != nfss->client->cl_timeout->to_retries || 2191 - data->auth_flavors[0] != nfss->client->cl_auth->au_flavor || 2149 + data->selected_flavor != nfss->client->cl_auth->au_flavor || 2192 2150 data->acregmin != nfss->acregmin / HZ || 2193 2151 data->acregmax != nfss->acregmax / HZ || 2194 2152 data->acdirmin != nfss->acdirmin / HZ || ··· 2235 2189 data->rsize = nfss->rsize; 2236 2190 data->wsize = nfss->wsize; 2237 2191 data->retrans = nfss->client->cl_timeout->to_retries; 2238 - nfs_set_auth_parsed_mount_data(data, nfss->client->cl_auth->au_flavor); 2192 + data->selected_flavor = nfss->client->cl_auth->au_flavor; 2193 + data->auth_info = nfss->auth_info; 2239 2194 data->acregmin = nfss->acregmin / HZ; 2240 2195 data->acregmax = nfss->acregmax / HZ; 2241 2196 data->acdirmin = nfss->acdirmin / HZ; ··· 2244 2197 data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; 2245 2198 data->nfs_server.port = nfss->port; 2246 2199 data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; 2200 + data->version = nfsvers; 2201 + data->minorversion = nfss->nfs_client->cl_minorversion; 2247 2202 memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr, 2248 2203 data->nfs_server.addrlen); 2249 2204 2250 2205 /* overwrite those values with any that were specified */ 2251 - error = nfs_parse_mount_options((char *)options, data); 2252 - if (error < 0) 2206 + error = -EINVAL; 2207 + if (!nfs_parse_mount_options((char *)options, data)) 2253 2208 goto out; 2254 2209 2255 2210 /* ··· 2381 2332 goto Ebusy; 2382 2333 if (a->acdirmax != b->acdirmax) 2383 2334 goto Ebusy; 2384 - if (b->flags & NFS_MOUNT_SECFLAVOUR && 2335 + if (b->auth_info.flavor_len > 0 && 2385 2336 clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor) 2386 2337 goto Ebusy; 2387 2338 return 1; ··· 2579 2530 mntroot = ERR_PTR(error); 2580 2531 goto error_splat_bdi; 2581 2532 } 2533 + server->super = s; 2582 2534 } 2583 2535 2584 2536 if (!s->s_root) { ··· 2763 2713 data->auth_flavours, 2764 2714 sizeof(pseudoflavor))) 2765 2715 return -EFAULT; 2766 - nfs_set_auth_parsed_mount_data(args, pseudoflavor); 2716 + args->selected_flavor = pseudoflavor; 2767 2717 } else 2768 - nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX); 2718 + args->selected_flavor = RPC_AUTH_UNIX; 2769 2719 2770 2720 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 2771 2721 if (IS_ERR(c))
+1 -2
fs/nfs/unlink.c
··· 493 493 unsigned long long fileid; 494 494 struct dentry *sdentry; 495 495 struct rpc_task *task; 496 - int error = -EIO; 496 + int error = -EBUSY; 497 497 498 498 dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n", 499 499 dentry->d_parent->d_name.name, dentry->d_name.name, ··· 503 503 /* 504 504 * We don't allow a dentry to be silly-renamed twice. 505 505 */ 506 - error = -EBUSY; 507 506 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) 508 507 goto out; 509 508
+5
include/linux/fs.h
··· 2292 2292 if (file) 2293 2293 atomic_inc(&file_inode(file)->i_writecount); 2294 2294 } 2295 + static inline bool inode_is_open_for_write(const struct inode *inode) 2296 + { 2297 + return atomic_read(&inode->i_writecount) > 0; 2298 + } 2299 + 2295 2300 #ifdef CONFIG_IMA 2296 2301 static inline void i_readcount_dec(struct inode *inode) 2297 2302 {
+18 -32
include/linux/fscache-cache.h
··· 308 308 void (*dissociate_pages)(struct fscache_cache *cache); 309 309 }; 310 310 311 - /* 312 - * data file or index object cookie 313 - * - a file will only appear in one cache 314 - * - a request to cache a file may or may not be honoured, subject to 315 - * constraints such as disk space 316 - * - indices are created on disk just-in-time 317 - */ 318 - struct fscache_cookie { 319 - atomic_t usage; /* number of users of this cookie */ 320 - atomic_t n_children; /* number of children of this cookie */ 321 - atomic_t n_active; /* number of active users of netfs ptrs */ 322 - spinlock_t lock; 323 - spinlock_t stores_lock; /* lock on page store tree */ 324 - struct hlist_head backing_objects; /* object(s) backing this file/index */ 325 - const struct fscache_cookie_def *def; /* definition */ 326 - struct fscache_cookie *parent; /* parent of this entry */ 327 - void *netfs_data; /* back pointer to netfs */ 328 - struct radix_tree_root stores; /* pages to be stored on this cookie */ 329 - #define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ 330 - #define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */ 331 - 332 - unsigned long flags; 333 - #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ 334 - #define FSCACHE_COOKIE_NO_DATA_YET 1 /* T if new object with no cached data yet */ 335 - #define FSCACHE_COOKIE_UNAVAILABLE 2 /* T if cookie is unavailable (error, etc) */ 336 - #define FSCACHE_COOKIE_INVALIDATING 3 /* T if cookie is being invalidated */ 337 - #define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */ 338 - #define FSCACHE_COOKIE_RETIRED 5 /* T if cookie was retired */ 339 - }; 340 - 341 311 extern struct fscache_cookie fscache_fsdef_index; 342 312 343 313 /* ··· 370 400 #define FSCACHE_OBJECT_IS_LIVE 3 /* T if object is not withdrawn or relinquished */ 371 401 #define FSCACHE_OBJECT_IS_LOOKED_UP 4 /* T if object has been looked up */ 372 402 #define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */ 403 + #define FSCACHE_OBJECT_RETIRED 6 /* T if object was retired on relinquishment */ 373 404 374 405 struct list_head cache_link; /* link in cache->object_list */ 375 406 struct hlist_node cookie_link; /* link in cookie->backing_objects */ ··· 482 511 op->end_io_func(page, op->context, error); 483 512 } 484 513 514 + static inline void __fscache_use_cookie(struct fscache_cookie *cookie) 515 + { 516 + atomic_inc(&cookie->n_active); 517 + } 518 + 485 519 /** 486 520 * fscache_use_cookie - Request usage of cookie attached to an object 487 521 * @object: Object description ··· 500 524 return atomic_inc_not_zero(&cookie->n_active) != 0; 501 525 } 502 526 527 + static inline bool __fscache_unuse_cookie(struct fscache_cookie *cookie) 528 + { 529 + return atomic_dec_and_test(&cookie->n_active); 530 + } 531 + 532 + static inline void __fscache_wake_unused_cookie(struct fscache_cookie *cookie) 533 + { 534 + wake_up_atomic_t(&cookie->n_active); 535 + } 536 + 503 537 /** 504 538 * fscache_unuse_cookie - Cease usage of cookie attached to an object 505 539 * @object: Object description ··· 520 534 static inline void fscache_unuse_cookie(struct fscache_object *object) 521 535 { 522 536 struct fscache_cookie *cookie = object->cookie; 523 - if (atomic_dec_and_test(&cookie->n_active)) 524 - wake_up_atomic_t(&cookie->n_active); 537 + if (__fscache_unuse_cookie(cookie)) 538 + __fscache_wake_unused_cookie(cookie); 525 539 } 526 540 527 541 /*
+99 -14
include/linux/fscache.h
··· 167 167 }; 168 168 169 169 /* 170 + * data file or index object cookie 171 + * - a file will only appear in one cache 172 + * - a request to cache a file may or may not be honoured, subject to 173 + * constraints such as disk space 174 + * - indices are created on disk just-in-time 175 + */ 176 + struct fscache_cookie { 177 + atomic_t usage; /* number of users of this cookie */ 178 + atomic_t n_children; /* number of children of this cookie */ 179 + atomic_t n_active; /* number of active users of netfs ptrs */ 180 + spinlock_t lock; 181 + spinlock_t stores_lock; /* lock on page store tree */ 182 + struct hlist_head backing_objects; /* object(s) backing this file/index */ 183 + const struct fscache_cookie_def *def; /* definition */ 184 + struct fscache_cookie *parent; /* parent of this entry */ 185 + void *netfs_data; /* back pointer to netfs */ 186 + struct radix_tree_root stores; /* pages to be stored on this cookie */ 187 + #define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ 188 + #define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */ 189 + 190 + unsigned long flags; 191 + #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ 192 + #define FSCACHE_COOKIE_NO_DATA_YET 1 /* T if new object with no cached data yet */ 193 + #define FSCACHE_COOKIE_UNAVAILABLE 2 /* T if cookie is unavailable (error, etc) */ 194 + #define FSCACHE_COOKIE_INVALIDATING 3 /* T if cookie is being invalidated */ 195 + #define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */ 196 + #define FSCACHE_COOKIE_ENABLED 5 /* T if cookie is enabled */ 197 + #define FSCACHE_COOKIE_ENABLEMENT_LOCK 6 /* T if cookie is being en/disabled */ 198 + }; 199 + 200 + static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie) 201 + { 202 + return test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 203 + } 204 + 205 + /* 170 206 * slow-path functions for when there is actually caching available, and the 171 207 * netfs does actually have a valid token 172 208 * - these are not to be called directly ··· 217 181 extern struct fscache_cookie *__fscache_acquire_cookie( 218 182 struct fscache_cookie *, 219 183 const struct fscache_cookie_def *, 220 - void *); 221 - extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); 184 + void *, bool); 185 + extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); 222 186 extern int __fscache_check_consistency(struct fscache_cookie *); 223 187 extern void __fscache_update_cookie(struct fscache_cookie *); 224 188 extern int __fscache_attr_changed(struct fscache_cookie *); ··· 247 211 struct inode *); 248 212 extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, 249 213 struct list_head *pages); 214 + extern void __fscache_disable_cookie(struct fscache_cookie *, bool); 215 + extern void __fscache_enable_cookie(struct fscache_cookie *, 216 + bool (*)(void *), void *); 250 217 251 218 /** 252 219 * fscache_register_netfs - Register a filesystem as desiring caching services ··· 328 289 * @def: A description of the cache object, including callback operations 329 290 * @netfs_data: An arbitrary piece of data to be kept in the cookie to 330 291 * represent the cache object to the netfs 292 + * @enable: Whether or not to enable a data cookie immediately 331 293 * 332 294 * This function is used to inform FS-Cache about part of an index hierarchy 333 295 * that can be used to locate files. This is done by requesting a cookie for ··· 341 301 struct fscache_cookie *fscache_acquire_cookie( 342 302 struct fscache_cookie *parent, 343 303 const struct fscache_cookie_def *def, 344 - void *netfs_data) 304 + void *netfs_data, 305 + bool enable) 345 306 { 346 - if (fscache_cookie_valid(parent)) 347 - return __fscache_acquire_cookie(parent, def, netfs_data); 307 + if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent)) 308 + return __fscache_acquire_cookie(parent, def, netfs_data, 309 + enable); 348 310 else 349 311 return NULL; 350 312 } ··· 364 322 * description. 365 323 */ 366 324 static inline 367 - void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) 325 + void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) 368 326 { 369 327 if (fscache_cookie_valid(cookie)) 370 328 __fscache_relinquish_cookie(cookie, retire); ··· 383 341 static inline 384 342 int fscache_check_consistency(struct fscache_cookie *cookie) 385 343 { 386 - if (fscache_cookie_valid(cookie)) 344 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 387 345 return __fscache_check_consistency(cookie); 388 346 else 389 347 return 0; ··· 402 360 static inline 403 361 void fscache_update_cookie(struct fscache_cookie *cookie) 404 362 { 405 - if (fscache_cookie_valid(cookie)) 363 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 406 364 __fscache_update_cookie(cookie); 407 365 } 408 366 ··· 449 407 static inline 450 408 int fscache_attr_changed(struct fscache_cookie *cookie) 451 409 { 452 - if (fscache_cookie_valid(cookie)) 410 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 453 411 return __fscache_attr_changed(cookie); 454 412 else 455 413 return -ENOBUFS; ··· 471 429 static inline 472 430 void fscache_invalidate(struct fscache_cookie *cookie) 473 431 { 474 - if (fscache_cookie_valid(cookie)) 432 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 475 433 __fscache_invalidate(cookie); 476 434 } 477 435 ··· 545 503 void *context, 546 504 gfp_t gfp) 547 505 { 548 - if (fscache_cookie_valid(cookie)) 506 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 549 507 return __fscache_read_or_alloc_page(cookie, page, end_io_func, 550 508 context, gfp); 551 509 else ··· 596 554 void *context, 597 555 gfp_t gfp) 598 556 { 599 - if (fscache_cookie_valid(cookie)) 557 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 600 558 return __fscache_read_or_alloc_pages(cookie, mapping, pages, 601 559 nr_pages, end_io_func, 602 560 context, gfp); ··· 627 585 struct page *page, 628 586 gfp_t gfp) 629 587 { 630 - if (fscache_cookie_valid(cookie)) 588 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 631 589 return __fscache_alloc_page(cookie, page, gfp); 632 590 else 633 591 return -ENOBUFS; ··· 676 634 struct page *page, 677 635 gfp_t gfp) 678 636 { 679 - if (fscache_cookie_valid(cookie)) 637 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 680 638 return __fscache_write_page(cookie, page, gfp); 681 639 else 682 640 return -ENOBUFS; ··· 784 742 { 785 743 if (fscache_cookie_valid(cookie)) 786 744 __fscache_uncache_all_inode_pages(cookie, inode); 745 + } 746 + 747 + /** 748 + * fscache_disable_cookie - Disable a cookie 749 + * @cookie: The cookie representing the cache object 750 + * @invalidate: Invalidate the backing object 751 + * 752 + * Disable a cookie from accepting further alloc, read, write, invalidate, 753 + * update or acquire operations. Outstanding operations can still be waited 754 + * upon and pages can still be uncached and the cookie relinquished. 755 + * 756 + * This will not return until all outstanding operations have completed. 757 + * 758 + * If @invalidate is set, then the backing object will be invalidated and 759 + * detached, otherwise it will just be detached. 760 + */ 761 + static inline 762 + void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) 763 + { 764 + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) 765 + __fscache_disable_cookie(cookie, invalidate); 766 + } 767 + 768 + /** 769 + * fscache_enable_cookie - Reenable a cookie 770 + * @cookie: The cookie representing the cache object 771 + * @can_enable: A function to permit enablement once lock is held 772 + * @data: Data for can_enable() 773 + * 774 + * Reenable a previously disabled cookie, allowing it to accept further alloc, 775 + * read, write, invalidate, update or acquire operations. An attempt will be 776 + * made to immediately reattach the cookie to a backing object. 777 + * 778 + * The can_enable() function is called (if not NULL) once the enablement lock 779 + * is held to rule on whether enablement is still permitted to go ahead. 780 + */ 781 + static inline 782 + void fscache_enable_cookie(struct fscache_cookie *cookie, 783 + bool (*can_enable)(void *data), 784 + void *data) 785 + { 786 + if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie)) 787 + __fscache_enable_cookie(cookie, can_enable, data); 787 788 } 788 789 789 790 #endif /* _LINUX_FSCACHE_H */
+4 -1
include/linux/nfs4.h
··· 395 395 #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) 396 396 #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) 397 397 #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) 398 - #define FATTR4_WORD2_SECURITY_LABEL (1UL << 17) 398 + #define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) 399 + #define FATTR4_WORD2_CHANGE_SECURITY_LABEL \ 400 + (1UL << 17) 399 401 400 402 /* MDS threshold bitmap bits */ 401 403 #define THRESHOLD_RD (1UL << 0) ··· 462 460 NFSPROC4_CLNT_FS_LOCATIONS, 463 461 NFSPROC4_CLNT_RELEASE_LOCKOWNER, 464 462 NFSPROC4_CLNT_SECINFO, 463 + NFSPROC4_CLNT_FSID_PRESENT, 465 464 466 465 /* nfs41 */ 467 466 NFSPROC4_CLNT_EXCHANGE_ID,
+6 -2
include/linux/nfs_fs.h
··· 269 269 return test_bit(NFS_INO_STALE, &NFS_I(inode)->flags); 270 270 } 271 271 272 - static inline int NFS_FSCACHE(const struct inode *inode) 272 + static inline struct fscache_cookie *nfs_i_fscache(struct inode *inode) 273 273 { 274 - return test_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); 274 + #ifdef CONFIG_NFS_FSCACHE 275 + return NFS_I(inode)->fscache; 276 + #else 277 + return NULL; 278 + #endif 275 279 } 276 280 277 281 static inline __u64 NFS_FILEID(const struct inode *inode)
+10
include/linux/nfs_fs_sb.h
··· 41 41 #define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */ 42 42 #define NFS_CS_MIGRATION 2 /* - transparent state migr */ 43 43 #define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */ 44 + #define NFS_CS_NO_RETRANS_TIMEOUT 4 /* - Disable retransmit timeouts */ 44 45 struct sockaddr_storage cl_addr; /* server identifier */ 45 46 size_t cl_addrlen; 46 47 char * cl_hostname; /* hostname of server */ ··· 79 78 char cl_ipaddr[48]; 80 79 u32 cl_cb_ident; /* v4.0 callback identifier */ 81 80 const struct nfs4_minor_version_ops *cl_mvops; 81 + unsigned long cl_mig_gen; 82 82 83 83 /* NFSv4.0 transport blocking */ 84 84 struct nfs4_slot_table *cl_slot_tbl; ··· 149 147 __u64 maxfilesize; /* maximum file size */ 150 148 struct timespec time_delta; /* smallest time granularity */ 151 149 unsigned long mount_time; /* when this fs was mounted */ 150 + struct super_block *super; /* VFS super block */ 152 151 dev_t s_dev; /* superblock dev numbers */ 152 + struct nfs_auth_info auth_info; /* parsed auth flavors */ 153 153 154 154 #ifdef CONFIG_NFS_FSCACHE 155 155 struct nfs_fscache_key *fscache_key; /* unique key for superblock */ ··· 191 187 struct list_head state_owners_lru; 192 188 struct list_head layouts; 193 189 struct list_head delegations; 190 + 191 + unsigned long mig_gen; 192 + unsigned long mig_status; 193 + #define NFS_MIG_IN_TRANSITION (1) 194 + #define NFS_MIG_FAILED (2) 195 + 194 196 void (*destroy)(struct nfs_server *); 195 197 196 198 atomic_t active; /* Keep trace of any activity to this server */
+24
include/linux/nfs_xdr.h
··· 591 591 struct nfs_fattr *new_fattr; 592 592 }; 593 593 594 + /* parsed sec= options */ 595 + #define NFS_AUTH_INFO_MAX_FLAVORS 12 /* see fs/nfs/super.c */ 596 + struct nfs_auth_info { 597 + unsigned int flavor_len; 598 + rpc_authflavor_t flavors[NFS_AUTH_INFO_MAX_FLAVORS]; 599 + }; 600 + 594 601 /* 595 602 * Argument struct for decode_entry function 596 603 */ ··· 1060 1053 struct nfs4_fs_locations_arg { 1061 1054 struct nfs4_sequence_args seq_args; 1062 1055 const struct nfs_fh *dir_fh; 1056 + const struct nfs_fh *fh; 1063 1057 const struct qstr *name; 1064 1058 struct page *page; 1065 1059 const u32 *bitmask; 1060 + clientid4 clientid; 1061 + unsigned char migration:1, renew:1; 1066 1062 }; 1067 1063 1068 1064 struct nfs4_fs_locations_res { 1069 1065 struct nfs4_sequence_res seq_res; 1070 1066 struct nfs4_fs_locations *fs_locations; 1067 + unsigned char migration:1, renew:1; 1071 1068 }; 1072 1069 1073 1070 struct nfs4_secinfo4 { ··· 1093 1082 struct nfs4_secinfo_res { 1094 1083 struct nfs4_sequence_res seq_res; 1095 1084 struct nfs4_secinfo_flavors *flavors; 1085 + }; 1086 + 1087 + struct nfs4_fsid_present_arg { 1088 + struct nfs4_sequence_args seq_args; 1089 + const struct nfs_fh *fh; 1090 + clientid4 clientid; 1091 + unsigned char renew:1; 1092 + }; 1093 + 1094 + struct nfs4_fsid_present_res { 1095 + struct nfs4_sequence_res seq_res; 1096 + struct nfs_fh *fh; 1097 + unsigned char renew:1; 1096 1098 }; 1097 1099 1098 1100 #endif /* CONFIG_NFS_V4 */
+6
include/linux/sunrpc/clnt.h
··· 49 49 50 50 unsigned int cl_softrtry : 1,/* soft timeouts */ 51 51 cl_discrtry : 1,/* disconnect before retry */ 52 + cl_noretranstimeo: 1,/* No retransmit timeouts */ 52 53 cl_autobind : 1,/* use getport() */ 53 54 cl_chatty : 1;/* be verbose */ 54 55 ··· 127 126 #define RPC_CLNT_CREATE_QUIET (1UL << 6) 128 127 #define RPC_CLNT_CREATE_INFINITE_SLOTS (1UL << 7) 129 128 #define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT (1UL << 8) 129 + #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9) 130 130 131 131 struct rpc_clnt *rpc_create(struct rpc_create_args *args); 132 132 struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, ··· 136 134 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); 137 135 struct rpc_clnt *rpc_clone_client_set_auth(struct rpc_clnt *, 138 136 rpc_authflavor_t); 137 + int rpc_switch_client_transport(struct rpc_clnt *, 138 + struct xprt_create *, 139 + const struct rpc_timeout *); 140 + 139 141 void rpc_shutdown_client(struct rpc_clnt *); 140 142 void rpc_release_client(struct rpc_clnt *); 141 143 void rpc_task_release_client(struct rpc_task *);
+1
include/linux/sunrpc/sched.h
··· 122 122 #define RPC_TASK_SENT 0x0800 /* message was sent */ 123 123 #define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */ 124 124 #define RPC_TASK_NOCONNECT 0x2000 /* return ENOTCONN if not connected */ 125 + #define RPC_TASK_NO_RETRANS_TIMEOUT 0x4000 /* wait forever for a reply */ 125 126 126 127 #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) 127 128 #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
+1 -1
include/linux/sunrpc/xprt.h
··· 288 288 int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); 289 289 void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); 290 290 void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); 291 - int xprt_prepare_transmit(struct rpc_task *task); 291 + bool xprt_prepare_transmit(struct rpc_task *task); 292 292 void xprt_transmit(struct rpc_task *task); 293 293 void xprt_end_transmit(struct rpc_task *task); 294 294 int xprt_adjust_timeout(struct rpc_rqst *req);
+1 -1
include/uapi/linux/nfs_mount.h
··· 60 60 #define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */ 61 61 #define NFS_MOUNT_NOACL 0x0800 /* 4 */ 62 62 #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */ 63 - #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ 63 + #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 non-text parsed mount data only */ 64 64 #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */ 65 65 #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */ 66 66 #define NFS_MOUNT_FLAGMASK 0xFFFF
+37 -18
net/sunrpc/auth_gss/auth_gss.c
··· 420 420 memcpy(gss_msg->databuf, &uid, sizeof(uid)); 421 421 gss_msg->msg.data = gss_msg->databuf; 422 422 gss_msg->msg.len = sizeof(uid); 423 - BUG_ON(sizeof(uid) > UPCALL_BUF_LEN); 423 + 424 + BUILD_BUG_ON(sizeof(uid) > sizeof(gss_msg->databuf)); 424 425 } 425 426 426 - static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, 427 + static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, 427 428 const char *service_name, 428 429 const char *target_name) 429 430 { 430 431 struct gss_api_mech *mech = gss_msg->auth->mech; 431 432 char *p = gss_msg->databuf; 432 - int len = 0; 433 + size_t buflen = sizeof(gss_msg->databuf); 434 + int len; 433 435 434 - gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", 435 - mech->gm_name, 436 - from_kuid(&init_user_ns, gss_msg->uid)); 437 - p += gss_msg->msg.len; 436 + len = scnprintf(p, buflen, "mech=%s uid=%d ", mech->gm_name, 437 + from_kuid(&init_user_ns, gss_msg->uid)); 438 + buflen -= len; 439 + p += len; 440 + gss_msg->msg.len = len; 438 441 if (target_name) { 439 - len = sprintf(p, "target=%s ", target_name); 442 + len = scnprintf(p, buflen, "target=%s ", target_name); 443 + buflen -= len; 440 444 p += len; 441 445 gss_msg->msg.len += len; 442 446 } 443 447 if (service_name != NULL) { 444 - len = sprintf(p, "service=%s ", service_name); 448 + len = scnprintf(p, buflen, "service=%s ", service_name); 449 + buflen -= len; 445 450 p += len; 446 451 gss_msg->msg.len += len; 447 452 } 448 453 if (mech->gm_upcall_enctypes) { 449 - len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes); 454 + len = scnprintf(p, buflen, "enctypes=%s ", 455 + mech->gm_upcall_enctypes); 456 + buflen -= len; 450 457 p += len; 451 458 gss_msg->msg.len += len; 452 459 } 453 - len = sprintf(p, "\n"); 460 + len = scnprintf(p, buflen, "\n"); 461 + if (len == 0) 462 + goto out_overflow; 454 463 gss_msg->msg.len += len; 455 464 456 465 gss_msg->msg.data = gss_msg->databuf; 457 - BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN); 466 + return 0; 467 + out_overflow: 468 + WARN_ON_ONCE(1); 469 + return -ENOMEM; 458 470 } 459 471 460 472 static struct gss_upcall_msg * ··· 475 463 { 476 464 struct gss_upcall_msg *gss_msg; 477 465 int vers; 466 + int err = -ENOMEM; 478 467 479 468 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); 480 469 if (gss_msg == NULL) 481 - return ERR_PTR(-ENOMEM); 470 + goto err; 482 471 vers = get_pipe_version(gss_auth->net); 483 - if (vers < 0) { 484 - kfree(gss_msg); 485 - return ERR_PTR(vers); 486 - } 472 + err = vers; 473 + if (err < 0) 474 + goto err_free_msg; 487 475 gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe; 488 476 INIT_LIST_HEAD(&gss_msg->list); 489 477 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); ··· 494 482 switch (vers) { 495 483 case 0: 496 484 gss_encode_v0_msg(gss_msg); 485 + break; 497 486 default: 498 - gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); 487 + err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); 488 + if (err) 489 + goto err_free_msg; 499 490 }; 500 491 return gss_msg; 492 + err_free_msg: 493 + kfree(gss_msg); 494 + err: 495 + return ERR_PTR(err); 501 496 } 502 497 503 498 static struct gss_upcall_msg *
+124 -24
net/sunrpc/clnt.c
··· 25 25 #include <linux/namei.h> 26 26 #include <linux/mount.h> 27 27 #include <linux/slab.h> 28 + #include <linux/rcupdate.h> 28 29 #include <linux/utsname.h> 29 30 #include <linux/workqueue.h> 30 31 #include <linux/in.h> 31 32 #include <linux/in6.h> 32 33 #include <linux/un.h> 33 - #include <linux/rcupdate.h> 34 34 35 35 #include <linux/sunrpc/clnt.h> 36 36 #include <linux/sunrpc/addr.h> ··· 264 264 return rpc_pipefs_notifier_unregister(&rpc_clients_block); 265 265 } 266 266 267 + static struct rpc_xprt *rpc_clnt_set_transport(struct rpc_clnt *clnt, 268 + struct rpc_xprt *xprt, 269 + const struct rpc_timeout *timeout) 270 + { 271 + struct rpc_xprt *old; 272 + 273 + spin_lock(&clnt->cl_lock); 274 + old = rcu_dereference_protected(clnt->cl_xprt, 275 + lockdep_is_held(&clnt->cl_lock)); 276 + 277 + if (!xprt_bound(xprt)) 278 + clnt->cl_autobind = 1; 279 + 280 + clnt->cl_timeout = timeout; 281 + rcu_assign_pointer(clnt->cl_xprt, xprt); 282 + spin_unlock(&clnt->cl_lock); 283 + 284 + return old; 285 + } 286 + 267 287 static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename) 268 288 { 269 289 clnt->cl_nodelen = strlen(nodename); ··· 292 272 memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); 293 273 } 294 274 295 - static int rpc_client_register(const struct rpc_create_args *args, 296 - struct rpc_clnt *clnt) 275 + static int rpc_client_register(struct rpc_clnt *clnt, 276 + rpc_authflavor_t pseudoflavor, 277 + const char *client_name) 297 278 { 298 279 struct rpc_auth_create_args auth_args = { 299 - .pseudoflavor = args->authflavor, 300 - .target_name = args->client_name, 280 + .pseudoflavor = pseudoflavor, 281 + .target_name = client_name, 301 282 }; 302 283 struct rpc_auth *auth; 303 284 struct net *net = rpc_net_ns(clnt); ··· 319 298 auth = rpcauth_create(&auth_args, clnt); 320 299 if (IS_ERR(auth)) { 321 300 dprintk("RPC: Couldn't create auth handle (flavor %u)\n", 322 - args->authflavor); 301 + pseudoflavor); 323 302 err = PTR_ERR(auth); 324 303 goto err_auth; 325 304 } ··· 358 337 { 359 338 const struct rpc_program *program = args->program; 360 339 const struct rpc_version *version; 361 - struct rpc_clnt *clnt = NULL; 340 + struct rpc_clnt *clnt = NULL; 341 + const struct rpc_timeout *timeout; 362 342 int err; 363 343 364 344 /* sanity check the name before trying to print it */ ··· 387 365 if (err) 388 366 goto out_no_clid; 389 367 390 - rcu_assign_pointer(clnt->cl_xprt, xprt); 391 368 clnt->cl_procinfo = version->procs; 392 369 clnt->cl_maxproc = version->nrprocs; 393 370 clnt->cl_prog = args->prognumber ? : program->number; ··· 401 380 INIT_LIST_HEAD(&clnt->cl_tasks); 402 381 spin_lock_init(&clnt->cl_lock); 403 382 404 - if (!xprt_bound(xprt)) 405 - clnt->cl_autobind = 1; 406 - 407 - clnt->cl_timeout = xprt->timeout; 383 + timeout = xprt->timeout; 408 384 if (args->timeout != NULL) { 409 385 memcpy(&clnt->cl_timeout_default, args->timeout, 410 386 sizeof(clnt->cl_timeout_default)); 411 - clnt->cl_timeout = &clnt->cl_timeout_default; 387 + timeout = &clnt->cl_timeout_default; 412 388 } 389 + 390 + rpc_clnt_set_transport(clnt, xprt, timeout); 413 391 414 392 clnt->cl_rtt = &clnt->cl_rtt_default; 415 393 rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); ··· 418 398 /* save the nodename */ 419 399 rpc_clnt_set_nodename(clnt, utsname()->nodename); 420 400 421 - err = rpc_client_register(args, clnt); 401 + err = rpc_client_register(clnt, args->authflavor, args->client_name); 422 402 if (err) 423 403 goto out_no_path; 424 404 if (parent) ··· 620 600 } 621 601 EXPORT_SYMBOL_GPL(rpc_clone_client_set_auth); 622 602 603 + /** 604 + * rpc_switch_client_transport: switch the RPC transport on the fly 605 + * @clnt: pointer to a struct rpc_clnt 606 + * @args: pointer to the new transport arguments 607 + * @timeout: pointer to the new timeout parameters 608 + * 609 + * This function allows the caller to switch the RPC transport for the 610 + * rpc_clnt structure 'clnt' to allow it to connect to a mirrored NFS 611 + * server, for instance. It assumes that the caller has ensured that 612 + * there are no active RPC tasks by using some form of locking. 613 + * 614 + * Returns zero if "clnt" is now using the new xprt. Otherwise a 615 + * negative errno is returned, and "clnt" continues to use the old 616 + * xprt. 617 + */ 618 + int rpc_switch_client_transport(struct rpc_clnt *clnt, 619 + struct xprt_create *args, 620 + const struct rpc_timeout *timeout) 621 + { 622 + const struct rpc_timeout *old_timeo; 623 + rpc_authflavor_t pseudoflavor; 624 + struct rpc_xprt *xprt, *old; 625 + struct rpc_clnt *parent; 626 + int err; 627 + 628 + xprt = xprt_create_transport(args); 629 + if (IS_ERR(xprt)) { 630 + dprintk("RPC: failed to create new xprt for clnt %p\n", 631 + clnt); 632 + return PTR_ERR(xprt); 633 + } 634 + 635 + pseudoflavor = clnt->cl_auth->au_flavor; 636 + 637 + old_timeo = clnt->cl_timeout; 638 + old = rpc_clnt_set_transport(clnt, xprt, timeout); 639 + 640 + rpc_unregister_client(clnt); 641 + __rpc_clnt_remove_pipedir(clnt); 642 + 643 + /* 644 + * A new transport was created. "clnt" therefore 645 + * becomes the root of a new cl_parent tree. clnt's 646 + * children, if it has any, still point to the old xprt. 647 + */ 648 + parent = clnt->cl_parent; 649 + clnt->cl_parent = clnt; 650 + 651 + /* 652 + * The old rpc_auth cache cannot be re-used. GSS 653 + * contexts in particular are between a single 654 + * client and server. 655 + */ 656 + err = rpc_client_register(clnt, pseudoflavor, NULL); 657 + if (err) 658 + goto out_revert; 659 + 660 + synchronize_rcu(); 661 + if (parent != clnt) 662 + rpc_release_client(parent); 663 + xprt_put(old); 664 + dprintk("RPC: replaced xprt for clnt %p\n", clnt); 665 + return 0; 666 + 667 + out_revert: 668 + rpc_clnt_set_transport(clnt, old, old_timeo); 669 + clnt->cl_parent = parent; 670 + rpc_client_register(clnt, pseudoflavor, NULL); 671 + xprt_put(xprt); 672 + dprintk("RPC: failed to switch xprt for clnt %p\n", clnt); 673 + return err; 674 + } 675 + EXPORT_SYMBOL_GPL(rpc_switch_client_transport); 676 + 623 677 /* 624 678 * Kill all tasks for the given client. 625 679 * XXX: kill their descendants as well? ··· 866 772 atomic_inc(&clnt->cl_count); 867 773 if (clnt->cl_softrtry) 868 774 task->tk_flags |= RPC_TASK_SOFT; 775 + if (clnt->cl_noretranstimeo) 776 + task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT; 869 777 if (sk_memalloc_socks()) { 870 778 struct rpc_xprt *xprt; 871 779 ··· 1786 1690 dprint_status(task); 1787 1691 1788 1692 trace_rpc_connect_status(task, status); 1693 + task->tk_status = 0; 1789 1694 switch (status) { 1790 1695 /* if soft mounted, test if we've timed out */ 1791 1696 case -ETIMEDOUT: ··· 1795 1698 case -ECONNREFUSED: 1796 1699 case -ECONNRESET: 1797 1700 case -ENETUNREACH: 1701 + /* retry with existing socket, after a delay */ 1702 + rpc_delay(task, 3*HZ); 1798 1703 if (RPC_IS_SOFTCONN(task)) 1799 1704 break; 1800 - /* retry with existing socket, after a delay */ 1801 - case 0: 1802 1705 case -EAGAIN: 1803 - task->tk_status = 0; 1706 + task->tk_action = call_bind; 1707 + return; 1708 + case 0: 1804 1709 clnt->cl_stats->netreconn++; 1805 1710 task->tk_action = call_transmit; 1806 1711 return; ··· 1816 1717 static void 1817 1718 call_transmit(struct rpc_task *task) 1818 1719 { 1720 + int is_retrans = RPC_WAS_SENT(task); 1721 + 1819 1722 dprint_status(task); 1820 1723 1821 1724 task->tk_action = call_status; 1822 1725 if (task->tk_status < 0) 1823 1726 return; 1824 - task->tk_status = xprt_prepare_transmit(task); 1825 - if (task->tk_status != 0) 1727 + if (!xprt_prepare_transmit(task)) 1826 1728 return; 1827 1729 task->tk_action = call_transmit_status; 1828 1730 /* Encode here so that rpcsec_gss can use correct sequence number. */ ··· 1842 1742 xprt_transmit(task); 1843 1743 if (task->tk_status < 0) 1844 1744 return; 1745 + if (is_retrans) 1746 + task->tk_client->cl_stats->rpcretrans++; 1845 1747 /* 1846 1748 * On success, ensure that we call xprt_end_transmit() before sleeping 1847 1749 * in order to allow access to the socket to other RPC requests. ··· 1913 1811 { 1914 1812 struct rpc_rqst *req = task->tk_rqstp; 1915 1813 1916 - task->tk_status = xprt_prepare_transmit(task); 1917 - if (task->tk_status == -EAGAIN) { 1814 + if (!xprt_prepare_transmit(task)) { 1918 1815 /* 1919 1816 * Could not reserve the transport. Try again after the 1920 1817 * transport is released. ··· 2001 1900 rpc_delay(task, 3*HZ); 2002 1901 case -ETIMEDOUT: 2003 1902 task->tk_action = call_timeout; 2004 - if (task->tk_client->cl_discrtry) 1903 + if (!(task->tk_flags & RPC_TASK_NO_RETRANS_TIMEOUT) 1904 + && task->tk_client->cl_discrtry) 2005 1905 xprt_conditional_disconnect(req->rq_xprt, 2006 1906 req->rq_connect_cookie); 2007 1907 break; ··· 2084 1982 rpcauth_invalcred(task); 2085 1983 2086 1984 retry: 2087 - clnt->cl_stats->rpcretrans++; 2088 1985 task->tk_action = call_bind; 2089 1986 task->tk_status = 0; 2090 1987 } ··· 2126 2025 if (req->rq_rcv_buf.len < 12) { 2127 2026 if (!RPC_IS_SOFT(task)) { 2128 2027 task->tk_action = call_bind; 2129 - clnt->cl_stats->rpcretrans++; 2130 2028 goto out_retry; 2131 2029 } 2132 2030 dprintk("RPC: %s: too small RPC reply size (%d bytes)\n",
+42 -21
net/sunrpc/xprt.c
··· 205 205 goto out_sleep; 206 206 } 207 207 xprt->snd_task = task; 208 - if (req != NULL) { 209 - req->rq_bytes_sent = 0; 208 + if (req != NULL) 210 209 req->rq_ntrans++; 211 - } 212 210 213 211 return 1; 214 212 ··· 261 263 } 262 264 if (__xprt_get_cong(xprt, task)) { 263 265 xprt->snd_task = task; 264 - req->rq_bytes_sent = 0; 265 266 req->rq_ntrans++; 266 267 return 1; 267 268 } ··· 297 300 298 301 req = task->tk_rqstp; 299 302 xprt->snd_task = task; 300 - if (req) { 301 - req->rq_bytes_sent = 0; 303 + if (req) 302 304 req->rq_ntrans++; 303 - } 304 305 return true; 305 306 } 306 307 ··· 324 329 } 325 330 if (__xprt_get_cong(xprt, task)) { 326 331 xprt->snd_task = task; 327 - req->rq_bytes_sent = 0; 328 332 req->rq_ntrans++; 329 333 return true; 330 334 } ··· 352 358 void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) 353 359 { 354 360 if (xprt->snd_task == task) { 361 + if (task != NULL) { 362 + struct rpc_rqst *req = task->tk_rqstp; 363 + if (req != NULL) 364 + req->rq_bytes_sent = 0; 365 + } 355 366 xprt_clear_locked(xprt); 356 367 __xprt_lock_write_next(xprt); 357 368 } ··· 374 375 void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) 375 376 { 376 377 if (xprt->snd_task == task) { 378 + if (task != NULL) { 379 + struct rpc_rqst *req = task->tk_rqstp; 380 + if (req != NULL) 381 + req->rq_bytes_sent = 0; 382 + } 377 383 xprt_clear_locked(xprt); 378 384 __xprt_lock_write_next_cong(xprt); 379 385 } ··· 858 854 * @task: RPC task about to send a request 859 855 * 860 856 */ 861 - int xprt_prepare_transmit(struct rpc_task *task) 857 + bool xprt_prepare_transmit(struct rpc_task *task) 862 858 { 863 859 struct rpc_rqst *req = task->tk_rqstp; 864 860 struct rpc_xprt *xprt = req->rq_xprt; 865 - int err = 0; 861 + bool ret = false; 866 862 867 863 dprintk("RPC: %5u xprt_prepare_transmit\n", task->tk_pid); 868 864 869 865 spin_lock_bh(&xprt->transport_lock); 870 - if (req->rq_reply_bytes_recvd && !req->rq_bytes_sent) { 871 - err = req->rq_reply_bytes_recvd; 866 + if (!req->rq_bytes_sent) { 867 + if (req->rq_reply_bytes_recvd) { 868 + task->tk_status = req->rq_reply_bytes_recvd; 869 + goto out_unlock; 870 + } 871 + if ((task->tk_flags & RPC_TASK_NO_RETRANS_TIMEOUT) 872 + && xprt_connected(xprt) 873 + && req->rq_connect_cookie == xprt->connect_cookie) { 874 + xprt->ops->set_retrans_timeout(task); 875 + rpc_sleep_on(&xprt->pending, task, xprt_timer); 876 + goto out_unlock; 877 + } 878 + } 879 + if (!xprt->ops->reserve_xprt(xprt, task)) { 880 + task->tk_status = -EAGAIN; 872 881 goto out_unlock; 873 882 } 874 - if (!xprt->ops->reserve_xprt(xprt, task)) 875 - err = -EAGAIN; 883 + ret = true; 876 884 out_unlock: 877 885 spin_unlock_bh(&xprt->transport_lock); 878 - return err; 886 + return ret; 879 887 } 880 888 881 889 void xprt_end_transmit(struct rpc_task *task) ··· 928 912 } else if (!req->rq_bytes_sent) 929 913 return; 930 914 931 - req->rq_connect_cookie = xprt->connect_cookie; 932 915 req->rq_xtime = ktime_get(); 933 916 status = xprt->ops->send_request(task); 934 917 if (status != 0) { ··· 953 938 /* Don't race with disconnect */ 954 939 if (!xprt_connected(xprt)) 955 940 task->tk_status = -ENOTCONN; 956 - else if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task)) { 941 + else { 957 942 /* 958 943 * Sleep on the pending queue since 959 944 * we're expecting a reply. 960 945 */ 961 - rpc_sleep_on(&xprt->pending, task, xprt_timer); 946 + if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task)) 947 + rpc_sleep_on(&xprt->pending, task, xprt_timer); 948 + req->rq_connect_cookie = xprt->connect_cookie; 962 949 } 963 950 spin_unlock_bh(&xprt->transport_lock); 964 951 } ··· 1104 1087 for (i = 0; i < num_prealloc; i++) { 1105 1088 req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL); 1106 1089 if (!req) 1107 - break; 1090 + goto out_free; 1108 1091 list_add(&req->rq_list, &xprt->free); 1109 1092 } 1110 - if (i < num_prealloc) 1111 - goto out_free; 1112 1093 if (max_alloc > num_prealloc) 1113 1094 xprt->max_reqs = max_alloc; 1114 1095 else ··· 1201 1186 req->rq_xprt = xprt; 1202 1187 req->rq_buffer = NULL; 1203 1188 req->rq_xid = xprt_alloc_xid(xprt); 1189 + req->rq_connect_cookie = xprt->connect_cookie - 1; 1190 + req->rq_bytes_sent = 0; 1191 + req->rq_snd_buf.len = 0; 1192 + req->rq_snd_buf.buflen = 0; 1193 + req->rq_rcv_buf.len = 0; 1194 + req->rq_rcv_buf.buflen = 0; 1204 1195 req->rq_release_snd_buf = NULL; 1205 1196 xprt_reset_majortimeo(req); 1206 1197 dprintk("RPC: %5u reserved req %p xid %08x\n", task->tk_pid,
+30 -17
net/sunrpc/xprtsock.c
··· 835 835 836 836 dprintk("RPC: xs_close xprt %p\n", xprt); 837 837 838 + cancel_delayed_work_sync(&transport->connect_worker); 839 + 838 840 xs_reset_transport(transport); 839 841 xprt->reestablish_timeout = 0; 840 842 ··· 856 854 xs_tcp_shutdown(xprt); 857 855 } 858 856 859 - static void xs_local_destroy(struct rpc_xprt *xprt) 860 - { 861 - xs_close(xprt); 862 - xs_free_peer_addresses(xprt); 863 - xprt_free(xprt); 864 - module_put(THIS_MODULE); 865 - } 866 - 867 857 /** 868 858 * xs_destroy - prepare to shutdown a transport 869 859 * @xprt: doomed transport ··· 863 869 */ 864 870 static void xs_destroy(struct rpc_xprt *xprt) 865 871 { 866 - struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 867 - 868 872 dprintk("RPC: xs_destroy xprt %p\n", xprt); 869 873 870 - cancel_delayed_work_sync(&transport->connect_worker); 871 - 872 - xs_local_destroy(xprt); 874 + xs_close(xprt); 875 + xs_free_peer_addresses(xprt); 876 + xprt_free(xprt); 877 + module_put(THIS_MODULE); 873 878 } 874 879 875 880 static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) ··· 1504 1511 transport->tcp_copied = 0; 1505 1512 transport->tcp_flags = 1506 1513 TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; 1514 + xprt->connect_cookie++; 1507 1515 1508 1516 xprt_wake_pending_tasks(xprt, -EAGAIN); 1509 1517 } ··· 1810 1816 } 1811 1817 #endif 1812 1818 1819 + static void xs_dummy_setup_socket(struct work_struct *work) 1820 + { 1821 + } 1822 + 1813 1823 static struct socket *xs_create_sock(struct rpc_xprt *xprt, 1814 1824 struct sock_xprt *transport, int family, int type, int protocol) 1815 1825 { ··· 2110 2112 2111 2113 if (!transport->inet) { 2112 2114 struct sock *sk = sock->sk; 2115 + unsigned int keepidle = xprt->timeout->to_initval / HZ; 2116 + unsigned int keepcnt = xprt->timeout->to_retries + 1; 2117 + unsigned int opt_on = 1; 2118 + 2119 + /* TCP Keepalive options */ 2120 + kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, 2121 + (char *)&opt_on, sizeof(opt_on)); 2122 + kernel_setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, 2123 + (char *)&keepidle, sizeof(keepidle)); 2124 + kernel_setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, 2125 + (char *)&keepidle, sizeof(keepidle)); 2126 + kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT, 2127 + (char *)&keepcnt, sizeof(keepcnt)); 2113 2128 2114 2129 write_lock_bh(&sk->sk_callback_lock); 2115 2130 ··· 2162 2151 case 0: 2163 2152 case -EINPROGRESS: 2164 2153 /* SYN_SENT! */ 2165 - xprt->connect_cookie++; 2166 2154 if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) 2167 2155 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 2168 2156 } ··· 2508 2498 .send_request = xs_local_send_request, 2509 2499 .set_retrans_timeout = xprt_set_retrans_timeout_def, 2510 2500 .close = xs_close, 2511 - .destroy = xs_local_destroy, 2501 + .destroy = xs_destroy, 2512 2502 .print_stats = xs_local_print_stats, 2513 2503 }; 2514 2504 ··· 2664 2654 2665 2655 xprt->ops = &xs_local_ops; 2666 2656 xprt->timeout = &xs_local_default_timeout; 2657 + 2658 + INIT_DELAYED_WORK(&transport->connect_worker, 2659 + xs_dummy_setup_socket); 2667 2660 2668 2661 switch (sun->sun_family) { 2669 2662 case AF_LOCAL: ··· 2872 2859 if (args->bc_xprt->xpt_bc_xprt) { 2873 2860 /* 2874 2861 * This server connection already has a backchannel 2875 - * export; we can't create a new one, as we wouldn't be 2876 - * able to match replies based on xid any more. So, 2862 + * transport; we can't create a new one, as we wouldn't 2863 + * be able to match replies based on xid any more. So, 2877 2864 * reuse the already-existing one: 2878 2865 */ 2879 2866 return args->bc_xprt->xpt_bc_xprt;