Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8aec0809 authored by Al Viro's avatar Al Viro
Browse files

[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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 5a190ae6
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -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 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
	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
+1 −0
Original line number Diff line number Diff line
@@ -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)
{
+2 −0
Original line number Diff line number Diff line
@@ -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 *);