Loading fs/namei.c +21 −18 Original line number Diff line number Diff line Loading @@ -427,6 +427,18 @@ EXPORT_SYMBOL(path_put); * to restart the path walk from the beginning in ref-walk mode. */ static inline void lock_rcu_walk(void) { br_read_lock(&vfsmount_lock); rcu_read_lock(); } static inline void unlock_rcu_walk(void) { rcu_read_unlock(); br_read_unlock(&vfsmount_lock); } /** * unlazy_walk - try to switch to ref-walk mode. * @nd: nameidata pathwalk data Loading Loading @@ -480,8 +492,7 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry) } mntget(nd->path.mnt); rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); nd->flags &= ~LOOKUP_RCU; return 0; Loading Loading @@ -522,15 +533,13 @@ static int complete_walk(struct nameidata *nd) spin_lock(&dentry->d_lock); if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) { spin_unlock(&dentry->d_lock); rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); return -ECHILD; } BUG_ON(nd->inode != dentry->d_inode); spin_unlock(&dentry->d_lock); mntget(nd->path.mnt); rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); } if (likely(!(nd->flags & LOOKUP_JUMPED))) Loading Loading @@ -985,8 +994,7 @@ static int follow_dotdot_rcu(struct nameidata *nd) nd->flags &= ~LOOKUP_RCU; if (!(nd->flags & LOOKUP_ROOT)) nd->root.mnt = NULL; rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); return -ECHILD; } Loading Loading @@ -1323,8 +1331,7 @@ static void terminate_walk(struct nameidata *nd) nd->flags &= ~LOOKUP_RCU; if (!(nd->flags & LOOKUP_ROOT)) nd->root.mnt = NULL; rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); } } Loading Loading @@ -1691,8 +1698,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, nd->path = nd->root; nd->inode = inode; if (flags & LOOKUP_RCU) { br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); } else { path_get(&nd->path); Loading @@ -1704,8 +1710,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, if (*name=='/') { if (flags & LOOKUP_RCU) { br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); set_root_rcu(nd); } else { set_root(nd); Loading @@ -1717,8 +1722,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, struct fs_struct *fs = current->fs; unsigned seq; br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); do { seq = read_seqcount_begin(&fs->seq); Loading Loading @@ -1753,8 +1757,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, if (fput_needed) *fp = file; nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); } else { path_get(&file->f_path); fput_light(file, fput_needed); Loading Loading
fs/namei.c +21 −18 Original line number Diff line number Diff line Loading @@ -427,6 +427,18 @@ EXPORT_SYMBOL(path_put); * to restart the path walk from the beginning in ref-walk mode. */ static inline void lock_rcu_walk(void) { br_read_lock(&vfsmount_lock); rcu_read_lock(); } static inline void unlock_rcu_walk(void) { rcu_read_unlock(); br_read_unlock(&vfsmount_lock); } /** * unlazy_walk - try to switch to ref-walk mode. * @nd: nameidata pathwalk data Loading Loading @@ -480,8 +492,7 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry) } mntget(nd->path.mnt); rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); nd->flags &= ~LOOKUP_RCU; return 0; Loading Loading @@ -522,15 +533,13 @@ static int complete_walk(struct nameidata *nd) spin_lock(&dentry->d_lock); if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) { spin_unlock(&dentry->d_lock); rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); return -ECHILD; } BUG_ON(nd->inode != dentry->d_inode); spin_unlock(&dentry->d_lock); mntget(nd->path.mnt); rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); } if (likely(!(nd->flags & LOOKUP_JUMPED))) Loading Loading @@ -985,8 +994,7 @@ static int follow_dotdot_rcu(struct nameidata *nd) nd->flags &= ~LOOKUP_RCU; if (!(nd->flags & LOOKUP_ROOT)) nd->root.mnt = NULL; rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); return -ECHILD; } Loading Loading @@ -1323,8 +1331,7 @@ static void terminate_walk(struct nameidata *nd) nd->flags &= ~LOOKUP_RCU; if (!(nd->flags & LOOKUP_ROOT)) nd->root.mnt = NULL; rcu_read_unlock(); br_read_unlock(&vfsmount_lock); unlock_rcu_walk(); } } Loading Loading @@ -1691,8 +1698,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, nd->path = nd->root; nd->inode = inode; if (flags & LOOKUP_RCU) { br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); } else { path_get(&nd->path); Loading @@ -1704,8 +1710,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, if (*name=='/') { if (flags & LOOKUP_RCU) { br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); set_root_rcu(nd); } else { set_root(nd); Loading @@ -1717,8 +1722,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, struct fs_struct *fs = current->fs; unsigned seq; br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); do { seq = read_seqcount_begin(&fs->seq); Loading Loading @@ -1753,8 +1757,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, if (fput_needed) *fp = file; nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); br_read_lock(&vfsmount_lock); rcu_read_lock(); lock_rcu_walk(); } else { path_get(&file->f_path); fput_light(file, fput_needed); Loading