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

Commit 1f707137 authored by Al Viro's avatar Al Viro
Browse files

new helper: iterate_mounts()



apply function to vfsmounts in set returned by collect_mounts(),
stop if it returns non-zero.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 462d6057
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -1246,6 +1246,21 @@ void drop_collected_mounts(struct vfsmount *mnt)
	release_mounts(&umount_list);
	release_mounts(&umount_list);
}
}


int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
		   struct vfsmount *root)
{
	struct vfsmount *mnt;
	int res = f(root, arg);
	if (res)
		return res;
	list_for_each_entry(mnt, &root->mnt_list, mnt_list) {
		res = f(mnt, arg);
		if (res)
			return res;
	}
	return 0;
}

static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
{
{
	struct vfsmount *p;
	struct vfsmount *p;
+2 −1
Original line number Original line Diff line number Diff line
@@ -1794,7 +1794,8 @@ extern int may_umount(struct vfsmount *);
extern long do_mount(char *, char *, char *, unsigned long, void *);
extern long do_mount(char *, char *, char *, unsigned long, void *);
extern struct vfsmount *collect_mounts(struct path *);
extern struct vfsmount *collect_mounts(struct path *);
extern void drop_collected_mounts(struct vfsmount *);
extern void drop_collected_mounts(struct vfsmount *);

extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
			  struct vfsmount *);
extern int vfs_statfs(struct dentry *, struct kstatfs *);
extern int vfs_statfs(struct dentry *, struct kstatfs *);


extern int current_umask(void);
extern int current_umask(void);
+16 −33
Original line number Original line Diff line number Diff line
@@ -548,6 +548,11 @@ int audit_remove_tree_rule(struct audit_krule *rule)
	return 0;
	return 0;
}
}


static int compare_root(struct vfsmount *mnt, void *arg)
{
	return mnt->mnt_root->d_inode == arg;
}

void audit_trim_trees(void)
void audit_trim_trees(void)
{
{
	struct list_head cursor;
	struct list_head cursor;
@@ -559,7 +564,6 @@ void audit_trim_trees(void)
		struct path path;
		struct path path;
		struct vfsmount *root_mnt;
		struct vfsmount *root_mnt;
		struct node *node;
		struct node *node;
		struct list_head list;
		int err;
		int err;


		tree = container_of(cursor.next, struct audit_tree, list);
		tree = container_of(cursor.next, struct audit_tree, list);
@@ -577,24 +581,16 @@ void audit_trim_trees(void)
		if (!root_mnt)
		if (!root_mnt)
			goto skip_it;
			goto skip_it;


		list_add_tail(&list, &root_mnt->mnt_list);
		spin_lock(&hash_lock);
		spin_lock(&hash_lock);
		list_for_each_entry(node, &tree->chunks, list) {
		list_for_each_entry(node, &tree->chunks, list) {
			struct audit_chunk *chunk = find_chunk(node);
			struct inode *inode = find_chunk(node)->watch.inode;
			struct inode *inode = chunk->watch.inode;
			struct vfsmount *mnt;
			node->index |= 1U<<31;
			node->index |= 1U<<31;
			list_for_each_entry(mnt, &list, mnt_list) {
			if (iterate_mounts(compare_root, inode, root_mnt))
				if (mnt->mnt_root->d_inode == inode) {
				node->index &= ~(1U<<31);
				node->index &= ~(1U<<31);
					break;
				}
			}
		}
		}
		spin_unlock(&hash_lock);
		spin_unlock(&hash_lock);
		trim_marked(tree);
		trim_marked(tree);
		put_tree(tree);
		put_tree(tree);
		list_del_init(&list);
		drop_collected_mounts(root_mnt);
		drop_collected_mounts(root_mnt);
skip_it:
skip_it:
		mutex_lock(&audit_filter_mutex);
		mutex_lock(&audit_filter_mutex);
@@ -622,13 +618,17 @@ void audit_put_tree(struct audit_tree *tree)
	put_tree(tree);
	put_tree(tree);
}
}


static int tag_mount(struct vfsmount *mnt, void *arg)
{
	return tag_chunk(mnt->mnt_root->d_inode, arg);
}

/* called with audit_filter_mutex */
/* called with audit_filter_mutex */
int audit_add_tree_rule(struct audit_krule *rule)
int audit_add_tree_rule(struct audit_krule *rule)
{
{
	struct audit_tree *seed = rule->tree, *tree;
	struct audit_tree *seed = rule->tree, *tree;
	struct path path;
	struct path path;
	struct vfsmount *mnt, *p;
	struct vfsmount *mnt;
	struct list_head list;
	int err;
	int err;


	list_for_each_entry(tree, &tree_list, list) {
	list_for_each_entry(tree, &tree_list, list) {
@@ -654,16 +654,9 @@ int audit_add_tree_rule(struct audit_krule *rule)
		err = -ENOMEM;
		err = -ENOMEM;
		goto Err;
		goto Err;
	}
	}
	list_add_tail(&list, &mnt->mnt_list);


	get_tree(tree);
	get_tree(tree);
	list_for_each_entry(p, &list, mnt_list) {
	err = iterate_mounts(tag_mount, tree, mnt);
		err = tag_chunk(p->mnt_root->d_inode, tree);
		if (err)
			break;
	}

	list_del(&list);
	drop_collected_mounts(mnt);
	drop_collected_mounts(mnt);


	if (!err) {
	if (!err) {
@@ -700,7 +693,6 @@ int audit_tag_tree(char *old, char *new)
	int failed = 0;
	int failed = 0;
	struct path path1, path2;
	struct path path1, path2;
	struct vfsmount *tagged;
	struct vfsmount *tagged;
	struct list_head list;
	int err;
	int err;


	err = kern_path(new, 0, &path2);
	err = kern_path(new, 0, &path2);
@@ -717,15 +709,12 @@ int audit_tag_tree(char *old, char *new)
		return err;
		return err;
	}
	}


	list_add_tail(&list, &tagged->mnt_list);

	mutex_lock(&audit_filter_mutex);
	mutex_lock(&audit_filter_mutex);
	list_add(&barrier, &tree_list);
	list_add(&barrier, &tree_list);
	list_add(&cursor, &barrier);
	list_add(&cursor, &barrier);


	while (cursor.next != &tree_list) {
	while (cursor.next != &tree_list) {
		struct audit_tree *tree;
		struct audit_tree *tree;
		struct vfsmount *p;
		int good_one = 0;
		int good_one = 0;


		tree = container_of(cursor.next, struct audit_tree, list);
		tree = container_of(cursor.next, struct audit_tree, list);
@@ -746,12 +735,7 @@ int audit_tag_tree(char *old, char *new)
			continue;
			continue;
		}
		}


		list_for_each_entry(p, &list, mnt_list) {
		failed = iterate_mounts(tag_mount, tree, tagged);
			failed = tag_chunk(p->mnt_root->d_inode, tree);
			if (failed)
				break;
		}

		if (failed) {
		if (failed) {
			put_tree(tree);
			put_tree(tree);
			mutex_lock(&audit_filter_mutex);
			mutex_lock(&audit_filter_mutex);
@@ -792,7 +776,6 @@ int audit_tag_tree(char *old, char *new)
	}
	}
	list_del(&barrier);
	list_del(&barrier);
	list_del(&cursor);
	list_del(&cursor);
	list_del(&list);
	mutex_unlock(&audit_filter_mutex);
	mutex_unlock(&audit_filter_mutex);
	path_put(&path1);
	path_put(&path1);
	drop_collected_mounts(tagged);
	drop_collected_mounts(tagged);