]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
vfs: Add a function to lazily unmount all mounts from any dentry. v3
authorEric W. Biederman <ebiederman@twitter.com>
Thu, 3 Oct 2013 08:31:18 +0000 (01:31 -0700)
committerEric W. Biederman <ebiederm@xmission.com>
Fri, 11 Oct 2013 22:26:26 +0000 (15:26 -0700)
v2: Always drop the lock when exiting early.
v3: Make detach_mounts robust about freeing several
    mounts on the same mountpoint at one time, and remove
    the unneeded mnt_list list test.

Signed-off-by: Eric W. Biederman <ebiederman@twitter.com>
fs/mount.h
fs/namespace.c

index e4342b8dfab1c763db60fdfcb3974d9b5821ce5c..7a6a2bb3f290c036c0c30eefdbf0698d523a381e 100644 (file)
@@ -79,6 +79,7 @@ static inline int is_mounted(struct vfsmount *mnt)
 }
 
 extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
+extern void detach_mounts(struct dentry *dentry);
 
 static inline void get_mnt_ns(struct mnt_namespace *ns)
 {
index e4fe22c23e00d1e182246732530bce4b33174262..78f7c5c9e6733625a8b646e7cfd2ef853ad1fbf4 100644 (file)
@@ -1295,6 +1295,30 @@ static int do_umount(struct mount *mnt, int flags)
        return retval;
 }
 
+void detach_mounts(struct dentry *dentry)
+{
+       struct mountpoint *mp;
+       struct mount *mnt;
+
+       namespace_lock();
+       if (!d_mountpoint(dentry))
+               goto out_unlock;
+
+       mp = new_mountpoint(dentry);
+       if (IS_ERR(mp))
+               goto out_unlock;
+
+       br_write_lock(&vfsmount_lock);
+       while (!list_empty(&mp->m_list)) {
+               mnt = list_first_entry(&mp->m_list, struct mount, mnt_mp_list);
+               umount_tree(mnt, 1);
+       }
+       br_write_unlock(&vfsmount_lock);
+       put_mountpoint(mp);
+out_unlock:
+       namespace_unlock();
+}
+
 /* 
  * Is the caller allowed to modify his namespace?
  */