Merge branch 'vfs-scale-working' of git://git.kernel.org/pub/scm/linux/kernel/git/npiggin/linux-npiggin

* 'vfs-scale-working' of git://git.kernel.org/pub/scm/linux/kernel/git/npiggin/linux-npiggin:
fs: fix do_last error case when need_reval_dot
nfs: add missing rcu-walk check
fs: hlist UP debug fixup
fs: fix dropping of rcu-walk from force_reval_path
fs: force_reval_path drop rcu-walk before d_invalidate
fs: small rcu-walk documentation fixes

Fixed up trivial conflicts in Documentation/filesystems/porting

+40 -14
+4 -4
Documentation/filesystems/porting
··· 365 365 [recommended] 366 366 vfs now tries to do path walking in "rcu-walk mode", which avoids 367 367 atomic operations and scalability hazards on dentries and inodes (see 368 - Documentation/filesystems/path-walk.txt). d_hash and d_compare changes (above) 369 - are examples of the changes required to support this. For more complex 368 + Documentation/filesystems/path-lookup.txt). d_hash and d_compare changes 369 + (above) are examples of the changes required to support this. For more complex 370 370 filesystem callbacks, the vfs drops out of rcu-walk mode before the fs call, so 371 371 no changes are required to the filesystem. However, this is costly and loses 372 372 the benefits of rcu-walk mode. We will begin to add filesystem callbacks that ··· 383 383 384 384 permission and check_acl are inode permission checks that are called 385 385 on many or all directory inodes on the way down a path walk (to check for 386 - exec permission). These must now be rcu-walk aware (flags & IPERM_RCU). See 387 - Documentation/filesystems/vfs.txt for more details. 386 + exec permission). These must now be rcu-walk aware (flags & IPERM_FLAG_RCU). 387 + See Documentation/filesystems/vfs.txt for more details. 388 388 389 389 -- 390 390 [mandatory]
+2 -2
Documentation/filesystems/vfs.txt
··· 415 415 permission: called by the VFS to check for access rights on a POSIX-like 416 416 filesystem. 417 417 418 - May be called in rcu-walk mode (flags & IPERM_RCU). If in rcu-walk 419 - mode, the filesystem must check the permission without blocking or 418 + May be called in rcu-walk mode (flags & IPERM_FLAG_RCU). If in rcu-walk 419 + mode, the filesystem must check the permission without blocking or 420 420 storing to the inode. 421 421 422 422 If a situation is encountered that rcu-walk cannot handle, return
+24 -4
fs/namei.c
··· 479 479 struct fs_struct *fs = current->fs; 480 480 struct dentry *parent = nd->path.dentry; 481 481 482 + /* 483 + * It can be possible to revalidate the dentry that we started 484 + * the path walk with. force_reval_path may also revalidate the 485 + * dentry already committed to the nameidata. 486 + */ 487 + if (unlikely(parent == dentry)) 488 + return nameidata_drop_rcu(nd); 489 + 482 490 BUG_ON(!(nd->flags & LOOKUP_RCU)); 483 491 if (nd->root.mnt) { 484 492 spin_lock(&fs->lock); ··· 591 583 fput(nd->intent.open.file); 592 584 } 593 585 586 + /* 587 + * Call d_revalidate and handle filesystems that request rcu-walk 588 + * to be dropped. This may be called and return in rcu-walk mode, 589 + * regardless of success or error. If -ECHILD is returned, the caller 590 + * must return -ECHILD back up the path walk stack so path walk may 591 + * be restarted in ref-walk mode. 592 + */ 594 593 static int d_revalidate(struct dentry *dentry, struct nameidata *nd) 595 594 { 596 595 int status; ··· 688 673 return 0; 689 674 690 675 if (!status) { 676 + /* Don't d_invalidate in rcu-walk mode */ 677 + if (nameidata_drop_rcu(nd)) 678 + return -ECHILD; 691 679 d_invalidate(dentry); 692 680 status = -ESTALE; 693 681 } ··· 2123 2105 dir = nd->path.dentry; 2124 2106 case LAST_DOT: 2125 2107 if (need_reval_dot(dir)) { 2126 - error = d_revalidate(nd->path.dentry, nd); 2127 - if (!error) 2128 - error = -ESTALE; 2129 - if (error < 0) 2108 + int status = d_revalidate(nd->path.dentry, nd); 2109 + if (!status) 2110 + status = -ESTALE; 2111 + if (status < 0) { 2112 + error = status; 2130 2113 goto exit; 2114 + } 2131 2115 } 2132 2116 /* fallthrough */ 2133 2117 case LAST_ROOT:
+5 -1
fs/nfs/dir.c
··· 1406 1406 static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) 1407 1407 { 1408 1408 struct dentry *parent = NULL; 1409 - struct inode *inode = dentry->d_inode; 1409 + struct inode *inode; 1410 1410 struct inode *dir; 1411 1411 struct nfs_open_context *ctx; 1412 1412 int openflags, ret = 0; 1413 1413 1414 + if (nd->flags & LOOKUP_RCU) 1415 + return -ECHILD; 1416 + 1417 + inode = dentry->d_inode; 1414 1418 if (!is_atomic_open(nd) || d_mountpoint(dentry)) 1415 1419 goto no_open; 1416 1420
+3 -2
include/linux/list_bl.h
··· 16 16 * some fast and compact auxiliary data. 17 17 */ 18 18 19 - #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) 19 + #if defined(CONFIG_SMP) 20 20 #define LIST_BL_LOCKMASK 1UL 21 21 #else 22 22 #define LIST_BL_LOCKMASK 0UL ··· 62 62 struct hlist_bl_node *n) 63 63 { 64 64 LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK); 65 - LIST_BL_BUG_ON(!((unsigned long)h->first & LIST_BL_LOCKMASK)); 65 + LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) != 66 + LIST_BL_LOCKMASK); 66 67 h->first = (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK); 67 68 } 68 69
+2 -1
include/linux/rculist_bl.h
··· 11 11 struct hlist_bl_node *n) 12 12 { 13 13 LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK); 14 - LIST_BL_BUG_ON(!((unsigned long)h->first & LIST_BL_LOCKMASK)); 14 + LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) != 15 + LIST_BL_LOCKMASK); 15 16 rcu_assign_pointer(h->first, 16 17 (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK)); 17 18 }