aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2007-06-07 12:20:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2007-10-21 02:37:25 -0400
commit8aec08094570562bc305df33b088926d983c3540 (patch)
tree399f4590f81428d1f72d754d336da13c449120f9
parent5a190ae69766da9a34bf31200c5cea4c0667cf94 (diff)
[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 <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namespace.c22
-rw-r--r--fs/pnode.h1
-rw-r--r--include/linux/fs.h2
3 files changed, 24 insertions, 1 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 860752998fb3..06083885b21e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
246 list_add(&mnt->mnt_slave, &old->mnt_slave_list); 246 list_add(&mnt->mnt_slave, &old->mnt_slave_list);
247 mnt->mnt_master = old; 247 mnt->mnt_master = old;
248 CLEAR_MNT_SHARED(mnt); 248 CLEAR_MNT_SHARED(mnt);
249 } else { 249 } else if (!(flag & CL_PRIVATE)) {
250 if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) 250 if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
251 list_add(&mnt->mnt_share, &old->mnt_share); 251 list_add(&mnt->mnt_share, &old->mnt_share);
252 if (IS_MNT_SLAVE(old)) 252 if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@ Enomem:
746 return NULL; 746 return NULL;
747} 747}
748 748
749struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
750{
751 struct vfsmount *tree;
752 down_read(&namespace_sem);
753 tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
754 up_read(&namespace_sem);
755 return tree;
756}
757
758void drop_collected_mounts(struct vfsmount *mnt)
759{
760 LIST_HEAD(umount_list);
761 down_read(&namespace_sem);
762 spin_lock(&vfsmount_lock);
763 umount_tree(mnt, 0, &umount_list);
764 spin_unlock(&vfsmount_lock);
765 up_read(&namespace_sem);
766 release_mounts(&umount_list);
767}
768
749/* 769/*
750 * @source_mnt : mount tree to be attached 770 * @source_mnt : mount tree to be attached
751 * @nd : place the mount tree @source_mnt is attached 771 * @nd : place the mount tree @source_mnt is attached
diff --git a/fs/pnode.h b/fs/pnode.h
index d45bd8ec36bf..f249be2fee7a 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -22,6 +22,7 @@
22#define CL_COPY_ALL 0x04 22#define CL_COPY_ALL 0x04
23#define CL_MAKE_SHARED 0x08 23#define CL_MAKE_SHARED 0x08
24#define CL_PROPAGATION 0x10 24#define CL_PROPAGATION 0x10
25#define CL_PRIVATE 0x20
25 26
26static inline void set_mnt_shared(struct vfsmount *mnt) 27static inline void set_mnt_shared(struct vfsmount *mnt)
27{ 28{
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1bcce660cf03..50078bb30a1c 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 *);
1470extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); 1470extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
1471extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *, 1471extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
1472 struct vfsmount *); 1472 struct vfsmount *);
1473extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
1474extern void drop_collected_mounts(struct vfsmount *);
1473 1475
1474extern int vfs_statfs(struct dentry *, struct kstatfs *); 1476extern int vfs_statfs(struct dentry *, struct kstatfs *);
1475 1477