Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8aec08094570562bc305df33b088926d983c3540
Commit:     8aec08094570562bc305df33b088926d983c3540
Parent:     5a190ae69766da9a34bf31200c5cea4c0667cf94
Author:     Al Viro <[EMAIL PROTECTED]>
AuthorDate: Thu Jun 7 12:20:32 2007 -0400
Committer:  Al Viro <[EMAIL PROTECTED]>
CommitDate: Sun Oct 21 02:37:25 2007 -0400

    [PATCH] new helpers - collect_mounts() and release_collected_mounts()
    
    Get a snapshot of a subtree, creating private clones of vfsmounts
    for all its components and release such snapshot resp.
    
    Signed-off-by: Al Viro <[EMAIL PROTECTED]>
---
 fs/namespace.c     |   22 +++++++++++++++++++++-
 fs/pnode.h         |    1 +
 include/linux/fs.h |    2 ++
 3 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index 8607529..0608388 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, 
struct dentry *root,
                        list_add(&mnt->mnt_slave, &old->mnt_slave_list);
                        mnt->mnt_master = old;
                        CLEAR_MNT_SHARED(mnt);
-               } else {
+               } else if (!(flag & CL_PRIVATE)) {
                        if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
                                list_add(&mnt->mnt_share, &old->mnt_share);
                        if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@ Enomem:
        return NULL;
 }
 
+struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
+{
+       struct vfsmount *tree;
+       down_read(&namespace_sem);
+       tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
+       up_read(&namespace_sem);
+       return tree;
+}
+
+void drop_collected_mounts(struct vfsmount *mnt)
+{
+       LIST_HEAD(umount_list);
+       down_read(&namespace_sem);
+       spin_lock(&vfsmount_lock);
+       umount_tree(mnt, 0, &umount_list);
+       spin_unlock(&vfsmount_lock);
+       up_read(&namespace_sem);
+       release_mounts(&umount_list);
+}
+
 /*
  *  @source_mnt : mount tree to be attached
  *  @nd         : place the mount tree @source_mnt is attached
diff --git a/fs/pnode.h b/fs/pnode.h
index d45bd8e..f249be2 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -22,6 +22,7 @@
 #define CL_COPY_ALL            0x04
 #define CL_MAKE_SHARED                 0x08
 #define CL_PROPAGATION                 0x10
+#define CL_PRIVATE             0x20
 
 static inline void set_mnt_shared(struct vfsmount *mnt)
 {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1bcce66..50078bb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1470,6 +1470,8 @@ extern long do_mount(char *, char *, char *, unsigned 
long, void *);
 extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
 extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
                                  struct vfsmount *);
+extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
+extern void drop_collected_mounts(struct vfsmount *);
 
 extern int vfs_statfs(struct dentry *, struct kstatfs *);
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to