|
@@ -511,7 +511,8 @@ out:
|
|
|
|
|
|
static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
|
|
|
__u32 mask,
|
|
|
- unsigned int flags)
|
|
|
+ unsigned int flags,
|
|
|
+ int *destroy)
|
|
|
{
|
|
|
__u32 oldmask;
|
|
|
|
|
@@ -525,8 +526,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
|
|
|
}
|
|
|
spin_unlock(&fsn_mark->lock);
|
|
|
|
|
|
- if (!(oldmask & ~mask))
|
|
|
- fsnotify_destroy_mark(fsn_mark);
|
|
|
+ *destroy = !(oldmask & ~mask);
|
|
|
|
|
|
return mask & oldmask;
|
|
|
}
|
|
@@ -537,12 +537,17 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
|
|
|
{
|
|
|
struct fsnotify_mark *fsn_mark = NULL;
|
|
|
__u32 removed;
|
|
|
+ int destroy_mark;
|
|
|
|
|
|
fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
|
|
|
if (!fsn_mark)
|
|
|
return -ENOENT;
|
|
|
|
|
|
- removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags);
|
|
|
+ removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
|
|
|
+ &destroy_mark);
|
|
|
+ if (destroy_mark)
|
|
|
+ fsnotify_destroy_mark(fsn_mark);
|
|
|
+
|
|
|
fsnotify_put_mark(fsn_mark);
|
|
|
if (removed & real_mount(mnt)->mnt_fsnotify_mask)
|
|
|
fsnotify_recalc_vfsmount_mask(mnt);
|
|
@@ -556,12 +561,16 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
|
|
|
{
|
|
|
struct fsnotify_mark *fsn_mark = NULL;
|
|
|
__u32 removed;
|
|
|
+ int destroy_mark;
|
|
|
|
|
|
fsn_mark = fsnotify_find_inode_mark(group, inode);
|
|
|
if (!fsn_mark)
|
|
|
return -ENOENT;
|
|
|
|
|
|
- removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags);
|
|
|
+ removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
|
|
|
+ &destroy_mark);
|
|
|
+ if (destroy_mark)
|
|
|
+ fsnotify_destroy_mark(fsn_mark);
|
|
|
/* matches the fsnotify_find_inode_mark() */
|
|
|
fsnotify_put_mark(fsn_mark);
|
|
|
if (removed & inode->i_fsnotify_mask)
|