fsnotify: Remove fsnotify_detach_group_marks()
authorJan Kara <jack@suse.cz>
Wed, 4 Jan 2017 09:51:58 +0000 (10:51 +0100)
committerJan Kara <jack@suse.cz>
Mon, 10 Apr 2017 15:37:36 +0000 (17:37 +0200)
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>
fs/notify/fsnotify.h
fs/notify/group.c
fs/notify/mark.c
include/linux/fsnotify_backend.h

index 86383c7..3ec593c 100644 (file)
@@ -40,8 +40,6 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
 {
        fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify_marks);
 }
-/* prepare for freeing all marks associated with given group */
-extern void fsnotify_detach_group_marks(struct fsnotify_group *group);
 /* Wait until all marks queued for destruction are destroyed */
 extern void fsnotify_wait_marks_destroyed(void);
 
index 79439cd..3235753 100644 (file)
@@ -67,7 +67,14 @@ void fsnotify_destroy_group(struct fsnotify_group *group)
        fsnotify_group_stop_queueing(group);
 
        /* Clear all marks for this group and queue them for destruction */
-       fsnotify_detach_group_marks(group);
+       fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES);
+
+       /*
+        * Some marks can still be pinned when waiting for response from
+        * userspace. Wait for those now. fsnotify_prepare_user_wait() will
+        * not succeed now so this wait is race-free.
+        */
+       wait_event(group->notification_waitq, !atomic_read(&group->user_waits));
 
        /*
         * Wait until all marks get really destroyed. We could actually destroy
index 89656ab..9f3364e 100644 (file)
@@ -67,7 +67,7 @@
  * - The fs the inode is on is unmounted.  (fsnotify_inode_delete/fsnotify_unmount_inodes)
  * - Something explicitly requests that it be removed.  (fsnotify_destroy_mark)
  * - The fsnotify_group associated with the mark is going away and all such marks
- *   need to be cleaned up. (fsnotify_detach_group_marks)
+ *   need to be cleaned up. (fsnotify_clear_marks_by_group)
  *
  * This has the very interesting property of being able to run concurrently with
  * any (or all) other directions.
@@ -651,7 +651,13 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
 {
        struct fsnotify_mark *lmark, *mark;
        LIST_HEAD(to_free);
+       struct list_head *head = &to_free;
 
+       /* Skip selection step if we want to clear all marks. */
+       if (type == FSNOTIFY_OBJ_ALL_TYPES) {
+               head = &group->marks_list;
+               goto clear;
+       }
        /*
         * We have to be really careful here. Anytime we drop mark_mutex, e.g.
         * fsnotify_clear_marks_by_inode() can come and free marks. Even in our
@@ -668,13 +674,14 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
        }
        mutex_unlock(&group->mark_mutex);
 
+clear:
        while (1) {
                mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
-               if (list_empty(&to_free)) {
+               if (list_empty(head)) {
                        mutex_unlock(&group->mark_mutex);
                        break;
                }
-               mark = list_first_entry(&to_free, struct fsnotify_mark, g_list);
+               mark = list_first_entry(head, struct fsnotify_mark, g_list);
                fsnotify_get_mark(mark);
                fsnotify_detach_mark(mark);
                mutex_unlock(&group->mark_mutex);
@@ -683,38 +690,6 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
        }
 }
 
-/*
- * Given a group, prepare for freeing all the marks associated with that group.
- * The marks are attached to the list of marks prepared for destruction, the
- * caller is responsible for freeing marks in that list after SRCU period has
- * ended.
- */
-void fsnotify_detach_group_marks(struct fsnotify_group *group)
-{
-       struct fsnotify_mark *mark;
-
-       while (1) {
-               mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
-               if (list_empty(&group->marks_list)) {
-                       mutex_unlock(&group->mark_mutex);
-                       break;
-               }
-               mark = list_first_entry(&group->marks_list,
-                                       struct fsnotify_mark, g_list);
-               fsnotify_get_mark(mark);
-               fsnotify_detach_mark(mark);
-               mutex_unlock(&group->mark_mutex);
-               fsnotify_free_mark(mark);
-               fsnotify_put_mark(mark);
-       }
-       /*
-        * Some marks can still be pinned when waiting for response from
-        * userspace. Wait for those now. fsnotify_prepare_user_wait() will
-        * not succeed now so this wait is race-free.
-        */
-       wait_event(group->notification_waitq, !atomic_read(&group->user_waits));
-}
-
 /* Destroy all marks attached to inode / vfsmount */
 void fsnotify_destroy_marks(struct fsnotify_mark_connector __rcu **connp)
 {
index d6bbd5a..7287cba 100644 (file)
@@ -208,6 +208,8 @@ struct fsnotify_mark_connector {
        spinlock_t lock;
 #define FSNOTIFY_OBJ_TYPE_INODE                0x01
 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT     0x02
+#define FSNOTIFY_OBJ_ALL_TYPES         (FSNOTIFY_OBJ_TYPE_INODE | \
+                                        FSNOTIFY_OBJ_TYPE_VFSMOUNT)
        unsigned int flags;     /* Type of object [lock] */
        union { /* Object pointer [lock] */
                struct inode *inode;