Commit f09b04a0 authored by Jan Kara's avatar Jan Kara

fsnotify: Remove special handling of mark destruction on group shutdown

Currently we queue all marks for destruction on group shutdown and then
destroy them from fsnotify_destroy_group() instead from a worker thread
which is the usual path. However worker can already be processing some
list of marks to destroy so this does not make 100% all marks are really
destroyed by the time group is shut down. This isn't a big problem as
each mark holds group reference and thus group stays partially alive
until all marks are really freed but there's no point in complicating
our lives - just wait for the delayed work to be finished instead.
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 6b3f05d2
...@@ -36,10 +36,8 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt) ...@@ -36,10 +36,8 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
} }
/* prepare for freeing all marks associated with given group */ /* prepare for freeing all marks associated with given group */
extern void fsnotify_detach_group_marks(struct fsnotify_group *group); extern void fsnotify_detach_group_marks(struct fsnotify_group *group);
/* /* Wait until all marks queued for destruction are destroyed */
* wait for fsnotify_mark_srcu period to end and free all marks in destroy_list extern void fsnotify_wait_marks_destroyed(void);
*/
extern void fsnotify_mark_destroy_list(void);
/* /*
* update the dentry->d_flags of all of inode's children to indicate if inode cares * update the dentry->d_flags of all of inode's children to indicate if inode cares
......
...@@ -66,14 +66,16 @@ void fsnotify_destroy_group(struct fsnotify_group *group) ...@@ -66,14 +66,16 @@ void fsnotify_destroy_group(struct fsnotify_group *group)
*/ */
fsnotify_group_stop_queueing(group); fsnotify_group_stop_queueing(group);
/* clear all inode marks for this group, attach them to destroy_list */ /* Clear all marks for this group and queue them for destruction */
fsnotify_detach_group_marks(group); fsnotify_detach_group_marks(group);
/* /*
* Wait for fsnotify_mark_srcu period to end and free all marks in * Wait until all marks get really destroyed. We could actually destroy
* destroy_list * them ourselves instead of waiting for worker to do it, however that
* would be racy as worker can already be processing some marks before
* we even entered fsnotify_destroy_group().
*/ */
fsnotify_mark_destroy_list(); fsnotify_wait_marks_destroyed();
/* /*
* Since we have waited for fsnotify_mark_srcu in * Since we have waited for fsnotify_mark_srcu in
......
...@@ -703,7 +703,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, ...@@ -703,7 +703,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
* Destroy all marks in destroy_list, waits for SRCU period to finish before * Destroy all marks in destroy_list, waits for SRCU period to finish before
* actually freeing marks. * actually freeing marks.
*/ */
void fsnotify_mark_destroy_list(void) static void fsnotify_mark_destroy_workfn(struct work_struct *work)
{ {
struct fsnotify_mark *mark, *next; struct fsnotify_mark *mark, *next;
struct list_head private_destroy_list; struct list_head private_destroy_list;
...@@ -721,7 +721,8 @@ void fsnotify_mark_destroy_list(void) ...@@ -721,7 +721,8 @@ void fsnotify_mark_destroy_list(void)
} }
} }
static void fsnotify_mark_destroy_workfn(struct work_struct *work) /* Wait for all marks queued for destruction to be actually destroyed */
void fsnotify_wait_marks_destroyed(void)
{ {
fsnotify_mark_destroy_list(); flush_delayed_work(&reaper_work);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment