path_lookup - precursor to fast_walk
Subsystems (2)
PATCH 1/1 path_lookup - precursor to fast_walk
Alan,
I have run 2.4.19-pre4-ac1 with path_lookup on an 8-way SMP and it looks good. Here is the latest version of path_lookup for your recently announced pre4-ac1 kernel.
This is a cleanup precursor to a fast_walk patch I wrote based on suggestions from Al Viro to decrease cacheline bouncing of a global reference counter during path lookup of dentries in the cache. That patch has shown 50% reduction in BKL contention on an 8-way SMP running dbench. Incidentally, it has also shown a 90% reduction in dcache_lock contention on a 16-way NUMA-Q building the kernel. Results and patch coming soon.
This patch included simply cleans up source code by changing the many calls of the form: if(path_init) error = path_walk to one function path_lookup. By wrapping path_init with path_lookup I will be able to control which filesystems use the fast_walk mechanism.
Linus has already accepted this patch from Al Viro in 2.5.6, his comments:
<[email protected]> (02/03/02 1.375.1.84)
[PATCH] path_lookup()
New helper:
path_lookup(name, flags, nd)
{
int err = 0;
if (path_init(name, flags, nd))
err = path_walk(name, nd);
return err;
}
Places doing that by hand converted to calling it.
Actually, quite a few of them were doing equivalent of __user_walk() (getname() and if it was successful - call path_lookup() and putname()). Converted to calling __user_walk().
Please consider this patch for inclusion in your 2.4.19 tree.
Following is the linux-2.4.19-pre4-ac1 version. Also available at:
http://prdownloads.sf.net/lse/path_lookupA5-2.4.19-pre4-ac1.patch
Hanna Linder
[email protected]
IBM Linux Technology Center
------
fs/exec.c +1 -2
@@ -351,8 +351,7 @@struct file *file;int err =0 ; -if (path_init (name,LOOKUP_FOLLOW |LOOKUP_POSITIVE , &nd)) - err =path_walk (name, &nd); + err =path_lookup (name,LOOKUP_FOLLOW |LOOKUP_POSITIVE , &nd); file =ERR_PTR (err);if (!err) { inode = nd.dentry->d_inode;
fs/namei.c +22 -32
139 lines not on this page · raw message
fs/namespace.c +6 -32
@@ -364,17 +364,9 @@asmlinkage long sys_umount (char * name,int flags) {struct nameidata nd; -char *kname;int retval; - kname =getname (name); - retval =PTR_ERR (kname); -if (IS_ERR (kname)) - goto out; - retval =0 ; -if (path_init (kname,LOOKUP_POSITIVE |LOOKUP_FOLLOW , &nd)) - retval =path_walk (kname, &nd); -putname (kname); + retval =__user_walk (name,LOOKUP_POSITIVE |LOOKUP_FOLLOW , &nd);if (retval) goto out; retval = -EINVAL ;
@@ -501,8 +493,7 @@return err;if (!old_name || !*old_name)return -EINVAL ; -if (path_init (old_name,LOOKUP_POSITIVE |LOOKUP_FOLLOW , &old_nd)) - err =path_walk (old_name, &old_nd); + err =path_lookup (old_name,LOOKUP_POSITIVE |LOOKUP_FOLLOW , &old_nd);if (err)return err;
@@ -568,8 +559,7 @@return -EPERM ;if (!old_name || !*old_name)return -EINVAL ; -if (path_init (old_name,LOOKUP_POSITIVE |LOOKUP_FOLLOW , &old_nd)) - err =path_walk (old_name, &old_nd); + err =path_lookup (old_name,LOOKUP_POSITIVE |LOOKUP_FOLLOW , &old_nd);if (err)return err;
@@ -726,8 +716,7 @@ flags &= ~(MS_NOSUID |MS_NOEXEC |MS_NODEV );/* ... and get the mountpoint */ -if (path_init (dir_name,LOOKUP_FOLLOW |LOOKUP_POSITIVE , &nd)) - retval =path_walk (dir_name, &nd); + retval =path_lookup (dir_name,LOOKUP_FOLLOW |LOOKUP_POSITIVE , &nd);if (retval)return retval;
@@ -826,7 +815,6 @@ {struct vfsmount *tmp;struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; -char *name;int error;if (!capable (CAP_SYS_ADMIN ))
@@ -834,28 +822,14 @@lock_kernel (); - name =getname (new_root); - error =PTR_ERR (name); -if (IS_ERR (name)) - goto out0; - error =0 ; -if (path_init (name,LOOKUP_POSITIVE |LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &new_nd)) - error =path_walk (name, &new_nd); -putname (name); + error =__user_walk (new_root,LOOKUP_POSITIVE |LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &new_nd);if (error) goto out0; error = -EINVAL ;if (!check_mnt (new_nd.mnt)) goto out1; - name =getname (put_old); - error =PTR_ERR (name); -if (IS_ERR (name)) - goto out1; - error =0 ; -if (path_init (name,LOOKUP_POSITIVE |LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &old_nd)) - error =path_walk (name, &old_nd); -putname (name); + error =__user_walk (put_old,LOOKUP_POSITIVE |LOOKUP_FOLLOW |LOOKUP_DIRECTORY , &old_nd);if (error) goto out1;
fs/open.c +2 -19
@@ -384,17 +384,8 @@ {int error;struct nameidata nd; -char *name; - name =getname (filename); - error =PTR_ERR (name); -if (IS_ERR (name)) - goto out; - - error =0 ; -if (path_init (name,LOOKUP_POSITIVE |LOOKUP_FOLLOW |LOOKUP_DIRECTORY ,&nd)) - error =path_walk (name, &nd); -putname (name); + error =__user_walk (filename,LOOKUP_POSITIVE |LOOKUP_FOLLOW |LOOKUP_DIRECTORY ,&nd);if (error) goto out;
@@ -444,17 +435,9 @@ {int error;struct nameidata nd; -char *name; - - name =getname (filename); - error =PTR_ERR (name); -if (IS_ERR (name)) - goto out; -path_init (name,LOOKUP_POSITIVE |LOOKUP_FOLLOW | + error =__user_walk (filename,LOOKUP_POSITIVE |LOOKUP_FOLLOW |LOOKUP_DIRECTORY |LOOKUP_NOALT , &nd); - error =path_walk (name, &nd); -putname (name);if (error) goto out;
fs/super.c +1 -2
@@ -575,8 +575,7 @@/* What device it is? */ if (!dev_name || !*dev_name)return ERR_PTR (-EINVAL ); -if (path_init (dev_name,LOOKUP_FOLLOW |LOOKUP_POSITIVE , &nd)) - error =path_walk (dev_name, &nd); + error =path_lookup (dev_name,LOOKUP_FOLLOW |LOOKUP_POSITIVE , &nd);if (error)return ERR_PTR (error); inode = nd.dentry->d_inode;
include/linux/fs.h +1 -0
@@ -1348,6 +1348,7 @@extern int FASTCALL (__user_walk (const char *,unsigned ,struct nameidata *));extern int FASTCALL (path_init (const char *,unsigned ,struct nameidata *));extern int FASTCALL (path_walk (const char *,struct nameidata *)); +extern int FASTCALL (path_lookup (const char *,unsigned ,struct nameidata *));extern int FASTCALL (link_path_walk (const char *,struct nameidata *));extern void path_release (struct nameidata *);extern int follow_down (struct vfsmount **,struct dentry **);