aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fanotify/fanotify_user.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 091371e1bde3..00628d3ce5a2 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -310,22 +310,33 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, __u3
310 return mask & oldmask; 310 return mask & oldmask;
311} 311}
312 312
313static int fanotify_remove_mark(struct fsnotify_group *group, struct inode *inode, 313static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
314 struct vfsmount *mnt, __u32 mask) 314 struct vfsmount *mnt, __u32 mask)
315{ 315{
316 struct fsnotify_mark *fsn_mark = NULL; 316 struct fsnotify_mark *fsn_mark = NULL;
317 __u32 removed; 317 __u32 removed;
318 318
319 BUG_ON(inode && mnt); 319 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
320 BUG_ON(!inode && !mnt); 320 if (!fsn_mark)
321 return -ENOENT;
321 322
322 if (inode) 323 removed = fanotify_mark_remove_from_mask(fsn_mark, mask);
323 fsn_mark = fsnotify_find_inode_mark(group, inode); 324 fsnotify_put_mark(fsn_mark);
324 else if (mnt) 325 if (removed & group->mask)
325 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); 326 fsnotify_recalc_group_mask(group);
326 else 327 if (removed & mnt->mnt_fsnotify_mask)
327 BUG(); 328 fsnotify_recalc_vfsmount_mask(mnt);
329
330 return 0;
331}
328 332
333static int fanotify_remove_inode_mark(struct fsnotify_group *group,
334 struct inode *inode, __u32 mask)
335{
336 struct fsnotify_mark *fsn_mark = NULL;
337 __u32 removed;
338
339 fsn_mark = fsnotify_find_inode_mark(group, inode);
329 if (!fsn_mark) 340 if (!fsn_mark)
330 return -ENOENT; 341 return -ENOENT;
331 342
@@ -335,13 +346,8 @@ static int fanotify_remove_mark(struct fsnotify_group *group, struct inode *inod
335 346
336 if (removed & group->mask) 347 if (removed & group->mask)
337 fsnotify_recalc_group_mask(group); 348 fsnotify_recalc_group_mask(group);
338 if (inode) { 349 if (removed & inode->i_fsnotify_mask)
339 if (removed & inode->i_fsnotify_mask) 350 fsnotify_recalc_inode_mask(inode);
340 fsnotify_recalc_inode_mask(inode);
341 } else if (mnt) {
342 if (removed & mnt->mnt_fsnotify_mask)
343 fsnotify_recalc_vfsmount_mask(mnt);
344 }
345 351
346 return 0; 352 return 0;
347} 353}
@@ -531,7 +537,10 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
531 ret = fanotify_add_inode_mark(group, inode, mask); 537 ret = fanotify_add_inode_mark(group, inode, mask);
532 break; 538 break;
533 case FAN_MARK_REMOVE: 539 case FAN_MARK_REMOVE:
534 ret = fanotify_remove_mark(group, inode, mnt, mask); 540 if (flags & FAN_MARK_MOUNT)
541 ret = fanotify_remove_vfsmount_mark(group, mnt, mask);
542 else
543 ret = fanotify_remove_inode_mark(group, inode, mask);
535 break; 544 break;
536 default: 545 default:
537 ret = -EINVAL; 546 ret = -EINVAL;