aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-01-30 22:51:25 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2010-03-03 14:07:57 -0500
commit1f707137b55764740981d022d29c622832a61880 (patch)
treeaf5f72ea7df1afbc1f3b5bb53a3ab3d8ebaae1e0
parent462d60577a997aa87c935ae4521bd303733a9f2b (diff)
new helper: iterate_mounts()
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>
-rw-r--r--fs/namespace.c15
-rw-r--r--include/linux/fs.h3
-rw-r--r--kernel/audit_tree.c49
3 files changed, 33 insertions, 34 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index d25d4602ab50..d5906c19e08e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1246,6 +1246,21 @@ void drop_collected_mounts(struct vfsmount *mnt)
1246 release_mounts(&umount_list); 1246 release_mounts(&umount_list);
1247} 1247}
1248 1248
1249int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
1250 struct vfsmount *root)
1251{
1252 struct vfsmount *mnt;
1253 int res = f(root, arg);
1254 if (res)
1255 return res;
1256 list_for_each_entry(mnt, &root->mnt_list, mnt_list) {
1257 res = f(mnt, arg);
1258 if (res)
1259 return res;
1260 }
1261 return 0;
1262}
1263
1249static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end) 1264static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
1250{ 1265{
1251 struct vfsmount *p; 1266 struct vfsmount *p;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8d53bc17f93f..e764f247d0ab 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1794,7 +1794,8 @@ extern int may_umount(struct vfsmount *);
1794extern long do_mount(char *, char *, char *, unsigned long, void *); 1794extern long do_mount(char *, char *, char *, unsigned long, void *);
1795extern struct vfsmount *collect_mounts(struct path *); 1795extern struct vfsmount *collect_mounts(struct path *);
1796extern void drop_collected_mounts(struct vfsmount *); 1796extern void drop_collected_mounts(struct vfsmount *);
1797 1797extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
1798 struct vfsmount *);
1798extern int vfs_statfs(struct dentry *, struct kstatfs *); 1799extern int vfs_statfs(struct dentry *, struct kstatfs *);
1799 1800
1800extern int current_umask(void); 1801extern int current_umask(void);
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index f09b42d9c32d..028e85663f27 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -548,6 +548,11 @@ int audit_remove_tree_rule(struct audit_krule *rule)
548 return 0; 548 return 0;
549} 549}
550 550
551static int compare_root(struct vfsmount *mnt, void *arg)
552{
553 return mnt->mnt_root->d_inode == arg;
554}
555
551void audit_trim_trees(void) 556void audit_trim_trees(void)
552{ 557{
553 struct list_head cursor; 558 struct list_head cursor;
@@ -559,7 +564,6 @@ void audit_trim_trees(void)
559 struct path path; 564 struct path path;
560 struct vfsmount *root_mnt; 565 struct vfsmount *root_mnt;
561 struct node *node; 566 struct node *node;
562 struct list_head list;
563 int err; 567 int err;
564 568
565 tree = container_of(cursor.next, struct audit_tree, list); 569 tree = container_of(cursor.next, struct audit_tree, list);
@@ -577,24 +581,16 @@ void audit_trim_trees(void)
577 if (!root_mnt) 581 if (!root_mnt)
578 goto skip_it; 582 goto skip_it;
579 583
580 list_add_tail(&list, &root_mnt->mnt_list);
581 spin_lock(&hash_lock); 584 spin_lock(&hash_lock);
582 list_for_each_entry(node, &tree->chunks, list) { 585 list_for_each_entry(node, &tree->chunks, list) {
583 struct audit_chunk *chunk = find_chunk(node); 586 struct inode *inode = find_chunk(node)->watch.inode;
584 struct inode *inode = chunk->watch.inode;
585 struct vfsmount *mnt;
586 node->index |= 1U<<31; 587 node->index |= 1U<<31;
587 list_for_each_entry(mnt, &list, mnt_list) { 588 if (iterate_mounts(compare_root, inode, root_mnt))
588 if (mnt->mnt_root->d_inode == inode) { 589 node->index &= ~(1U<<31);
589 node->index &= ~(1U<<31);
590 break;
591 }
592 }
593 } 590 }
594 spin_unlock(&hash_lock); 591 spin_unlock(&hash_lock);
595 trim_marked(tree); 592 trim_marked(tree);
596 put_tree(tree); 593 put_tree(tree);
597 list_del_init(&list);
598 drop_collected_mounts(root_mnt); 594 drop_collected_mounts(root_mnt);
599skip_it: 595skip_it:
600 mutex_lock(&audit_filter_mutex); 596 mutex_lock(&audit_filter_mutex);
@@ -622,13 +618,17 @@ void audit_put_tree(struct audit_tree *tree)
622 put_tree(tree); 618 put_tree(tree);
623} 619}
624 620
621static int tag_mount(struct vfsmount *mnt, void *arg)
622{
623 return tag_chunk(mnt->mnt_root->d_inode, arg);
624}
625
625/* called with audit_filter_mutex */ 626/* called with audit_filter_mutex */
626int audit_add_tree_rule(struct audit_krule *rule) 627int audit_add_tree_rule(struct audit_krule *rule)
627{ 628{
628 struct audit_tree *seed = rule->tree, *tree; 629 struct audit_tree *seed = rule->tree, *tree;
629 struct path path; 630 struct path path;
630 struct vfsmount *mnt, *p; 631 struct vfsmount *mnt;
631 struct list_head list;
632 int err; 632 int err;
633 633
634 list_for_each_entry(tree, &tree_list, list) { 634 list_for_each_entry(tree, &tree_list, list) {
@@ -654,16 +654,9 @@ int audit_add_tree_rule(struct audit_krule *rule)
654 err = -ENOMEM; 654 err = -ENOMEM;
655 goto Err; 655 goto Err;
656 } 656 }
657 list_add_tail(&list, &mnt->mnt_list);
658 657
659 get_tree(tree); 658 get_tree(tree);
660 list_for_each_entry(p, &list, mnt_list) { 659 err = iterate_mounts(tag_mount, tree, mnt);
661 err = tag_chunk(p->mnt_root->d_inode, tree);
662 if (err)
663 break;
664 }
665
666 list_del(&list);
667 drop_collected_mounts(mnt); 660 drop_collected_mounts(mnt);
668 661
669 if (!err) { 662 if (!err) {
@@ -700,7 +693,6 @@ int audit_tag_tree(char *old, char *new)
700 int failed = 0; 693 int failed = 0;
701 struct path path1, path2; 694 struct path path1, path2;
702 struct vfsmount *tagged; 695 struct vfsmount *tagged;
703 struct list_head list;
704 int err; 696 int err;
705 697
706 err = kern_path(new, 0, &path2); 698 err = kern_path(new, 0, &path2);
@@ -717,15 +709,12 @@ int audit_tag_tree(char *old, char *new)
717 return err; 709 return err;
718 } 710 }
719 711
720 list_add_tail(&list, &tagged->mnt_list);
721
722 mutex_lock(&audit_filter_mutex); 712 mutex_lock(&audit_filter_mutex);
723 list_add(&barrier, &tree_list); 713 list_add(&barrier, &tree_list);
724 list_add(&cursor, &barrier); 714 list_add(&cursor, &barrier);
725 715
726 while (cursor.next != &tree_list) { 716 while (cursor.next != &tree_list) {
727 struct audit_tree *tree; 717 struct audit_tree *tree;
728 struct vfsmount *p;
729 int good_one = 0; 718 int good_one = 0;
730 719
731 tree = container_of(cursor.next, struct audit_tree, list); 720 tree = container_of(cursor.next, struct audit_tree, list);
@@ -746,12 +735,7 @@ int audit_tag_tree(char *old, char *new)
746 continue; 735 continue;
747 } 736 }
748 737
749 list_for_each_entry(p, &list, mnt_list) { 738 failed = iterate_mounts(tag_mount, tree, tagged);
750 failed = tag_chunk(p->mnt_root->d_inode, tree);
751 if (failed)
752 break;
753 }
754
755 if (failed) { 739 if (failed) {
756 put_tree(tree); 740 put_tree(tree);
757 mutex_lock(&audit_filter_mutex); 741 mutex_lock(&audit_filter_mutex);
@@ -792,7 +776,6 @@ int audit_tag_tree(char *old, char *new)
792 } 776 }
793 list_del(&barrier); 777 list_del(&barrier);
794 list_del(&cursor); 778 list_del(&cursor);
795 list_del(&list);
796 mutex_unlock(&audit_filter_mutex); 779 mutex_unlock(&audit_filter_mutex);
797 path_put(&path1); 780 path_put(&path1);
798 drop_collected_mounts(tagged); 781 drop_collected_mounts(tagged);