struct audit_parent *parent = NULL;
struct fsnotify_mark *entry;
- spin_lock(&inode->i_lock);
- entry = fsnotify_find_mark(audit_watch_group, inode);
- spin_unlock(&inode->i_lock);
-
+ entry = fsnotify_find_inode_mark(audit_watch_group, inode);
if (entry)
parent = container_of(entry, struct audit_parent, mark);
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;
}
mutex_unlock(&audit_filter_mutex);
fsnotify_destroy_mark(&parent->mark);
-
- fsnotify_recalc_group_mask(audit_watch_group);
-
}
/* Get path information necessary for adding watches. */
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,
- struct vfsmount *mnt, __u32 mask, void *data,
- int data_type)
+ struct fsnotify_mark *inode_mark,
+ struct fsnotify_mark *vfsmount_mark,
+ __u32 mask, void *data, int data_type)
{
- struct fsnotify_mark *entry;
- bool send;
-
- spin_lock(&inode->i_lock);
- entry = fsnotify_find_mark(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);
-
- return send;
+ return true;
}
/* 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 *inode_mark,
+ struct fsnotify_mark *vfsmount_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(inode_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;
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;
}