Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fsnotify: Remove fsnotify_detach_group_marks()

The function is already mostly contained in what
fsnotify_clear_marks_by_group() does. Just update that function to not
select marks when all of them should be destroyed and remove
fsnotify_detach_group_marks().

Reviewed-by: Miklos Szeredi <mszeredi@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>

Jan Kara 2e37c6ca 18f2e0d3

+20 -38
-2
fs/notify/fsnotify.h
··· 40 40 { 41 41 fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify_marks); 42 42 } 43 - /* prepare for freeing all marks associated with given group */ 44 - extern void fsnotify_detach_group_marks(struct fsnotify_group *group); 45 43 /* Wait until all marks queued for destruction are destroyed */ 46 44 extern void fsnotify_wait_marks_destroyed(void); 47 45
+8 -1
fs/notify/group.c
··· 67 67 fsnotify_group_stop_queueing(group); 68 68 69 69 /* Clear all marks for this group and queue them for destruction */ 70 - fsnotify_detach_group_marks(group); 70 + fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES); 71 + 72 + /* 73 + * Some marks can still be pinned when waiting for response from 74 + * userspace. Wait for those now. fsnotify_prepare_user_wait() will 75 + * not succeed now so this wait is race-free. 76 + */ 77 + wait_event(group->notification_waitq, !atomic_read(&group->user_waits)); 71 78 72 79 /* 73 80 * Wait until all marks get really destroyed. We could actually destroy
+10 -35
fs/notify/mark.c
··· 67 67 * - The fs the inode is on is unmounted. (fsnotify_inode_delete/fsnotify_unmount_inodes) 68 68 * - Something explicitly requests that it be removed. (fsnotify_destroy_mark) 69 69 * - The fsnotify_group associated with the mark is going away and all such marks 70 - * need to be cleaned up. (fsnotify_detach_group_marks) 70 + * need to be cleaned up. (fsnotify_clear_marks_by_group) 71 71 * 72 72 * This has the very interesting property of being able to run concurrently with 73 73 * any (or all) other directions. ··· 651 651 { 652 652 struct fsnotify_mark *lmark, *mark; 653 653 LIST_HEAD(to_free); 654 + struct list_head *head = &to_free; 654 655 656 + /* Skip selection step if we want to clear all marks. */ 657 + if (type == FSNOTIFY_OBJ_ALL_TYPES) { 658 + head = &group->marks_list; 659 + goto clear; 660 + } 655 661 /* 656 662 * We have to be really careful here. Anytime we drop mark_mutex, e.g. 657 663 * fsnotify_clear_marks_by_inode() can come and free marks. Even in our ··· 674 668 } 675 669 mutex_unlock(&group->mark_mutex); 676 670 671 + clear: 677 672 while (1) { 678 673 mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); 679 - if (list_empty(&to_free)) { 674 + if (list_empty(head)) { 680 675 mutex_unlock(&group->mark_mutex); 681 676 break; 682 677 } 683 - mark = list_first_entry(&to_free, struct fsnotify_mark, g_list); 678 + mark = list_first_entry(head, struct fsnotify_mark, g_list); 684 679 fsnotify_get_mark(mark); 685 680 fsnotify_detach_mark(mark); 686 681 mutex_unlock(&group->mark_mutex); 687 682 fsnotify_free_mark(mark); 688 683 fsnotify_put_mark(mark); 689 684 } 690 - } 691 - 692 - /* 693 - * Given a group, prepare for freeing all the marks associated with that group. 694 - * The marks are attached to the list of marks prepared for destruction, the 695 - * caller is responsible for freeing marks in that list after SRCU period has 696 - * ended. 697 - */ 698 - void fsnotify_detach_group_marks(struct fsnotify_group *group) 699 - { 700 - struct fsnotify_mark *mark; 701 - 702 - while (1) { 703 - mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); 704 - if (list_empty(&group->marks_list)) { 705 - mutex_unlock(&group->mark_mutex); 706 - break; 707 - } 708 - mark = list_first_entry(&group->marks_list, 709 - struct fsnotify_mark, g_list); 710 - fsnotify_get_mark(mark); 711 - fsnotify_detach_mark(mark); 712 - mutex_unlock(&group->mark_mutex); 713 - fsnotify_free_mark(mark); 714 - fsnotify_put_mark(mark); 715 - } 716 - /* 717 - * Some marks can still be pinned when waiting for response from 718 - * userspace. Wait for those now. fsnotify_prepare_user_wait() will 719 - * not succeed now so this wait is race-free. 720 - */ 721 - wait_event(group->notification_waitq, !atomic_read(&group->user_waits)); 722 685 } 723 686 724 687 /* Destroy all marks attached to inode / vfsmount */
+2
include/linux/fsnotify_backend.h
··· 208 208 spinlock_t lock; 209 209 #define FSNOTIFY_OBJ_TYPE_INODE 0x01 210 210 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT 0x02 211 + #define FSNOTIFY_OBJ_ALL_TYPES (FSNOTIFY_OBJ_TYPE_INODE | \ 212 + FSNOTIFY_OBJ_TYPE_VFSMOUNT) 211 213 unsigned int flags; /* Type of object [lock] */ 212 214 union { /* Object pointer [lock] */ 213 215 struct inode *inode;