apply function to vfsmounts in set returned by collect_mounts(),
stop if it returns non-zero.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
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)
{
struct vfsmount *p;
static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
{
struct vfsmount *p;
extern long do_mount(char *, char *, char *, unsigned long, void *);
extern struct vfsmount *collect_mounts(struct path *);
extern void drop_collected_mounts(struct vfsmount *);
extern long do_mount(char *, char *, char *, unsigned long, void *);
extern struct vfsmount *collect_mounts(struct path *);
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 current_umask(void);
extern int vfs_statfs(struct dentry *, struct kstatfs *);
extern int current_umask(void);
+static int compare_root(struct vfsmount *mnt, void *arg)
+{
+ return mnt->mnt_root->d_inode == arg;
+}
+
void audit_trim_trees(void)
{
struct list_head cursor;
void audit_trim_trees(void)
{
struct list_head cursor;
struct path path;
struct vfsmount *root_mnt;
struct node *node;
struct path path;
struct vfsmount *root_mnt;
struct node *node;
int err;
tree = container_of(cursor.next, struct audit_tree, list);
int err;
tree = container_of(cursor.next, struct audit_tree, list);
if (!root_mnt)
goto skip_it;
if (!root_mnt)
goto skip_it;
- list_add_tail(&list, &root_mnt->mnt_list);
spin_lock(&hash_lock);
list_for_each_entry(node, &tree->chunks, list) {
spin_lock(&hash_lock);
list_for_each_entry(node, &tree->chunks, list) {
- struct audit_chunk *chunk = find_chunk(node);
- struct inode *inode = chunk->watch.inode;
- struct vfsmount *mnt;
+ struct inode *inode = find_chunk(node)->watch.inode;
- list_for_each_entry(mnt, &list, mnt_list) {
- if (mnt->mnt_root->d_inode == inode) {
- node->index &= ~(1U<<31);
- break;
- }
- }
+ if (iterate_mounts(compare_root, inode, root_mnt))
+ node->index &= ~(1U<<31);
}
spin_unlock(&hash_lock);
trim_marked(tree);
put_tree(tree);
}
spin_unlock(&hash_lock);
trim_marked(tree);
put_tree(tree);
drop_collected_mounts(root_mnt);
skip_it:
mutex_lock(&audit_filter_mutex);
drop_collected_mounts(root_mnt);
skip_it:
mutex_lock(&audit_filter_mutex);
+static int tag_mount(struct vfsmount *mnt, void *arg)
+{
+ return tag_chunk(mnt->mnt_root->d_inode, arg);
+}
+
/* called with audit_filter_mutex */
int audit_add_tree_rule(struct audit_krule *rule)
{
struct audit_tree *seed = rule->tree, *tree;
struct path path;
/* called with audit_filter_mutex */
int audit_add_tree_rule(struct audit_krule *rule)
{
struct audit_tree *seed = rule->tree, *tree;
struct path path;
- struct vfsmount *mnt, *p;
- struct list_head list;
int err;
list_for_each_entry(tree, &tree_list, list) {
int err;
list_for_each_entry(tree, &tree_list, list) {
err = -ENOMEM;
goto Err;
}
err = -ENOMEM;
goto Err;
}
- list_add_tail(&list, &mnt->mnt_list);
- list_for_each_entry(p, &list, mnt_list) {
- err = tag_chunk(p->mnt_root->d_inode, tree);
- if (err)
- break;
- }
-
- list_del(&list);
+ err = iterate_mounts(tag_mount, tree, mnt);
drop_collected_mounts(mnt);
if (!err) {
drop_collected_mounts(mnt);
if (!err) {
int failed = 0;
struct path path1, path2;
struct vfsmount *tagged;
int failed = 0;
struct path path1, path2;
struct vfsmount *tagged;
int err;
err = kern_path(new, 0, &path2);
int err;
err = kern_path(new, 0, &path2);
- list_add_tail(&list, &tagged->mnt_list);
-
mutex_lock(&audit_filter_mutex);
list_add(&barrier, &tree_list);
list_add(&cursor, &barrier);
while (cursor.next != &tree_list) {
struct audit_tree *tree;
mutex_lock(&audit_filter_mutex);
list_add(&barrier, &tree_list);
list_add(&cursor, &barrier);
while (cursor.next != &tree_list) {
struct audit_tree *tree;
int good_one = 0;
tree = container_of(cursor.next, struct audit_tree, list);
int good_one = 0;
tree = container_of(cursor.next, struct audit_tree, list);
- list_for_each_entry(p, &list, mnt_list) {
- failed = tag_chunk(p->mnt_root->d_inode, tree);
- if (failed)
- break;
- }
-
+ failed = iterate_mounts(tag_mount, tree, tagged);
if (failed) {
put_tree(tree);
mutex_lock(&audit_filter_mutex);
if (failed) {
put_tree(tree);
mutex_lock(&audit_filter_mutex);
}
list_del(&barrier);
list_del(&cursor);
}
list_del(&barrier);
list_del(&cursor);
mutex_unlock(&audit_filter_mutex);
path_put(&path1);
drop_collected_mounts(tagged);
mutex_unlock(&audit_filter_mutex);
path_put(&path1);
drop_collected_mounts(tagged);