Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e37c6ca authored by Jan Kara's avatar Jan Kara
Browse files

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: default avatarMiklos Szeredi <mszeredi@redhat.com>
Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 18f2e0d3
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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);

+8 −1
Original line number Diff line number Diff line
@@ -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
+10 −35
Original line number Diff line number Diff line
@@ -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)
{
+2 −0
Original line number Diff line number Diff line
@@ -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;