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 [recommended] 366 vfs now tries to do path walking in "rcu-walk mode", which avoids 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 370 filesystem callbacks, the vfs drops out of rcu-walk mode before the fs call, so 371 no changes are required to the filesystem. However, this is costly and loses 372 the benefits of rcu-walk mode. We will begin to add filesystem callbacks that ··· 383 384 permission and check_acl are inode permission checks that are called 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. 388 389 -- 390 [mandatory]
··· 365 [recommended] 366 vfs now tries to do path walking in "rcu-walk mode", which avoids 367 atomic operations and scalability hazards on dentries and inodes (see 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 filesystem callbacks, the vfs drops out of rcu-walk mode before the fs call, so 371 no changes are required to the filesystem. However, this is costly and loses 372 the benefits of rcu-walk mode. We will begin to add filesystem callbacks that ··· 383 384 permission and check_acl are inode permission checks that are called 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_FLAG_RCU). 387 + See Documentation/filesystems/vfs.txt for more details. 388 389 -- 390 [mandatory]
+2 -2
Documentation/filesystems/vfs.txt
··· 415 permission: called by the VFS to check for access rights on a POSIX-like 416 filesystem. 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 420 storing to the inode. 421 422 If a situation is encountered that rcu-walk cannot handle, return
··· 415 permission: called by the VFS to check for access rights on a POSIX-like 416 filesystem. 417 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 storing to the inode. 421 422 If a situation is encountered that rcu-walk cannot handle, return
+24 -4
fs/namei.c
··· 479 struct fs_struct *fs = current->fs; 480 struct dentry *parent = nd->path.dentry; 481 482 BUG_ON(!(nd->flags & LOOKUP_RCU)); 483 if (nd->root.mnt) { 484 spin_lock(&fs->lock); ··· 591 fput(nd->intent.open.file); 592 } 593 594 static int d_revalidate(struct dentry *dentry, struct nameidata *nd) 595 { 596 int status; ··· 688 return 0; 689 690 if (!status) { 691 d_invalidate(dentry); 692 status = -ESTALE; 693 } ··· 2123 dir = nd->path.dentry; 2124 case LAST_DOT: 2125 if (need_reval_dot(dir)) { 2126 - error = d_revalidate(nd->path.dentry, nd); 2127 - if (!error) 2128 - error = -ESTALE; 2129 - if (error < 0) 2130 goto exit; 2131 } 2132 /* fallthrough */ 2133 case LAST_ROOT:
··· 479 struct fs_struct *fs = current->fs; 480 struct dentry *parent = nd->path.dentry; 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 + 490 BUG_ON(!(nd->flags & LOOKUP_RCU)); 491 if (nd->root.mnt) { 492 spin_lock(&fs->lock); ··· 583 fput(nd->intent.open.file); 584 } 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 + */ 593 static int d_revalidate(struct dentry *dentry, struct nameidata *nd) 594 { 595 int status; ··· 673 return 0; 674 675 if (!status) { 676 + /* Don't d_invalidate in rcu-walk mode */ 677 + if (nameidata_drop_rcu(nd)) 678 + return -ECHILD; 679 d_invalidate(dentry); 680 status = -ESTALE; 681 } ··· 2105 dir = nd->path.dentry; 2106 case LAST_DOT: 2107 if (need_reval_dot(dir)) { 2108 + int status = d_revalidate(nd->path.dentry, nd); 2109 + if (!status) 2110 + status = -ESTALE; 2111 + if (status < 0) { 2112 + error = status; 2113 goto exit; 2114 + } 2115 } 2116 /* fallthrough */ 2117 case LAST_ROOT:
+5 -1
fs/nfs/dir.c
··· 1406 static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) 1407 { 1408 struct dentry *parent = NULL; 1409 - struct inode *inode = dentry->d_inode; 1410 struct inode *dir; 1411 struct nfs_open_context *ctx; 1412 int openflags, ret = 0; 1413 1414 if (!is_atomic_open(nd) || d_mountpoint(dentry)) 1415 goto no_open; 1416
··· 1406 static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) 1407 { 1408 struct dentry *parent = NULL; 1409 + struct inode *inode; 1410 struct inode *dir; 1411 struct nfs_open_context *ctx; 1412 int openflags, ret = 0; 1413 1414 + if (nd->flags & LOOKUP_RCU) 1415 + return -ECHILD; 1416 + 1417 + inode = dentry->d_inode; 1418 if (!is_atomic_open(nd) || d_mountpoint(dentry)) 1419 goto no_open; 1420
+3 -2
include/linux/list_bl.h
··· 16 * some fast and compact auxiliary data. 17 */ 18 19 - #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) 20 #define LIST_BL_LOCKMASK 1UL 21 #else 22 #define LIST_BL_LOCKMASK 0UL ··· 62 struct hlist_bl_node *n) 63 { 64 LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK); 65 - LIST_BL_BUG_ON(!((unsigned long)h->first & LIST_BL_LOCKMASK)); 66 h->first = (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK); 67 } 68
··· 16 * some fast and compact auxiliary data. 17 */ 18 19 + #if defined(CONFIG_SMP) 20 #define LIST_BL_LOCKMASK 1UL 21 #else 22 #define LIST_BL_LOCKMASK 0UL ··· 62 struct hlist_bl_node *n) 63 { 64 LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK); 65 + LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) != 66 + LIST_BL_LOCKMASK); 67 h->first = (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK); 68 } 69
+2 -1
include/linux/rculist_bl.h
··· 11 struct hlist_bl_node *n) 12 { 13 LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK); 14 - LIST_BL_BUG_ON(!((unsigned long)h->first & LIST_BL_LOCKMASK)); 15 rcu_assign_pointer(h->first, 16 (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK)); 17 }
··· 11 struct hlist_bl_node *n) 12 { 13 LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK); 14 + LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) != 15 + LIST_BL_LOCKMASK); 16 rcu_assign_pointer(h->first, 17 (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK)); 18 }