diff options
| -rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 86 |
1 files changed, 29 insertions, 57 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 3899ad177651..d736a833fe39 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
| @@ -524,17 +524,16 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, | |||
| 524 | return mask & oldmask; | 524 | return mask & oldmask; |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group, | 527 | static int fanotify_remove_mark(struct fsnotify_group *group, |
| 528 | struct vfsmount *mnt, __u32 mask, | 528 | fsnotify_connp_t *connp, __u32 mask, |
| 529 | unsigned int flags) | 529 | unsigned int flags) |
| 530 | { | 530 | { |
| 531 | struct fsnotify_mark *fsn_mark = NULL; | 531 | struct fsnotify_mark *fsn_mark = NULL; |
| 532 | __u32 removed; | 532 | __u32 removed; |
| 533 | int destroy_mark; | 533 | int destroy_mark; |
| 534 | 534 | ||
| 535 | mutex_lock(&group->mark_mutex); | 535 | mutex_lock(&group->mark_mutex); |
| 536 | fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify_marks, | 536 | fsn_mark = fsnotify_find_mark(connp, group); |
| 537 | group); | ||
| 538 | if (!fsn_mark) { | 537 | if (!fsn_mark) { |
| 539 | mutex_unlock(&group->mark_mutex); | 538 | mutex_unlock(&group->mark_mutex); |
| 540 | return -ENOENT; | 539 | return -ENOENT; |
| @@ -550,39 +549,25 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group, | |||
| 550 | if (destroy_mark) | 549 | if (destroy_mark) |
| 551 | fsnotify_free_mark(fsn_mark); | 550 | fsnotify_free_mark(fsn_mark); |
| 552 | 551 | ||
| 552 | /* matches the fsnotify_find_mark() */ | ||
| 553 | fsnotify_put_mark(fsn_mark); | 553 | fsnotify_put_mark(fsn_mark); |
| 554 | return 0; | 554 | return 0; |
| 555 | } | 555 | } |
| 556 | 556 | ||
| 557 | static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group, | ||
| 558 | struct vfsmount *mnt, __u32 mask, | ||
| 559 | unsigned int flags) | ||
| 560 | { | ||
| 561 | return fanotify_remove_mark(group, &real_mount(mnt)->mnt_fsnotify_marks, | ||
| 562 | mask, flags); | ||
| 563 | } | ||
| 564 | |||
| 557 | static int fanotify_remove_inode_mark(struct fsnotify_group *group, | 565 | static int fanotify_remove_inode_mark(struct fsnotify_group *group, |
| 558 | struct inode *inode, __u32 mask, | 566 | struct inode *inode, __u32 mask, |
| 559 | unsigned int flags) | 567 | unsigned int flags) |
| 560 | { | 568 | { |
| 561 | struct fsnotify_mark *fsn_mark = NULL; | 569 | return fanotify_remove_mark(group, &inode->i_fsnotify_marks, mask, |
| 562 | __u32 removed; | 570 | flags); |
| 563 | int destroy_mark; | ||
| 564 | |||
| 565 | mutex_lock(&group->mark_mutex); | ||
| 566 | fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group); | ||
| 567 | if (!fsn_mark) { | ||
| 568 | mutex_unlock(&group->mark_mutex); | ||
| 569 | return -ENOENT; | ||
| 570 | } | ||
| 571 | |||
| 572 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, | ||
| 573 | &destroy_mark); | ||
| 574 | if (removed & fsnotify_conn_mask(fsn_mark->connector)) | ||
| 575 | fsnotify_recalc_mask(fsn_mark->connector); | ||
| 576 | if (destroy_mark) | ||
| 577 | fsnotify_detach_mark(fsn_mark); | ||
| 578 | mutex_unlock(&group->mark_mutex); | ||
| 579 | if (destroy_mark) | ||
| 580 | fsnotify_free_mark(fsn_mark); | ||
| 581 | |||
| 582 | /* matches the fsnotify_find_mark() */ | ||
| 583 | fsnotify_put_mark(fsn_mark); | ||
| 584 | |||
| 585 | return 0; | ||
| 586 | } | 571 | } |
| 587 | 572 | ||
| 588 | static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, | 573 | static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, |
| @@ -639,19 +624,17 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group, | |||
| 639 | } | 624 | } |
| 640 | 625 | ||
| 641 | 626 | ||
| 642 | static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | 627 | static int fanotify_add_mark(struct fsnotify_group *group, |
| 643 | struct vfsmount *mnt, __u32 mask, | 628 | fsnotify_connp_t *connp, unsigned int type, |
| 644 | unsigned int flags) | 629 | __u32 mask, unsigned int flags) |
| 645 | { | 630 | { |
| 646 | fsnotify_connp_t *connp = &real_mount(mnt)->mnt_fsnotify_marks; | ||
| 647 | struct fsnotify_mark *fsn_mark; | 631 | struct fsnotify_mark *fsn_mark; |
| 648 | __u32 added; | 632 | __u32 added; |
| 649 | 633 | ||
| 650 | mutex_lock(&group->mark_mutex); | 634 | mutex_lock(&group->mark_mutex); |
| 651 | fsn_mark = fsnotify_find_mark(connp, group); | 635 | fsn_mark = fsnotify_find_mark(connp, group); |
| 652 | if (!fsn_mark) { | 636 | if (!fsn_mark) { |
| 653 | fsn_mark = fanotify_add_new_mark(group, connp, | 637 | fsn_mark = fanotify_add_new_mark(group, connp, type); |
| 654 | FSNOTIFY_OBJ_TYPE_VFSMOUNT); | ||
| 655 | if (IS_ERR(fsn_mark)) { | 638 | if (IS_ERR(fsn_mark)) { |
| 656 | mutex_unlock(&group->mark_mutex); | 639 | mutex_unlock(&group->mark_mutex); |
| 657 | return PTR_ERR(fsn_mark); | 640 | return PTR_ERR(fsn_mark); |
| @@ -666,14 +649,18 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | |||
| 666 | return 0; | 649 | return 0; |
| 667 | } | 650 | } |
| 668 | 651 | ||
| 652 | static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | ||
| 653 | struct vfsmount *mnt, __u32 mask, | ||
| 654 | unsigned int flags) | ||
| 655 | { | ||
| 656 | return fanotify_add_mark(group, &real_mount(mnt)->mnt_fsnotify_marks, | ||
| 657 | FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags); | ||
| 658 | } | ||
| 659 | |||
| 669 | static int fanotify_add_inode_mark(struct fsnotify_group *group, | 660 | static int fanotify_add_inode_mark(struct fsnotify_group *group, |
| 670 | struct inode *inode, __u32 mask, | 661 | struct inode *inode, __u32 mask, |
| 671 | unsigned int flags) | 662 | unsigned int flags) |
| 672 | { | 663 | { |
| 673 | fsnotify_connp_t *connp = &inode->i_fsnotify_marks; | ||
| 674 | struct fsnotify_mark *fsn_mark; | ||
| 675 | __u32 added; | ||
| 676 | |||
| 677 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); | 664 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); |
| 678 | 665 | ||
| 679 | /* | 666 | /* |
| @@ -686,23 +673,8 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
| 686 | (atomic_read(&inode->i_writecount) > 0)) | 673 | (atomic_read(&inode->i_writecount) > 0)) |
| 687 | return 0; | 674 | return 0; |
| 688 | 675 | ||
| 689 | mutex_lock(&group->mark_mutex); | 676 | return fanotify_add_mark(group, &inode->i_fsnotify_marks, |
| 690 | fsn_mark = fsnotify_find_mark(connp, group); | 677 | FSNOTIFY_OBJ_TYPE_INODE, mask, flags); |
| 691 | if (!fsn_mark) { | ||
| 692 | fsn_mark = fanotify_add_new_mark(group, connp, | ||
| 693 | FSNOTIFY_OBJ_TYPE_INODE); | ||
| 694 | if (IS_ERR(fsn_mark)) { | ||
| 695 | mutex_unlock(&group->mark_mutex); | ||
| 696 | return PTR_ERR(fsn_mark); | ||
| 697 | } | ||
| 698 | } | ||
| 699 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); | ||
| 700 | if (added & ~fsnotify_conn_mask(fsn_mark->connector)) | ||
| 701 | fsnotify_recalc_mask(fsn_mark->connector); | ||
| 702 | mutex_unlock(&group->mark_mutex); | ||
| 703 | |||
| 704 | fsnotify_put_mark(fsn_mark); | ||
| 705 | return 0; | ||
| 706 | } | 678 | } |
| 707 | 679 | ||
| 708 | /* fanotify syscalls */ | 680 | /* fanotify syscalls */ |
