diff options
| -rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 82ae6d783c1..599a01952c7 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
| @@ -511,7 +511,8 @@ out: | |||
| 511 | 511 | ||
| 512 | static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, | 512 | static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, |
| 513 | __u32 mask, | 513 | __u32 mask, |
| 514 | unsigned int flags) | 514 | unsigned int flags, |
| 515 | int *destroy) | ||
| 515 | { | 516 | { |
| 516 | __u32 oldmask; | 517 | __u32 oldmask; |
| 517 | 518 | ||
| @@ -525,8 +526,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, | |||
| 525 | } | 526 | } |
| 526 | spin_unlock(&fsn_mark->lock); | 527 | spin_unlock(&fsn_mark->lock); |
| 527 | 528 | ||
| 528 | if (!(oldmask & ~mask)) | 529 | *destroy = !(oldmask & ~mask); |
| 529 | fsnotify_destroy_mark(fsn_mark); | ||
| 530 | 530 | ||
| 531 | return mask & oldmask; | 531 | return mask & oldmask; |
| 532 | } | 532 | } |
| @@ -537,12 +537,17 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group, | |||
| 537 | { | 537 | { |
| 538 | struct fsnotify_mark *fsn_mark = NULL; | 538 | struct fsnotify_mark *fsn_mark = NULL; |
| 539 | __u32 removed; | 539 | __u32 removed; |
| 540 | int destroy_mark; | ||
| 540 | 541 | ||
| 541 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); | 542 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); |
| 542 | if (!fsn_mark) | 543 | if (!fsn_mark) |
| 543 | return -ENOENT; | 544 | return -ENOENT; |
| 544 | 545 | ||
| 545 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags); | 546 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, |
| 547 | &destroy_mark); | ||
| 548 | if (destroy_mark) | ||
| 549 | fsnotify_destroy_mark(fsn_mark); | ||
| 550 | |||
| 546 | fsnotify_put_mark(fsn_mark); | 551 | fsnotify_put_mark(fsn_mark); |
| 547 | if (removed & real_mount(mnt)->mnt_fsnotify_mask) | 552 | if (removed & real_mount(mnt)->mnt_fsnotify_mask) |
| 548 | fsnotify_recalc_vfsmount_mask(mnt); | 553 | fsnotify_recalc_vfsmount_mask(mnt); |
| @@ -556,12 +561,16 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group, | |||
| 556 | { | 561 | { |
| 557 | struct fsnotify_mark *fsn_mark = NULL; | 562 | struct fsnotify_mark *fsn_mark = NULL; |
| 558 | __u32 removed; | 563 | __u32 removed; |
| 564 | int destroy_mark; | ||
| 559 | 565 | ||
| 560 | fsn_mark = fsnotify_find_inode_mark(group, inode); | 566 | fsn_mark = fsnotify_find_inode_mark(group, inode); |
| 561 | if (!fsn_mark) | 567 | if (!fsn_mark) |
| 562 | return -ENOENT; | 568 | return -ENOENT; |
| 563 | 569 | ||
| 564 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags); | 570 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, |
| 571 | &destroy_mark); | ||
| 572 | if (destroy_mark) | ||
| 573 | fsnotify_destroy_mark(fsn_mark); | ||
| 565 | /* matches the fsnotify_find_inode_mark() */ | 574 | /* matches the fsnotify_find_inode_mark() */ |
| 566 | fsnotify_put_mark(fsn_mark); | 575 | fsnotify_put_mark(fsn_mark); |
| 567 | if (removed & inode->i_fsnotify_mask) | 576 | if (removed & inode->i_fsnotify_mask) |
