diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-18 12:43:19 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-22 16:00:55 -0400 |
commit | 32a7991b6a9c758e4e2b8166c5e1cc7563c3dcde (patch) | |
tree | 90fdffcdb0e236cd64a3d6b90006490ecf0cc5de /fs/namei.c | |
parent | 3c0a6163688b8ca3f44029c7bdb3d91a865c878a (diff) |
tidy up namei.c a bit
locking/unlocking for rcu walk taken to a couple of inline helpers
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/fs/namei.c b/fs/namei.c index d4d15bbc8af7..2ccc35c4dc24 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -427,6 +427,18 @@ EXPORT_SYMBOL(path_put); | |||
427 | * to restart the path walk from the beginning in ref-walk mode. | 427 | * to restart the path walk from the beginning in ref-walk mode. |
428 | */ | 428 | */ |
429 | 429 | ||
430 | static inline void lock_rcu_walk(void) | ||
431 | { | ||
432 | br_read_lock(&vfsmount_lock); | ||
433 | rcu_read_lock(); | ||
434 | } | ||
435 | |||
436 | static inline void unlock_rcu_walk(void) | ||
437 | { | ||
438 | rcu_read_unlock(); | ||
439 | br_read_unlock(&vfsmount_lock); | ||
440 | } | ||
441 | |||
430 | /** | 442 | /** |
431 | * unlazy_walk - try to switch to ref-walk mode. | 443 | * unlazy_walk - try to switch to ref-walk mode. |
432 | * @nd: nameidata pathwalk data | 444 | * @nd: nameidata pathwalk data |
@@ -480,8 +492,7 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry) | |||
480 | } | 492 | } |
481 | mntget(nd->path.mnt); | 493 | mntget(nd->path.mnt); |
482 | 494 | ||
483 | rcu_read_unlock(); | 495 | unlock_rcu_walk(); |
484 | br_read_unlock(&vfsmount_lock); | ||
485 | nd->flags &= ~LOOKUP_RCU; | 496 | nd->flags &= ~LOOKUP_RCU; |
486 | return 0; | 497 | return 0; |
487 | 498 | ||
@@ -522,15 +533,13 @@ static int complete_walk(struct nameidata *nd) | |||
522 | spin_lock(&dentry->d_lock); | 533 | spin_lock(&dentry->d_lock); |
523 | if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) { | 534 | if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) { |
524 | spin_unlock(&dentry->d_lock); | 535 | spin_unlock(&dentry->d_lock); |
525 | rcu_read_unlock(); | 536 | unlock_rcu_walk(); |
526 | br_read_unlock(&vfsmount_lock); | ||
527 | return -ECHILD; | 537 | return -ECHILD; |
528 | } | 538 | } |
529 | BUG_ON(nd->inode != dentry->d_inode); | 539 | BUG_ON(nd->inode != dentry->d_inode); |
530 | spin_unlock(&dentry->d_lock); | 540 | spin_unlock(&dentry->d_lock); |
531 | mntget(nd->path.mnt); | 541 | mntget(nd->path.mnt); |
532 | rcu_read_unlock(); | 542 | unlock_rcu_walk(); |
533 | br_read_unlock(&vfsmount_lock); | ||
534 | } | 543 | } |
535 | 544 | ||
536 | if (likely(!(nd->flags & LOOKUP_JUMPED))) | 545 | if (likely(!(nd->flags & LOOKUP_JUMPED))) |
@@ -985,8 +994,7 @@ failed: | |||
985 | nd->flags &= ~LOOKUP_RCU; | 994 | nd->flags &= ~LOOKUP_RCU; |
986 | if (!(nd->flags & LOOKUP_ROOT)) | 995 | if (!(nd->flags & LOOKUP_ROOT)) |
987 | nd->root.mnt = NULL; | 996 | nd->root.mnt = NULL; |
988 | rcu_read_unlock(); | 997 | unlock_rcu_walk(); |
989 | br_read_unlock(&vfsmount_lock); | ||
990 | return -ECHILD; | 998 | return -ECHILD; |
991 | } | 999 | } |
992 | 1000 | ||
@@ -1323,8 +1331,7 @@ static void terminate_walk(struct nameidata *nd) | |||
1323 | nd->flags &= ~LOOKUP_RCU; | 1331 | nd->flags &= ~LOOKUP_RCU; |
1324 | if (!(nd->flags & LOOKUP_ROOT)) | 1332 | if (!(nd->flags & LOOKUP_ROOT)) |
1325 | nd->root.mnt = NULL; | 1333 | nd->root.mnt = NULL; |
1326 | rcu_read_unlock(); | 1334 | unlock_rcu_walk(); |
1327 | br_read_unlock(&vfsmount_lock); | ||
1328 | } | 1335 | } |
1329 | } | 1336 | } |
1330 | 1337 | ||
@@ -1691,8 +1698,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1691 | nd->path = nd->root; | 1698 | nd->path = nd->root; |
1692 | nd->inode = inode; | 1699 | nd->inode = inode; |
1693 | if (flags & LOOKUP_RCU) { | 1700 | if (flags & LOOKUP_RCU) { |
1694 | br_read_lock(&vfsmount_lock); | 1701 | lock_rcu_walk(); |
1695 | rcu_read_lock(); | ||
1696 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); | 1702 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); |
1697 | } else { | 1703 | } else { |
1698 | path_get(&nd->path); | 1704 | path_get(&nd->path); |
@@ -1704,8 +1710,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1704 | 1710 | ||
1705 | if (*name=='/') { | 1711 | if (*name=='/') { |
1706 | if (flags & LOOKUP_RCU) { | 1712 | if (flags & LOOKUP_RCU) { |
1707 | br_read_lock(&vfsmount_lock); | 1713 | lock_rcu_walk(); |
1708 | rcu_read_lock(); | ||
1709 | set_root_rcu(nd); | 1714 | set_root_rcu(nd); |
1710 | } else { | 1715 | } else { |
1711 | set_root(nd); | 1716 | set_root(nd); |
@@ -1717,8 +1722,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1717 | struct fs_struct *fs = current->fs; | 1722 | struct fs_struct *fs = current->fs; |
1718 | unsigned seq; | 1723 | unsigned seq; |
1719 | 1724 | ||
1720 | br_read_lock(&vfsmount_lock); | 1725 | lock_rcu_walk(); |
1721 | rcu_read_lock(); | ||
1722 | 1726 | ||
1723 | do { | 1727 | do { |
1724 | seq = read_seqcount_begin(&fs->seq); | 1728 | seq = read_seqcount_begin(&fs->seq); |
@@ -1753,8 +1757,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1753 | if (fput_needed) | 1757 | if (fput_needed) |
1754 | *fp = file; | 1758 | *fp = file; |
1755 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); | 1759 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); |
1756 | br_read_lock(&vfsmount_lock); | 1760 | lock_rcu_walk(); |
1757 | rcu_read_lock(); | ||
1758 | } else { | 1761 | } else { |
1759 | path_get(&file->f_path); | 1762 | path_get(&file->f_path); |
1760 | fput_light(file, fput_needed); | 1763 | fput_light(file, fput_needed); |