summaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fanotify/fanotify_user.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index e16076d386c4..4e1d8ec77b04 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -524,14 +524,18 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
524 __u32 removed; 524 __u32 removed;
525 int destroy_mark; 525 int destroy_mark;
526 526
527 mutex_lock(&group->mark_mutex);
527 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); 528 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
528 if (!fsn_mark) 529 if (!fsn_mark) {
530 mutex_unlock(&group->mark_mutex);
529 return -ENOENT; 531 return -ENOENT;
532 }
530 533
531 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, 534 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
532 &destroy_mark); 535 &destroy_mark);
533 if (destroy_mark) 536 if (destroy_mark)
534 fsnotify_destroy_mark(fsn_mark, group); 537 fsnotify_destroy_mark_locked(fsn_mark, group);
538 mutex_unlock(&group->mark_mutex);
535 539
536 fsnotify_put_mark(fsn_mark); 540 fsnotify_put_mark(fsn_mark);
537 if (removed & real_mount(mnt)->mnt_fsnotify_mask) 541 if (removed & real_mount(mnt)->mnt_fsnotify_mask)
@@ -548,14 +552,19 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
548 __u32 removed; 552 __u32 removed;
549 int destroy_mark; 553 int destroy_mark;
550 554
555 mutex_lock(&group->mark_mutex);
551 fsn_mark = fsnotify_find_inode_mark(group, inode); 556 fsn_mark = fsnotify_find_inode_mark(group, inode);
552 if (!fsn_mark) 557 if (!fsn_mark) {
558 mutex_unlock(&group->mark_mutex);
553 return -ENOENT; 559 return -ENOENT;
560 }
554 561
555 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, 562 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
556 &destroy_mark); 563 &destroy_mark);
557 if (destroy_mark) 564 if (destroy_mark)
558 fsnotify_destroy_mark(fsn_mark, group); 565 fsnotify_destroy_mark_locked(fsn_mark, group);
566 mutex_unlock(&group->mark_mutex);
567
559 /* matches the fsnotify_find_inode_mark() */ 568 /* matches the fsnotify_find_inode_mark() */
560 fsnotify_put_mark(fsn_mark); 569 fsnotify_put_mark(fsn_mark);
561 if (removed & inode->i_fsnotify_mask) 570 if (removed & inode->i_fsnotify_mask)
@@ -599,21 +608,29 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
599 __u32 added; 608 __u32 added;
600 int ret = 0; 609 int ret = 0;
601 610
611 mutex_lock(&group->mark_mutex);
602 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); 612 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
603 if (!fsn_mark) { 613 if (!fsn_mark) {
604 if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) 614 if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) {
615 mutex_unlock(&group->mark_mutex);
605 return -ENOSPC; 616 return -ENOSPC;
617 }
606 618
607 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); 619 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
608 if (!fsn_mark) 620 if (!fsn_mark) {
621 mutex_unlock(&group->mark_mutex);
609 return -ENOMEM; 622 return -ENOMEM;
623 }
610 624
611 fsnotify_init_mark(fsn_mark, fanotify_free_mark); 625 fsnotify_init_mark(fsn_mark, fanotify_free_mark);
612 ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); 626 ret = fsnotify_add_mark_locked(fsn_mark, group, NULL, mnt, 0);
613 if (ret) 627 if (ret) {
628 mutex_unlock(&group->mark_mutex);
614 goto err; 629 goto err;
630 }
615 } 631 }
616 added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); 632 added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
633 mutex_unlock(&group->mark_mutex);
617 634
618 if (added & ~real_mount(mnt)->mnt_fsnotify_mask) 635 if (added & ~real_mount(mnt)->mnt_fsnotify_mask)
619 fsnotify_recalc_vfsmount_mask(mnt); 636 fsnotify_recalc_vfsmount_mask(mnt);
@@ -642,21 +659,29 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
642 (atomic_read(&inode->i_writecount) > 0)) 659 (atomic_read(&inode->i_writecount) > 0))
643 return 0; 660 return 0;
644 661
662 mutex_lock(&group->mark_mutex);
645 fsn_mark = fsnotify_find_inode_mark(group, inode); 663 fsn_mark = fsnotify_find_inode_mark(group, inode);
646 if (!fsn_mark) { 664 if (!fsn_mark) {
647 if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) 665 if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) {
666 mutex_unlock(&group->mark_mutex);
648 return -ENOSPC; 667 return -ENOSPC;
668 }
649 669
650 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); 670 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
651 if (!fsn_mark) 671 if (!fsn_mark) {
672 mutex_unlock(&group->mark_mutex);
652 return -ENOMEM; 673 return -ENOMEM;
674 }
653 675
654 fsnotify_init_mark(fsn_mark, fanotify_free_mark); 676 fsnotify_init_mark(fsn_mark, fanotify_free_mark);
655 ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); 677 ret = fsnotify_add_mark_locked(fsn_mark, group, inode, NULL, 0);
656 if (ret) 678 if (ret) {
679 mutex_unlock(&group->mark_mutex);
657 goto err; 680 goto err;
681 }
658 } 682 }
659 added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); 683 added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
684 mutex_unlock(&group->mark_mutex);
660 685
661 if (added & ~inode->i_fsnotify_mask) 686 if (added & ~inode->i_fsnotify_mask)
662 fsnotify_recalc_inode_mask(inode); 687 fsnotify_recalc_inode_mask(inode);