Chunk 2:
        Since all branches of do_mount() (mounting, binding, remounting)
do the same thing (lookup of directory) we can take that lookup in the
beginning of do_mount() and pass to do_loopback() and do_remount()
nameidata instead of name.

Please, apply
                                                        Al

diff -urN S6-pre1-do_remount/fs/super.c S6-pre1-do_mount/fs/super.c
--- S6-pre1-do_remount/fs/super.c       Tue Jun  5 08:14:29 2001
+++ S6-pre1-do_mount/fs/super.c Tue Jun  5 08:15:33 2001
@@ -1151,9 +1151,9 @@
 /*
  * do loopback mount.
  */
-static int do_loopback(char *old_name, char *new_name)
+static int do_loopback(struct nameidata *nd, char *old_name)
 {
-       struct nameidata old_nd, new_nd;
+       struct nameidata old_nd;
        int err = 0;
        if (!old_name || !*old_name)
                return -EINVAL;
@@ -1161,31 +1161,25 @@
                err = path_walk(old_name, &old_nd);
        if (err)
                goto out;
-       if (path_init(new_name, LOOKUP_POSITIVE, &new_nd))
-               err = path_walk(new_name, &new_nd);
+       err = mount_is_safe(nd);
        if (err)
                goto out1;
-       err = mount_is_safe(&new_nd);
-       if (err)
-               goto out2;
        err = -EINVAL;
-       if (S_ISDIR(new_nd.dentry->d_inode->i_mode) !=
+       if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
              S_ISDIR(old_nd.dentry->d_inode->i_mode))
-               goto out2;
+               goto out1;
 
        err = -ENOMEM;
                
        down(&mount_sem);
        /* there we go */
-       down(&new_nd.dentry->d_inode->i_zombie);
-       if (IS_DEADDIR(new_nd.dentry->d_inode))
+       down(&nd->dentry->d_inode->i_zombie);
+       if (IS_DEADDIR(nd->dentry->d_inode))
                err = -ENOENT;
-       else if (add_vfsmnt(&new_nd, old_nd.dentry, old_nd.mnt->mnt_devname))
+       else if (add_vfsmnt(nd, old_nd.dentry, old_nd.mnt->mnt_devname))
                err = 0;
-       up(&new_nd.dentry->d_inode->i_zombie);
+       up(&nd->dentry->d_inode->i_zombie);
        up(&mount_sem);
-out2:
-       path_release(&new_nd);
 out1:
        path_release(&old_nd);
 out:
@@ -1198,25 +1192,15 @@
  * on it - tough luck.
  */
 
-static int do_remount(const char *dir,int flags,char *data)
+static int do_remount(struct nameidata *nd, int flags, char *data)
 {
-       struct nameidata nd;
-       int retval = 0;
-
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       if (path_init(dir, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
-               retval = path_walk(dir, &nd);
-       if (retval)
-               return retval;
-
-       retval = -EINVAL;
-       if (nd.dentry == nd.mnt->mnt_root)
-               retval = do_remount_sb(nd.mnt->mnt_sb, flags, data);
+       if (nd->dentry != nd->mnt->mnt_root)
+               return -EINVAL;
 
-       path_release(&nd);
-       return retval;
+       return do_remount_sb(nd->mnt->mnt_sb, flags, data);
 }
 
 static int copy_mount_options (const void *data, unsigned long *where)
@@ -1286,38 +1270,41 @@
        if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))
                return -EINVAL;
 
-       /* OK, looks good, now let's see what do they want */
+       /* ... and get the mountpoint */
+       if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+               retval = path_walk(dir_name, &nd);
+       if (retval)
+               return retval;
 
        /* just change the flags? - capabilities are checked in do_remount() */
-       if (flags & MS_REMOUNT)
-               return do_remount(dir_name, flags & ~MS_REMOUNT,
-                                 (char *) data_page);
+       if (flags & MS_REMOUNT) {
+               retval = do_remount(&nd, flags&~MS_REMOUNT, (char *)data_page);
+               goto nd_out;
+       }
 
        /* "mount --bind"? Equivalent to older "mount -t bind" */
        /* No capabilities? What if users do thousands of these? */
-       if (flags & MS_BIND)
-               return do_loopback(dev_name, dir_name);
+       if (flags & MS_BIND) {
+               retval = do_loopback(&nd, dev_name);
+               goto nd_out;
+       }
 
        /* For the rest we need the type */
 
+       retval = -EINVAL;
        if (!type_page || !memchr(type_page, 0, PAGE_SIZE))
-               return -EINVAL;
+               goto nd_out;
 
+       retval = -EPERM;
        /* for the rest we _really_ need capabilities... */
        if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
+               goto nd_out;
 
+       retval = -ENODEV;
        /* ... filesystem driver... */
        fstype = get_fs_type(type_page);
        if (!fstype)            
-               return -ENODEV;
-
-       /* ... and mountpoint. Do the lookup first to force automounting. */
-       if (path_init(dir_name,
-                     LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
-               retval = path_walk(dir_name, &nd);
-       if (retval)
-               goto fs_out;
+               goto nd_out;
 
        /* get superblock, locks mount_sem on success */
        if (fstype->fs_flags & FS_NOMOUNT)
@@ -1331,7 +1318,7 @@
 
        retval = PTR_ERR(sb);
        if (IS_ERR(sb))
-               goto dput_out;
+               goto fs_out;
 
        /* Something was mounted here while we slept */
        while(d_mountpoint(nd.dentry) && follow_down(&nd.mnt, &nd.dentry))
@@ -1346,6 +1333,9 @@
        retval = -ENOENT;
        if (!nd.dentry->d_inode)
                goto fail;
+       retval = -ENOTDIR;
+       if (!S_ISDIR(nd.dentry->d_inode->i_mode))
+               goto fail;
        down(&nd.dentry->d_inode->i_zombie);
        if (!IS_DEADDIR(nd.dentry->d_inode)) {
                retval = -ENOMEM;
@@ -1357,10 +1347,10 @@
        retval = 0;
 unlock_out:
        up(&mount_sem);
-dput_out:
-       path_release(&nd);
 fs_out:
        put_filesystem(fstype);
+nd_out:
+       path_release(&nd);
        return retval;
 
 fail:

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to