]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - kernel/audit_watch.c
audit: use the mark in handler functions
[net-next-2.6.git] / kernel / audit_watch.c
index 67d8f2f52874c215c6be318cef3676e15d7eb2ed..9173bcf33763a8c803bec77b98154ee0d2f4aaa1 100644 (file)
@@ -56,7 +56,7 @@ struct audit_watch {
 
 struct audit_parent {
        struct list_head        watches; /* anchor for audit_watch->wlist */
-       struct fsnotify_mark_entry mark; /* fsnotify mark on the inode */
+       struct fsnotify_mark mark; /* fsnotify mark on the inode */
 };
 
 /* fsnotify handle. */
@@ -72,7 +72,7 @@ static void audit_free_parent(struct audit_parent *parent)
        kfree(parent);
 }
 
-static void audit_watch_free_mark(struct fsnotify_mark_entry *entry)
+static void audit_watch_free_mark(struct fsnotify_mark *entry)
 {
        struct audit_parent *parent;
 
@@ -99,12 +99,9 @@ static void audit_put_parent(struct audit_parent *parent)
 static inline struct audit_parent *audit_find_parent(struct inode *inode)
 {
        struct audit_parent *parent = NULL;
-       struct fsnotify_mark_entry *entry;
-
-       spin_lock(&inode->i_lock);
-       entry = fsnotify_find_mark_entry(audit_watch_group, inode);
-       spin_unlock(&inode->i_lock);
+       struct fsnotify_mark *entry;
 
+       entry = fsnotify_find_inode_mark(audit_watch_group, inode);
        if (entry)
                parent = container_of(entry, struct audit_parent, mark);
 
@@ -161,12 +158,14 @@ static struct audit_parent *audit_init_parent(struct nameidata *ndp)
 
        fsnotify_init_mark(&parent->mark, audit_watch_free_mark);
        parent->mark.mask = AUDIT_FS_WATCH;
-       ret = fsnotify_add_mark(&parent->mark, audit_watch_group, inode, 0);
+       ret = fsnotify_add_mark(&parent->mark, audit_watch_group, inode, NULL, 0);
        if (ret < 0) {
                audit_free_parent(parent);
                return ERR_PTR(ret);
        }
 
+       fsnotify_recalc_group_mask(audit_watch_group);
+
        return parent;
 }
 
@@ -352,7 +351,10 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
        }
        mutex_unlock(&audit_filter_mutex);
 
-       fsnotify_destroy_mark_by_entry(&parent->mark);
+       fsnotify_destroy_mark(&parent->mark);
+
+       fsnotify_recalc_group_mask(audit_watch_group);
+
 }
 
 /* Get path information necessary for adding watches. */
@@ -499,50 +501,44 @@ void audit_remove_watch_rule(struct audit_krule *krule)
 
                if (list_empty(&parent->watches)) {
                        audit_get_parent(parent);
-                       fsnotify_destroy_mark_by_entry(&parent->mark);
+                       fsnotify_destroy_mark(&parent->mark);
                        audit_put_parent(parent);
                }
        }
+
+       fsnotify_recalc_group_mask(audit_watch_group);
+
 }
 
 static bool audit_watch_should_send_event(struct fsnotify_group *group, struct inode *inode,
-                                         __u32 mask, int data_type)
+                                         struct vfsmount *mnt, struct fsnotify_mark *mark,
+                                         __u32 mask, void *data, int data_type)
 {
-       struct fsnotify_mark_entry *entry;
        bool send;
 
-       spin_lock(&inode->i_lock);
-       entry = fsnotify_find_mark_entry(group, inode);
-       spin_unlock(&inode->i_lock);
-       if (!entry)
-               return false;
-
        mask = (mask & ~FS_EVENT_ON_CHILD);
-       send = (entry->mask & mask);
-
-       /* find took a reference */
-       fsnotify_put_mark(entry);
+       send = (mark->mask & mask);
 
        return send;
 }
 
 /* Update watch data in audit rules based on fsnotify events. */
-static int audit_watch_handle_event(struct fsnotify_group *group, struct fsnotify_event *event)
+static int audit_watch_handle_event(struct fsnotify_group *group,
+                                   struct fsnotify_mark *mark,
+                                   struct fsnotify_event *event)
 {
        struct inode *inode;
        __u32 mask = event->mask;
        const char *dname = event->file_name;
        struct audit_parent *parent;
 
-       BUG_ON(group != audit_watch_group);
+       parent = container_of(mark, struct audit_parent, mark);
 
-       parent = audit_find_parent(event->to_tell);
-       if (unlikely(!parent))
-               return 0;
+       BUG_ON(group != audit_watch_group);
 
        switch (event->data_type) {
-       case (FSNOTIFY_EVENT_PATH):
-               inode = event->path.dentry->d_inode;
+       case (FSNOTIFY_EVENT_FILE):
+               inode = event->file->f_path.dentry->d_inode;
                break;
        case (FSNOTIFY_EVENT_INODE):
                inode = event->inode;
@@ -559,10 +555,6 @@ static int audit_watch_handle_event(struct fsnotify_group *group, struct fsnotif
                audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1);
        else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF))
                audit_remove_parent_watches(parent);
-       /* moved put_inotify_watch to freeing mark */
-
-       /* matched the ref taken by audit_find_parent */
-       audit_put_parent(parent);
 
        return 0;
 }
@@ -577,8 +569,7 @@ static const struct fsnotify_ops audit_watch_fsnotify_ops = {
 
 static int __init audit_watch_init(void)
 {
-       audit_watch_group = fsnotify_obtain_group(AUDIT_WATCH_GROUP_NUM, AUDIT_FS_WATCH,
-                                                 &audit_watch_fsnotify_ops);
+       audit_watch_group = fsnotify_alloc_group(&audit_watch_fsnotify_ops);
        if (IS_ERR(audit_watch_group)) {
                audit_watch_group = NULL;
                audit_panic("cannot create audit fsnotify group");