aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-07-18 12:43:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-22 16:00:55 -0400
commit32a7991b6a9c758e4e2b8166c5e1cc7563c3dcde (patch)
tree90fdffcdb0e236cd64a3d6b90006490ecf0cc5de /fs/namei.c
parent3c0a6163688b8ca3f44029c7bdb3d91a865c878a (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.c39
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
430static inline void lock_rcu_walk(void)
431{
432 br_read_lock(&vfsmount_lock);
433 rcu_read_lock();
434}
435
436static 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);