]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/namespace.c
x86: fix long standing bug with usb after hibernation with 4GB ram
[linux-2.6-omap-h63xx.git] / fs / namespace.c
index c77eedd2ac6696ffc15f582df5d3ab010845f44a..7953c96a20715a981032b4d7af18e428f39b3ca6 100644 (file)
@@ -408,10 +408,11 @@ static int show_vfsmnt(struct seq_file *m, void *v)
                { 0, NULL }
        };
        struct proc_fs_info *fs_infop;
+       struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
 
        mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
        seq_putc(m, ' ');
-       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+       seq_path(m, &mnt_path, " \t\n\\");
        seq_putc(m, ' ');
        mangle(m, mnt->mnt_sb->s_type->name);
        if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
@@ -443,6 +444,7 @@ struct seq_operations mounts_op = {
 static int show_vfsstat(struct seq_file *m, void *v)
 {
        struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list);
+       struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
        int err = 0;
 
        /* device */
@@ -454,7 +456,7 @@ static int show_vfsstat(struct seq_file *m, void *v)
 
        /* mount point */
        seq_puts(m, " mounted on ");
-       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+       seq_path(m, &mnt_path, " \t\n\\");
        seq_putc(m, ' ');
 
        /* file system type */
@@ -593,7 +595,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
         *  (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
         */
        if (flags & MNT_EXPIRE) {
-               if (mnt == current->fs->rootmnt ||
+               if (mnt == current->fs->root.mnt ||
                    flags & (MNT_FORCE | MNT_DETACH))
                        return -EINVAL;
 
@@ -628,7 +630,7 @@ static int do_umount(struct vfsmount *mnt, int flags)
         * /reboot - static binary that would close all descriptors and
         * call reboot(9). Then init(8) could umount root and exec /reboot.
         */
-       if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
+       if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
                /*
                 * Special case for "unmounting" root ...
                 * we just try to remount it readonly.
@@ -1559,17 +1561,17 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
        while (p) {
                q->mnt_ns = new_ns;
                if (fs) {
-                       if (p == fs->rootmnt) {
+                       if (p == fs->root.mnt) {
                                rootmnt = p;
-                               fs->rootmnt = mntget(q);
+                               fs->root.mnt = mntget(q);
                        }
-                       if (p == fs->pwdmnt) {
+                       if (p == fs->pwd.mnt) {
                                pwdmnt = p;
-                               fs->pwdmnt = mntget(q);
+                               fs->pwd.mnt = mntget(q);
                        }
-                       if (p == fs->altrootmnt) {
+                       if (p == fs->altroot.mnt) {
                                altrootmnt = p;
-                               fs->altrootmnt = mntget(q);
+                               fs->altroot.mnt = mntget(q);
                        }
                }
                p = next_mnt(p, mnt_ns->root);
@@ -1650,44 +1652,35 @@ out1:
  * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
  * It can block. Requires the big lock held.
  */
-void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
-                struct dentry *dentry)
+void set_fs_root(struct fs_struct *fs, struct path *path)
 {
-       struct dentry *old_root;
-       struct vfsmount *old_rootmnt;
+       struct path old_root;
+
        write_lock(&fs->lock);
        old_root = fs->root;
-       old_rootmnt = fs->rootmnt;
-       fs->rootmnt = mntget(mnt);
-       fs->root = dget(dentry);
+       fs->root = *path;
+       path_get(path);
        write_unlock(&fs->lock);
-       if (old_root) {
-               dput(old_root);
-               mntput(old_rootmnt);
-       }
+       if (old_root.dentry)
+               path_put(&old_root);
 }
 
 /*
  * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
  * It can block. Requires the big lock held.
  */
-void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
-               struct dentry *dentry)
+void set_fs_pwd(struct fs_struct *fs, struct path *path)
 {
-       struct dentry *old_pwd;
-       struct vfsmount *old_pwdmnt;
+       struct path old_pwd;
 
        write_lock(&fs->lock);
        old_pwd = fs->pwd;
-       old_pwdmnt = fs->pwdmnt;
-       fs->pwdmnt = mntget(mnt);
-       fs->pwd = dget(dentry);
+       fs->pwd = *path;
+       path_get(path);
        write_unlock(&fs->lock);
 
-       if (old_pwd) {
-               dput(old_pwd);
-               mntput(old_pwdmnt);
-       }
+       if (old_pwd.dentry)
+               path_put(&old_pwd);
 }
 
 static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
@@ -1702,14 +1695,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
                if (fs) {
                        atomic_inc(&fs->count);
                        task_unlock(p);
-                       if (fs->root == old_nd->path.dentry
-                           && fs->rootmnt == old_nd->path.mnt)
-                               set_fs_root(fs, new_nd->path.mnt,
-                                           new_nd->path.dentry);
-                       if (fs->pwd == old_nd->path.dentry
-                           && fs->pwdmnt == old_nd->path.mnt)
-                               set_fs_pwd(fs, new_nd->path.mnt,
-                                          new_nd->path.dentry);
+                       if (fs->root.dentry == old_nd->path.dentry
+                           && fs->root.mnt == old_nd->path.mnt)
+                               set_fs_root(fs, &new_nd->path);
+                       if (fs->pwd.dentry == old_nd->path.dentry
+                           && fs->pwd.mnt == old_nd->path.mnt)
+                               set_fs_pwd(fs, &new_nd->path);
                        put_fs_struct(fs);
                } else
                        task_unlock(p);
@@ -1773,8 +1764,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
        }
 
        read_lock(&current->fs->lock);
-       user_nd.path.mnt = mntget(current->fs->rootmnt);
-       user_nd.path.dentry = dget(current->fs->root);
+       user_nd.path = current->fs->root;
+       path_get(&current->fs->root);
        read_unlock(&current->fs->lock);
        down_write(&namespace_sem);
        mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);
@@ -1852,6 +1843,7 @@ static void __init init_mount_tree(void)
 {
        struct vfsmount *mnt;
        struct mnt_namespace *ns;
+       struct path root;
 
        mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
        if (IS_ERR(mnt))
@@ -1870,8 +1862,11 @@ static void __init init_mount_tree(void)
        init_task.nsproxy->mnt_ns = ns;
        get_mnt_ns(ns);
 
-       set_fs_pwd(current->fs, ns->root, ns->root->mnt_root);
-       set_fs_root(current->fs, ns->root, ns->root->mnt_root);
+       root.mnt = ns->root;
+       root.dentry = ns->root->mnt_root;
+
+       set_fs_pwd(current->fs, &root);
+       set_fs_root(current->fs, &root);
 }
 
 void __init mnt_init(void)