aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/notify/dnotify/dnotify.c8
-rw-r--r--fs/notify/fanotify/fanotify.c46
-rw-r--r--fs/notify/fdinfo.c6
-rw-r--r--fs/notify/fsnotify.c138
-rw-r--r--fs/notify/fsnotify.h6
-rw-r--r--fs/notify/group.c2
-rw-r--r--fs/notify/inotify/inotify.h2
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c6
-rw-r--r--fs/notify/inotify/inotify_user.c10
-rw-r--r--fs/notify/mark.c52
-rw-r--r--include/linux/fsnotify_backend.h79
-rw-r--r--kernel/audit_fsnotify.c5
-rw-r--r--kernel/audit_tree.c12
-rw-r--r--kernel/audit_watch.c5
14 files changed, 230 insertions, 147 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 63a1ca4b9dee..e2bea2ac5dfb 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -79,12 +79,11 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
79 */ 79 */
80static int dnotify_handle_event(struct fsnotify_group *group, 80static int dnotify_handle_event(struct fsnotify_group *group,
81 struct inode *inode, 81 struct inode *inode,
82 struct fsnotify_mark *inode_mark,
83 struct fsnotify_mark *vfsmount_mark,
84 u32 mask, const void *data, int data_type, 82 u32 mask, const void *data, int data_type,
85 const unsigned char *file_name, u32 cookie, 83 const unsigned char *file_name, u32 cookie,
86 struct fsnotify_iter_info *iter_info) 84 struct fsnotify_iter_info *iter_info)
87{ 85{
86 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
88 struct dnotify_mark *dn_mark; 87 struct dnotify_mark *dn_mark;
89 struct dnotify_struct *dn; 88 struct dnotify_struct *dn;
90 struct dnotify_struct **prev; 89 struct dnotify_struct **prev;
@@ -95,7 +94,8 @@ static int dnotify_handle_event(struct fsnotify_group *group,
95 if (!S_ISDIR(inode->i_mode)) 94 if (!S_ISDIR(inode->i_mode))
96 return 0; 95 return 0;
97 96
98 BUG_ON(vfsmount_mark); 97 if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
98 return 0;
99 99
100 dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark); 100 dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark);
101 101
@@ -319,7 +319,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
319 dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); 319 dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
320 spin_lock(&fsn_mark->lock); 320 spin_lock(&fsn_mark->lock);
321 } else { 321 } else {
322 error = fsnotify_add_mark_locked(new_fsn_mark, inode, NULL, 0); 322 error = fsnotify_add_inode_mark_locked(new_fsn_mark, inode, 0);
323 if (error) { 323 if (error) {
324 mutex_unlock(&dnotify_group->mark_mutex); 324 mutex_unlock(&dnotify_group->mark_mutex);
325 goto out_err; 325 goto out_err;
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index d94e8031fe5f..f90842efea13 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -87,17 +87,17 @@ static int fanotify_get_response(struct fsnotify_group *group,
87 return ret; 87 return ret;
88} 88}
89 89
90static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark, 90static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
91 struct fsnotify_mark *vfsmnt_mark, 91 u32 event_mask, const void *data,
92 u32 event_mask, 92 int data_type)
93 const void *data, int data_type)
94{ 93{
95 __u32 marks_mask = 0, marks_ignored_mask = 0; 94 __u32 marks_mask = 0, marks_ignored_mask = 0;
96 const struct path *path = data; 95 const struct path *path = data;
96 struct fsnotify_mark *mark;
97 int type;
97 98
98 pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p" 99 pr_debug("%s: report_mask=%x mask=%x data=%p data_type=%d\n",
99 " data_type=%d\n", __func__, inode_mark, vfsmnt_mark, 100 __func__, iter_info->report_mask, event_mask, data, data_type);
100 event_mask, data, data_type);
101 101
102 /* if we don't have enough info to send an event to userspace say no */ 102 /* if we don't have enough info to send an event to userspace say no */
103 if (data_type != FSNOTIFY_EVENT_PATH) 103 if (data_type != FSNOTIFY_EVENT_PATH)
@@ -108,20 +108,21 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
108 !d_can_lookup(path->dentry)) 108 !d_can_lookup(path->dentry))
109 return false; 109 return false;
110 110
111 /* 111 fsnotify_foreach_obj_type(type) {
112 * if the event is for a child and this inode doesn't care about 112 if (!fsnotify_iter_should_report_type(iter_info, type))
113 * events on the child, don't send it! 113 continue;
114 */ 114 mark = iter_info->marks[type];
115 if (inode_mark && 115 /*
116 (!(event_mask & FS_EVENT_ON_CHILD) || 116 * if the event is for a child and this inode doesn't care about
117 (inode_mark->mask & FS_EVENT_ON_CHILD))) { 117 * events on the child, don't send it!
118 marks_mask |= inode_mark->mask; 118 */
119 marks_ignored_mask |= inode_mark->ignored_mask; 119 if (type == FSNOTIFY_OBJ_TYPE_INODE &&
120 } 120 (event_mask & FS_EVENT_ON_CHILD) &&
121 !(mark->mask & FS_EVENT_ON_CHILD))
122 continue;
121 123
122 if (vfsmnt_mark) { 124 marks_mask |= mark->mask;
123 marks_mask |= vfsmnt_mark->mask; 125 marks_ignored_mask |= mark->ignored_mask;
124 marks_ignored_mask |= vfsmnt_mark->ignored_mask;
125 } 126 }
126 127
127 if (d_is_dir(path->dentry) && 128 if (d_is_dir(path->dentry) &&
@@ -178,8 +179,6 @@ init: __maybe_unused
178 179
179static int fanotify_handle_event(struct fsnotify_group *group, 180static int fanotify_handle_event(struct fsnotify_group *group,
180 struct inode *inode, 181 struct inode *inode,
181 struct fsnotify_mark *inode_mark,
182 struct fsnotify_mark *fanotify_mark,
183 u32 mask, const void *data, int data_type, 182 u32 mask, const void *data, int data_type,
184 const unsigned char *file_name, u32 cookie, 183 const unsigned char *file_name, u32 cookie,
185 struct fsnotify_iter_info *iter_info) 184 struct fsnotify_iter_info *iter_info)
@@ -199,8 +198,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
199 BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM); 198 BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
200 BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR); 199 BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
201 200
202 if (!fanotify_should_send_event(inode_mark, fanotify_mark, mask, data, 201 if (!fanotify_should_send_event(iter_info, mask, data, data_type))
203 data_type))
204 return 0; 202 return 0;
205 203
206 pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode, 204 pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
index d478629c728b..10aac1942c9f 100644
--- a/fs/notify/fdinfo.c
+++ b/fs/notify/fdinfo.c
@@ -77,7 +77,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
77 struct inotify_inode_mark *inode_mark; 77 struct inotify_inode_mark *inode_mark;
78 struct inode *inode; 78 struct inode *inode;
79 79
80 if (!(mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE)) 80 if (mark->connector->type != FSNOTIFY_OBJ_TYPE_INODE)
81 return; 81 return;
82 82
83 inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark); 83 inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
@@ -116,7 +116,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
116 if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY) 116 if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)
117 mflags |= FAN_MARK_IGNORED_SURV_MODIFY; 117 mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
118 118
119 if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE) { 119 if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
120 inode = igrab(mark->connector->inode); 120 inode = igrab(mark->connector->inode);
121 if (!inode) 121 if (!inode)
122 return; 122 return;
@@ -126,7 +126,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
126 show_mark_fhandle(m, inode); 126 show_mark_fhandle(m, inode);
127 seq_putc(m, '\n'); 127 seq_putc(m, '\n');
128 iput(inode); 128 iput(inode);
129 } else if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) { 129 } else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
130 struct mount *mnt = real_mount(mark->connector->mnt); 130 struct mount *mnt = real_mount(mark->connector->mnt);
131 131
132 seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n", 132 seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 613ec7e5a465..f174397b63a0 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -184,8 +184,6 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask
184EXPORT_SYMBOL_GPL(__fsnotify_parent); 184EXPORT_SYMBOL_GPL(__fsnotify_parent);
185 185
186static int send_to_group(struct inode *to_tell, 186static int send_to_group(struct inode *to_tell,
187 struct fsnotify_mark *inode_mark,
188 struct fsnotify_mark *vfsmount_mark,
189 __u32 mask, const void *data, 187 __u32 mask, const void *data,
190 int data_is, u32 cookie, 188 int data_is, u32 cookie,
191 const unsigned char *file_name, 189 const unsigned char *file_name,
@@ -195,48 +193,45 @@ static int send_to_group(struct inode *to_tell,
195 __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); 193 __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
196 __u32 marks_mask = 0; 194 __u32 marks_mask = 0;
197 __u32 marks_ignored_mask = 0; 195 __u32 marks_ignored_mask = 0;
196 struct fsnotify_mark *mark;
197 int type;
198 198
199 if (unlikely(!inode_mark && !vfsmount_mark)) { 199 if (WARN_ON(!iter_info->report_mask))
200 BUG();
201 return 0; 200 return 0;
202 }
203 201
204 /* clear ignored on inode modification */ 202 /* clear ignored on inode modification */
205 if (mask & FS_MODIFY) { 203 if (mask & FS_MODIFY) {
206 if (inode_mark && 204 fsnotify_foreach_obj_type(type) {
207 !(inode_mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) 205 if (!fsnotify_iter_should_report_type(iter_info, type))
208 inode_mark->ignored_mask = 0; 206 continue;
209 if (vfsmount_mark && 207 mark = iter_info->marks[type];
210 !(vfsmount_mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)) 208 if (mark &&
211 vfsmount_mark->ignored_mask = 0; 209 !(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY))
212 } 210 mark->ignored_mask = 0;
213 211 }
214 /* does the inode mark tell us to do something? */
215 if (inode_mark) {
216 group = inode_mark->group;
217 marks_mask |= inode_mark->mask;
218 marks_ignored_mask |= inode_mark->ignored_mask;
219 } 212 }
220 213
221 /* does the vfsmount_mark tell us to do something? */ 214 fsnotify_foreach_obj_type(type) {
222 if (vfsmount_mark) { 215 if (!fsnotify_iter_should_report_type(iter_info, type))
223 group = vfsmount_mark->group; 216 continue;
224 marks_mask |= vfsmount_mark->mask; 217 mark = iter_info->marks[type];
225 marks_ignored_mask |= vfsmount_mark->ignored_mask; 218 /* does the object mark tell us to do something? */
219 if (mark) {
220 group = mark->group;
221 marks_mask |= mark->mask;
222 marks_ignored_mask |= mark->ignored_mask;
223 }
226 } 224 }
227 225
228 pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p" 226 pr_debug("%s: group=%p to_tell=%p mask=%x marks_mask=%x marks_ignored_mask=%x"
229 " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
230 " data=%p data_is=%d cookie=%d\n", 227 " data=%p data_is=%d cookie=%d\n",
231 __func__, group, to_tell, mask, inode_mark, vfsmount_mark, 228 __func__, group, to_tell, mask, marks_mask, marks_ignored_mask,
232 marks_mask, marks_ignored_mask, data, 229 data, data_is, cookie);
233 data_is, cookie);
234 230
235 if (!(test_mask & marks_mask & ~marks_ignored_mask)) 231 if (!(test_mask & marks_mask & ~marks_ignored_mask))
236 return 0; 232 return 0;
237 233
238 return group->ops->handle_event(group, to_tell, inode_mark, 234 return group->ops->handle_event(group, to_tell, mask, data, data_is,
239 vfsmount_mark, mask, data, data_is,
240 file_name, cookie, iter_info); 235 file_name, cookie, iter_info);
241} 236}
242 237
@@ -264,6 +259,57 @@ static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark)
264} 259}
265 260
266/* 261/*
262 * iter_info is a multi head priority queue of marks.
263 * Pick a subset of marks from queue heads, all with the
264 * same group and set the report_mask for selected subset.
265 * Returns the report_mask of the selected subset.
266 */
267static unsigned int fsnotify_iter_select_report_types(
268 struct fsnotify_iter_info *iter_info)
269{
270 struct fsnotify_group *max_prio_group = NULL;
271 struct fsnotify_mark *mark;
272 int type;
273
274 /* Choose max prio group among groups of all queue heads */
275 fsnotify_foreach_obj_type(type) {
276 mark = iter_info->marks[type];
277 if (mark &&
278 fsnotify_compare_groups(max_prio_group, mark->group) > 0)
279 max_prio_group = mark->group;
280 }
281
282 if (!max_prio_group)
283 return 0;
284
285 /* Set the report mask for marks from same group as max prio group */
286 iter_info->report_mask = 0;
287 fsnotify_foreach_obj_type(type) {
288 mark = iter_info->marks[type];
289 if (mark &&
290 fsnotify_compare_groups(max_prio_group, mark->group) == 0)
291 fsnotify_iter_set_report_type(iter_info, type);
292 }
293
294 return iter_info->report_mask;
295}
296
297/*
298 * Pop from iter_info multi head queue, the marks that were iterated in the
299 * current iteration step.
300 */
301static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
302{
303 int type;
304
305 fsnotify_foreach_obj_type(type) {
306 if (fsnotify_iter_should_report_type(iter_info, type))
307 iter_info->marks[type] =
308 fsnotify_next_mark(iter_info->marks[type]);
309 }
310}
311
312/*
267 * This is the main call to fsnotify. The VFS calls into hook specific functions 313 * This is the main call to fsnotify. The VFS calls into hook specific functions
268 * in linux/fsnotify.h. Those functions then in turn call here. Here will call 314 * in linux/fsnotify.h. Those functions then in turn call here. Here will call
269 * out to all of the registered fsnotify_group. Those groups can then use the 315 * out to all of the registered fsnotify_group. Those groups can then use the
@@ -307,15 +353,15 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
307 353
308 if ((mask & FS_MODIFY) || 354 if ((mask & FS_MODIFY) ||
309 (test_mask & to_tell->i_fsnotify_mask)) { 355 (test_mask & to_tell->i_fsnotify_mask)) {
310 iter_info.inode_mark = 356 iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
311 fsnotify_first_mark(&to_tell->i_fsnotify_marks); 357 fsnotify_first_mark(&to_tell->i_fsnotify_marks);
312 } 358 }
313 359
314 if (mnt && ((mask & FS_MODIFY) || 360 if (mnt && ((mask & FS_MODIFY) ||
315 (test_mask & mnt->mnt_fsnotify_mask))) { 361 (test_mask & mnt->mnt_fsnotify_mask))) {
316 iter_info.inode_mark = 362 iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
317 fsnotify_first_mark(&to_tell->i_fsnotify_marks); 363 fsnotify_first_mark(&to_tell->i_fsnotify_marks);
318 iter_info.vfsmount_mark = 364 iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] =
319 fsnotify_first_mark(&mnt->mnt_fsnotify_marks); 365 fsnotify_first_mark(&mnt->mnt_fsnotify_marks);
320 } 366 }
321 367
@@ -324,32 +370,14 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
324 * ignore masks are properly reflected for mount mark notifications. 370 * ignore masks are properly reflected for mount mark notifications.
325 * That's why this traversal is so complicated... 371 * That's why this traversal is so complicated...
326 */ 372 */
327 while (iter_info.inode_mark || iter_info.vfsmount_mark) { 373 while (fsnotify_iter_select_report_types(&iter_info)) {
328 struct fsnotify_mark *inode_mark = iter_info.inode_mark; 374 ret = send_to_group(to_tell, mask, data, data_is, cookie,
329 struct fsnotify_mark *vfsmount_mark = iter_info.vfsmount_mark; 375 file_name, &iter_info);
330
331 if (inode_mark && vfsmount_mark) {
332 int cmp = fsnotify_compare_groups(inode_mark->group,
333 vfsmount_mark->group);
334 if (cmp > 0)
335 inode_mark = NULL;
336 else if (cmp < 0)
337 vfsmount_mark = NULL;
338 }
339
340 ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask,
341 data, data_is, cookie, file_name,
342 &iter_info);
343 376
344 if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) 377 if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
345 goto out; 378 goto out;
346 379
347 if (inode_mark) 380 fsnotify_iter_next(&iter_info);
348 iter_info.inode_mark =
349 fsnotify_next_mark(iter_info.inode_mark);
350 if (vfsmount_mark)
351 iter_info.vfsmount_mark =
352 fsnotify_next_mark(iter_info.vfsmount_mark);
353 } 381 }
354 ret = 0; 382 ret = 0;
355out: 383out:
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index 60f365dc1408..34515d2c4ba3 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -9,12 +9,6 @@
9 9
10#include "../mount.h" 10#include "../mount.h"
11 11
12struct fsnotify_iter_info {
13 struct fsnotify_mark *inode_mark;
14 struct fsnotify_mark *vfsmount_mark;
15 int srcu_idx;
16};
17
18/* destroy all events sitting in this groups notification queue */ 12/* destroy all events sitting in this groups notification queue */
19extern void fsnotify_flush_notify(struct fsnotify_group *group); 13extern void fsnotify_flush_notify(struct fsnotify_group *group);
20 14
diff --git a/fs/notify/group.c b/fs/notify/group.c
index b7a4b6a69efa..aa5468f23e45 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -67,7 +67,7 @@ void fsnotify_destroy_group(struct fsnotify_group *group)
67 fsnotify_group_stop_queueing(group); 67 fsnotify_group_stop_queueing(group);
68 68
69 /* Clear all marks for this group and queue them for destruction */ 69 /* Clear all marks for this group and queue them for destruction */
70 fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES); 70 fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES_MASK);
71 71
72 /* 72 /*
73 * Some marks can still be pinned when waiting for response from 73 * Some marks can still be pinned when waiting for response from
diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h
index c00d2caca894..7e4578d35b61 100644
--- a/fs/notify/inotify/inotify.h
+++ b/fs/notify/inotify/inotify.h
@@ -25,8 +25,6 @@ extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
25 struct fsnotify_group *group); 25 struct fsnotify_group *group);
26extern int inotify_handle_event(struct fsnotify_group *group, 26extern int inotify_handle_event(struct fsnotify_group *group,
27 struct inode *inode, 27 struct inode *inode,
28 struct fsnotify_mark *inode_mark,
29 struct fsnotify_mark *vfsmount_mark,
30 u32 mask, const void *data, int data_type, 28 u32 mask, const void *data, int data_type,
31 const unsigned char *file_name, u32 cookie, 29 const unsigned char *file_name, u32 cookie,
32 struct fsnotify_iter_info *iter_info); 30 struct fsnotify_iter_info *iter_info);
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 40dedb37a1f3..9ab6dde38a14 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -65,12 +65,11 @@ static int inotify_merge(struct list_head *list,
65 65
66int inotify_handle_event(struct fsnotify_group *group, 66int inotify_handle_event(struct fsnotify_group *group,
67 struct inode *inode, 67 struct inode *inode,
68 struct fsnotify_mark *inode_mark,
69 struct fsnotify_mark *vfsmount_mark,
70 u32 mask, const void *data, int data_type, 68 u32 mask, const void *data, int data_type,
71 const unsigned char *file_name, u32 cookie, 69 const unsigned char *file_name, u32 cookie,
72 struct fsnotify_iter_info *iter_info) 70 struct fsnotify_iter_info *iter_info)
73{ 71{
72 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
74 struct inotify_inode_mark *i_mark; 73 struct inotify_inode_mark *i_mark;
75 struct inotify_event_info *event; 74 struct inotify_event_info *event;
76 struct fsnotify_event *fsn_event; 75 struct fsnotify_event *fsn_event;
@@ -78,7 +77,8 @@ int inotify_handle_event(struct fsnotify_group *group,
78 int len = 0; 77 int len = 0;
79 int alloc_len = sizeof(struct inotify_event_info); 78 int alloc_len = sizeof(struct inotify_event_info);
80 79
81 BUG_ON(vfsmount_mark); 80 if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
81 return 0;
82 82
83 if ((inode_mark->mask & FS_EXCL_UNLINK) && 83 if ((inode_mark->mask & FS_EXCL_UNLINK) &&
84 (data_type == FSNOTIFY_EVENT_PATH)) { 84 (data_type == FSNOTIFY_EVENT_PATH)) {
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index ef32f3657958..1cf5b779d862 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -485,10 +485,14 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
485 struct fsnotify_group *group) 485 struct fsnotify_group *group)
486{ 486{
487 struct inotify_inode_mark *i_mark; 487 struct inotify_inode_mark *i_mark;
488 struct fsnotify_iter_info iter_info = { };
489
490 fsnotify_iter_set_report_type_mark(&iter_info, FSNOTIFY_OBJ_TYPE_INODE,
491 fsn_mark);
488 492
489 /* Queue ignore event for the watch */ 493 /* Queue ignore event for the watch */
490 inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED, 494 inotify_handle_event(group, NULL, FS_IN_IGNORED, NULL,
491 NULL, FSNOTIFY_EVENT_NONE, NULL, 0, NULL); 495 FSNOTIFY_EVENT_NONE, NULL, 0, &iter_info);
492 496
493 i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); 497 i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
494 /* remove this mark from the idr */ 498 /* remove this mark from the idr */
@@ -578,7 +582,7 @@ static int inotify_new_watch(struct fsnotify_group *group,
578 } 582 }
579 583
580 /* we are on the idr, now get on the inode */ 584 /* we are on the idr, now get on the inode */
581 ret = fsnotify_add_mark_locked(&tmp_i_mark->fsn_mark, inode, NULL, 0); 585 ret = fsnotify_add_inode_mark_locked(&tmp_i_mark->fsn_mark, inode, 0);
582 if (ret) { 586 if (ret) {
583 /* we failed to get on the inode, get off the idr */ 587 /* we failed to get on the inode, get off the idr */
584 inotify_remove_from_idr(group, tmp_i_mark); 588 inotify_remove_from_idr(group, tmp_i_mark);
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index e9191b416434..61f4c5fa34c7 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -119,9 +119,9 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
119 if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) 119 if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
120 new_mask |= mark->mask; 120 new_mask |= mark->mask;
121 } 121 }
122 if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) 122 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
123 conn->inode->i_fsnotify_mask = new_mask; 123 conn->inode->i_fsnotify_mask = new_mask;
124 else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) 124 else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
125 real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask; 125 real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask;
126} 126}
127 127
@@ -139,7 +139,7 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
139 spin_lock(&conn->lock); 139 spin_lock(&conn->lock);
140 __fsnotify_recalc_mask(conn); 140 __fsnotify_recalc_mask(conn);
141 spin_unlock(&conn->lock); 141 spin_unlock(&conn->lock);
142 if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) 142 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
143 __fsnotify_update_child_dentry_flags(conn->inode); 143 __fsnotify_update_child_dentry_flags(conn->inode);
144} 144}
145 145
@@ -166,18 +166,18 @@ static struct inode *fsnotify_detach_connector_from_object(
166{ 166{
167 struct inode *inode = NULL; 167 struct inode *inode = NULL;
168 168
169 if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) { 169 if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
170 inode = conn->inode; 170 inode = conn->inode;
171 rcu_assign_pointer(inode->i_fsnotify_marks, NULL); 171 rcu_assign_pointer(inode->i_fsnotify_marks, NULL);
172 inode->i_fsnotify_mask = 0; 172 inode->i_fsnotify_mask = 0;
173 conn->inode = NULL; 173 conn->inode = NULL;
174 conn->flags &= ~FSNOTIFY_OBJ_TYPE_INODE; 174 conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
175 } else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) { 175 } else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
176 rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify_marks, 176 rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify_marks,
177 NULL); 177 NULL);
178 real_mount(conn->mnt)->mnt_fsnotify_mask = 0; 178 real_mount(conn->mnt)->mnt_fsnotify_mask = 0;
179 conn->mnt = NULL; 179 conn->mnt = NULL;
180 conn->flags &= ~FSNOTIFY_OBJ_TYPE_VFSMOUNT; 180 conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
181 } 181 }
182 182
183 return inode; 183 return inode;
@@ -294,12 +294,12 @@ static void fsnotify_put_mark_wake(struct fsnotify_mark *mark)
294 294
295bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info) 295bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info)
296{ 296{
297 /* This can fail if mark is being removed */ 297 int type;
298 if (!fsnotify_get_mark_safe(iter_info->inode_mark)) 298
299 return false; 299 fsnotify_foreach_obj_type(type) {
300 if (!fsnotify_get_mark_safe(iter_info->vfsmount_mark)) { 300 /* This can fail if mark is being removed */
301 fsnotify_put_mark_wake(iter_info->inode_mark); 301 if (!fsnotify_get_mark_safe(iter_info->marks[type]))
302 return false; 302 goto fail;
303 } 303 }
304 304
305 /* 305 /*
@@ -310,13 +310,20 @@ bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info)
310 srcu_read_unlock(&fsnotify_mark_srcu, iter_info->srcu_idx); 310 srcu_read_unlock(&fsnotify_mark_srcu, iter_info->srcu_idx);
311 311
312 return true; 312 return true;
313
314fail:
315 for (type--; type >= 0; type--)
316 fsnotify_put_mark_wake(iter_info->marks[type]);
317 return false;
313} 318}
314 319
315void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info) 320void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info)
316{ 321{
322 int type;
323
317 iter_info->srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); 324 iter_info->srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
318 fsnotify_put_mark_wake(iter_info->inode_mark); 325 fsnotify_foreach_obj_type(type)
319 fsnotify_put_mark_wake(iter_info->vfsmount_mark); 326 fsnotify_put_mark_wake(iter_info->marks[type]);
320} 327}
321 328
322/* 329/*
@@ -442,10 +449,10 @@ static int fsnotify_attach_connector_to_object(
442 spin_lock_init(&conn->lock); 449 spin_lock_init(&conn->lock);
443 INIT_HLIST_HEAD(&conn->list); 450 INIT_HLIST_HEAD(&conn->list);
444 if (inode) { 451 if (inode) {
445 conn->flags = FSNOTIFY_OBJ_TYPE_INODE; 452 conn->type = FSNOTIFY_OBJ_TYPE_INODE;
446 conn->inode = igrab(inode); 453 conn->inode = igrab(inode);
447 } else { 454 } else {
448 conn->flags = FSNOTIFY_OBJ_TYPE_VFSMOUNT; 455 conn->type = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
449 conn->mnt = mnt; 456 conn->mnt = mnt;
450 } 457 }
451 /* 458 /*
@@ -479,8 +486,7 @@ static struct fsnotify_mark_connector *fsnotify_grab_connector(
479 if (!conn) 486 if (!conn)
480 goto out; 487 goto out;
481 spin_lock(&conn->lock); 488 spin_lock(&conn->lock);
482 if (!(conn->flags & (FSNOTIFY_OBJ_TYPE_INODE | 489 if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED) {
483 FSNOTIFY_OBJ_TYPE_VFSMOUNT))) {
484 spin_unlock(&conn->lock); 490 spin_unlock(&conn->lock);
485 srcu_read_unlock(&fsnotify_mark_srcu, idx); 491 srcu_read_unlock(&fsnotify_mark_srcu, idx);
486 return NULL; 492 return NULL;
@@ -646,16 +652,16 @@ struct fsnotify_mark *fsnotify_find_mark(
646 return NULL; 652 return NULL;
647} 653}
648 654
649/* Clear any marks in a group with given type */ 655/* Clear any marks in a group with given type mask */
650void fsnotify_clear_marks_by_group(struct fsnotify_group *group, 656void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
651 unsigned int type) 657 unsigned int type_mask)
652{ 658{
653 struct fsnotify_mark *lmark, *mark; 659 struct fsnotify_mark *lmark, *mark;
654 LIST_HEAD(to_free); 660 LIST_HEAD(to_free);
655 struct list_head *head = &to_free; 661 struct list_head *head = &to_free;
656 662
657 /* Skip selection step if we want to clear all marks. */ 663 /* Skip selection step if we want to clear all marks. */
658 if (type == FSNOTIFY_OBJ_ALL_TYPES) { 664 if (type_mask == FSNOTIFY_OBJ_ALL_TYPES_MASK) {
659 head = &group->marks_list; 665 head = &group->marks_list;
660 goto clear; 666 goto clear;
661 } 667 }
@@ -670,7 +676,7 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
670 */ 676 */
671 mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); 677 mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
672 list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { 678 list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
673 if (mark->connector->flags & type) 679 if ((1U << mark->connector->type) & type_mask)
674 list_move(&mark->g_list, &to_free); 680 list_move(&mark->g_list, &to_free);
675 } 681 }
676 mutex_unlock(&group->mark_mutex); 682 mutex_unlock(&group->mark_mutex);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index e64c0294f50b..b38964a7a521 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -98,8 +98,6 @@ struct fsnotify_iter_info;
98struct fsnotify_ops { 98struct fsnotify_ops {
99 int (*handle_event)(struct fsnotify_group *group, 99 int (*handle_event)(struct fsnotify_group *group,
100 struct inode *inode, 100 struct inode *inode,
101 struct fsnotify_mark *inode_mark,
102 struct fsnotify_mark *vfsmount_mark,
103 u32 mask, const void *data, int data_type, 101 u32 mask, const void *data, int data_type,
104 const unsigned char *file_name, u32 cookie, 102 const unsigned char *file_name, u32 cookie,
105 struct fsnotify_iter_info *iter_info); 103 struct fsnotify_iter_info *iter_info);
@@ -201,6 +199,57 @@ struct fsnotify_group {
201#define FSNOTIFY_EVENT_PATH 1 199#define FSNOTIFY_EVENT_PATH 1
202#define FSNOTIFY_EVENT_INODE 2 200#define FSNOTIFY_EVENT_INODE 2
203 201
202enum fsnotify_obj_type {
203 FSNOTIFY_OBJ_TYPE_INODE,
204 FSNOTIFY_OBJ_TYPE_VFSMOUNT,
205 FSNOTIFY_OBJ_TYPE_COUNT,
206 FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT
207};
208
209#define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE)
210#define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
211#define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
212
213struct fsnotify_iter_info {
214 struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT];
215 unsigned int report_mask;
216 int srcu_idx;
217};
218
219static inline bool fsnotify_iter_should_report_type(
220 struct fsnotify_iter_info *iter_info, int type)
221{
222 return (iter_info->report_mask & (1U << type));
223}
224
225static inline void fsnotify_iter_set_report_type(
226 struct fsnotify_iter_info *iter_info, int type)
227{
228 iter_info->report_mask |= (1U << type);
229}
230
231static inline void fsnotify_iter_set_report_type_mark(
232 struct fsnotify_iter_info *iter_info, int type,
233 struct fsnotify_mark *mark)
234{
235 iter_info->marks[type] = mark;
236 iter_info->report_mask |= (1U << type);
237}
238
239#define FSNOTIFY_ITER_FUNCS(name, NAME) \
240static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \
241 struct fsnotify_iter_info *iter_info) \
242{ \
243 return (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_##NAME##_FL) ? \
244 iter_info->marks[FSNOTIFY_OBJ_TYPE_##NAME] : NULL; \
245}
246
247FSNOTIFY_ITER_FUNCS(inode, INODE)
248FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
249
250#define fsnotify_foreach_obj_type(type) \
251 for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++)
252
204/* 253/*
205 * Inode / vfsmount point to this structure which tracks all marks attached to 254 * Inode / vfsmount point to this structure which tracks all marks attached to
206 * the inode / vfsmount. The reference to inode / vfsmount is held by this 255 * the inode / vfsmount. The reference to inode / vfsmount is held by this
@@ -209,11 +258,7 @@ struct fsnotify_group {
209 */ 258 */
210struct fsnotify_mark_connector { 259struct fsnotify_mark_connector {
211 spinlock_t lock; 260 spinlock_t lock;
212#define FSNOTIFY_OBJ_TYPE_INODE 0x01 261 unsigned int type; /* Type of object [lock] */
213#define FSNOTIFY_OBJ_TYPE_VFSMOUNT 0x02
214#define FSNOTIFY_OBJ_ALL_TYPES (FSNOTIFY_OBJ_TYPE_INODE | \
215 FSNOTIFY_OBJ_TYPE_VFSMOUNT)
216 unsigned int flags; /* Type of object [lock] */
217 union { /* Object pointer [lock] */ 262 union { /* Object pointer [lock] */
218 struct inode *inode; 263 struct inode *inode;
219 struct vfsmount *mnt; 264 struct vfsmount *mnt;
@@ -356,7 +401,21 @@ extern struct fsnotify_mark *fsnotify_find_mark(
356extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode, 401extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
357 struct vfsmount *mnt, int allow_dups); 402 struct vfsmount *mnt, int allow_dups);
358extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, 403extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
359 struct inode *inode, struct vfsmount *mnt, int allow_dups); 404 struct inode *inode, struct vfsmount *mnt,
405 int allow_dups);
406/* attach the mark to the inode */
407static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
408 struct inode *inode,
409 int allow_dups)
410{
411 return fsnotify_add_mark(mark, inode, NULL, allow_dups);
412}
413static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark,
414 struct inode *inode,
415 int allow_dups)
416{
417 return fsnotify_add_mark_locked(mark, inode, NULL, allow_dups);
418}
360/* given a group and a mark, flag mark to be freed when all references are dropped */ 419/* given a group and a mark, flag mark to be freed when all references are dropped */
361extern void fsnotify_destroy_mark(struct fsnotify_mark *mark, 420extern void fsnotify_destroy_mark(struct fsnotify_mark *mark,
362 struct fsnotify_group *group); 421 struct fsnotify_group *group);
@@ -369,12 +428,12 @@ extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group, unsigned
369/* run all the marks in a group, and clear all of the vfsmount marks */ 428/* run all the marks in a group, and clear all of the vfsmount marks */
370static inline void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) 429static inline void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group)
371{ 430{
372 fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT); 431 fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL);
373} 432}
374/* run all the marks in a group, and clear all of the inode marks */ 433/* run all the marks in a group, and clear all of the inode marks */
375static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group) 434static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group)
376{ 435{
377 fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE); 436 fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL);
378} 437}
379extern void fsnotify_get_mark(struct fsnotify_mark *mark); 438extern void fsnotify_get_mark(struct fsnotify_mark *mark);
380extern void fsnotify_put_mark(struct fsnotify_mark *mark); 439extern void fsnotify_put_mark(struct fsnotify_mark *mark);
diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
index 52f368b6561e..fba78047fb37 100644
--- a/kernel/audit_fsnotify.c
+++ b/kernel/audit_fsnotify.c
@@ -109,7 +109,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa
109 audit_update_mark(audit_mark, dentry->d_inode); 109 audit_update_mark(audit_mark, dentry->d_inode);
110 audit_mark->rule = krule; 110 audit_mark->rule = krule;
111 111
112 ret = fsnotify_add_mark(&audit_mark->mark, inode, NULL, true); 112 ret = fsnotify_add_inode_mark(&audit_mark->mark, inode, true);
113 if (ret < 0) { 113 if (ret < 0) {
114 fsnotify_put_mark(&audit_mark->mark); 114 fsnotify_put_mark(&audit_mark->mark);
115 audit_mark = ERR_PTR(ret); 115 audit_mark = ERR_PTR(ret);
@@ -165,12 +165,11 @@ static void audit_autoremove_mark_rule(struct audit_fsnotify_mark *audit_mark)
165/* Update mark data in audit rules based on fsnotify events. */ 165/* Update mark data in audit rules based on fsnotify events. */
166static int audit_mark_handle_event(struct fsnotify_group *group, 166static int audit_mark_handle_event(struct fsnotify_group *group,
167 struct inode *to_tell, 167 struct inode *to_tell,
168 struct fsnotify_mark *inode_mark,
169 struct fsnotify_mark *vfsmount_mark,
170 u32 mask, const void *data, int data_type, 168 u32 mask, const void *data, int data_type,
171 const unsigned char *dname, u32 cookie, 169 const unsigned char *dname, u32 cookie,
172 struct fsnotify_iter_info *iter_info) 170 struct fsnotify_iter_info *iter_info)
173{ 171{
172 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
174 struct audit_fsnotify_mark *audit_mark; 173 struct audit_fsnotify_mark *audit_mark;
175 const struct inode *inode = NULL; 174 const struct inode *inode = NULL;
176 175
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 67e6956c0b61..c99ebaae5abc 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -288,8 +288,8 @@ static void untag_chunk(struct node *p)
288 if (!new) 288 if (!new)
289 goto Fallback; 289 goto Fallback;
290 290
291 if (fsnotify_add_mark_locked(&new->mark, entry->connector->inode, 291 if (fsnotify_add_inode_mark_locked(&new->mark, entry->connector->inode,
292 NULL, 1)) { 292 1)) {
293 fsnotify_put_mark(&new->mark); 293 fsnotify_put_mark(&new->mark);
294 goto Fallback; 294 goto Fallback;
295 } 295 }
@@ -354,7 +354,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
354 return -ENOMEM; 354 return -ENOMEM;
355 355
356 entry = &chunk->mark; 356 entry = &chunk->mark;
357 if (fsnotify_add_mark(entry, inode, NULL, 0)) { 357 if (fsnotify_add_inode_mark(entry, inode, 0)) {
358 fsnotify_put_mark(entry); 358 fsnotify_put_mark(entry);
359 return -ENOSPC; 359 return -ENOSPC;
360 } 360 }
@@ -434,8 +434,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
434 return -ENOENT; 434 return -ENOENT;
435 } 435 }
436 436
437 if (fsnotify_add_mark_locked(chunk_entry, 437 if (fsnotify_add_inode_mark_locked(chunk_entry,
438 old_entry->connector->inode, NULL, 1)) { 438 old_entry->connector->inode, 1)) {
439 spin_unlock(&old_entry->lock); 439 spin_unlock(&old_entry->lock);
440 mutex_unlock(&old_entry->group->mark_mutex); 440 mutex_unlock(&old_entry->group->mark_mutex);
441 fsnotify_put_mark(chunk_entry); 441 fsnotify_put_mark(chunk_entry);
@@ -989,8 +989,6 @@ static void evict_chunk(struct audit_chunk *chunk)
989 989
990static int audit_tree_handle_event(struct fsnotify_group *group, 990static int audit_tree_handle_event(struct fsnotify_group *group,
991 struct inode *to_tell, 991 struct inode *to_tell,
992 struct fsnotify_mark *inode_mark,
993 struct fsnotify_mark *vfsmount_mark,
994 u32 mask, const void *data, int data_type, 992 u32 mask, const void *data, int data_type,
995 const unsigned char *file_name, u32 cookie, 993 const unsigned char *file_name, u32 cookie,
996 struct fsnotify_iter_info *iter_info) 994 struct fsnotify_iter_info *iter_info)
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index f1ba88994508..c17c0c268436 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -160,7 +160,7 @@ static struct audit_parent *audit_init_parent(struct path *path)
160 160
161 fsnotify_init_mark(&parent->mark, audit_watch_group); 161 fsnotify_init_mark(&parent->mark, audit_watch_group);
162 parent->mark.mask = AUDIT_FS_WATCH; 162 parent->mark.mask = AUDIT_FS_WATCH;
163 ret = fsnotify_add_mark(&parent->mark, inode, NULL, 0); 163 ret = fsnotify_add_inode_mark(&parent->mark, inode, 0);
164 if (ret < 0) { 164 if (ret < 0) {
165 audit_free_parent(parent); 165 audit_free_parent(parent);
166 return ERR_PTR(ret); 166 return ERR_PTR(ret);
@@ -472,12 +472,11 @@ void audit_remove_watch_rule(struct audit_krule *krule)
472/* Update watch data in audit rules based on fsnotify events. */ 472/* Update watch data in audit rules based on fsnotify events. */
473static int audit_watch_handle_event(struct fsnotify_group *group, 473static int audit_watch_handle_event(struct fsnotify_group *group,
474 struct inode *to_tell, 474 struct inode *to_tell,
475 struct fsnotify_mark *inode_mark,
476 struct fsnotify_mark *vfsmount_mark,
477 u32 mask, const void *data, int data_type, 475 u32 mask, const void *data, int data_type,
478 const unsigned char *dname, u32 cookie, 476 const unsigned char *dname, u32 cookie,
479 struct fsnotify_iter_info *iter_info) 477 struct fsnotify_iter_info *iter_info)
480{ 478{
479 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
481 const struct inode *inode; 480 const struct inode *inode;
482 struct audit_parent *parent; 481 struct audit_parent *parent;
483 482