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

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
...@@ -1246,6 +1246,21 @@ void drop_collected_mounts(struct vfsmount *mnt) ...@@ -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;
......
...@@ -1794,7 +1794,8 @@ extern int may_umount(struct vfsmount *); ...@@ -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);
......
...@@ -548,6 +548,11 @@ int audit_remove_tree_rule(struct audit_krule *rule) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment