ata-acpi: don't call _GTF for disabled drive
[safe/jmp/linux-2.6] / fs / namespace.c
index 1c78917..94f026e 100644 (file)
@@ -262,10 +262,8 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
                /* stick the duplicate mount on the same expiry list
                 * as the original if that was on one */
                if (flag & CL_EXPIRE) {
-                       spin_lock(&vfsmount_lock);
                        if (!list_empty(&old->mnt_expire))
                                list_add(&mnt->mnt_expire, &old->mnt_expire);
-                       spin_unlock(&vfsmount_lock);
                }
        }
        return mnt;
@@ -581,6 +579,8 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
        }
 }
 
+static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts);
+
 static int do_umount(struct vfsmount *mnt, int flags)
 {
        struct super_block *sb = mnt->mnt_sb;
@@ -653,6 +653,9 @@ static int do_umount(struct vfsmount *mnt, int flags)
        spin_lock(&vfsmount_lock);
        event++;
 
+       if (!(flags & MNT_DETACH))
+               shrink_submounts(mnt, &umount_list);
+
        retval = -EBUSY;
        if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {
                if (!list_empty(&mnt->mnt_list))
@@ -1122,11 +1125,9 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name)
        if (err)
                goto out1;
 
-       spin_lock(&vfsmount_lock);
        /* if the mount is moved, it should no longer be expire
         * automatically */
        list_del_init(&old_nd.path.mnt->mnt_expire);
-       spin_unlock(&vfsmount_lock);
 out1:
        mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
 out:
@@ -1193,12 +1194,9 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
        if ((err = graft_tree(newmnt, nd)))
                goto unlock;
 
-       if (fslist) {
-               /* add to the specified expiration list */
-               spin_lock(&vfsmount_lock);
+       if (fslist) /* add to the specified expiration list */
                list_add_tail(&newmnt->mnt_expire, fslist);
-               spin_unlock(&vfsmount_lock);
-       }
+
        up_write(&namespace_sem);
        return 0;
 
@@ -1302,30 +1300,22 @@ resume:
  * process a list of expirable mountpoints with the intent of discarding any
  * submounts of a specific parent mountpoint
  */
-void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts)
+static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts)
 {
        LIST_HEAD(graveyard);
-       LIST_HEAD(umounts);
-       struct vfsmount *mnt;
+       struct vfsmount *m;
 
-       down_write(&namespace_sem);
-       spin_lock(&vfsmount_lock);
        /* extract submounts of 'mountpoint' from the expiration list */
-       while (select_submounts(mountpoint, &graveyard)) {
+       while (select_submounts(mnt, &graveyard)) {
                while (!list_empty(&graveyard)) {
-                       mnt = list_first_entry(&graveyard, struct vfsmount,
+                       m = list_first_entry(&graveyard, struct vfsmount,
                                                mnt_expire);
                        touch_mnt_namespace(mnt->mnt_ns);
-                       umount_tree(mnt, 1, &umounts);
+                       umount_tree(mnt, 1, umounts);
                }
        }
-       spin_unlock(&vfsmount_lock);
-       up_write(&namespace_sem);
-       release_mounts(&umounts);
 }
 
-EXPORT_SYMBOL_GPL(shrink_submounts);
-
 /*
  * Some copy_from_user() implementations do not return the exact number of
  * bytes remaining to copy on a fault.  But copy_mount_options() requires that.