From: Al Viro Date: Thu, 7 Jun 2007 16:20:32 +0000 (-0400) Subject: [PATCH] new helpers - collect_mounts() and release_collected_mounts() X-Git-Tag: v2.6.24-rc1~116^2~3 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=8aec08094570562bc305df33b088926d983c3540;p=linux-2.6-omap-h63xx.git [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 --- diff --git a/fs/namespace.c b/fs/namespace.c index 860752998fb..06083885b21 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 d45bd8ec36b..f249be2fee7 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 1bcce660cf0..50078bb30a1 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 *);