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 | |
| 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')
| -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); |
