From 8bc1afd1e148e6bde2f3b64f8c86b386c23c0fd5 Mon Sep 17 00:00:00 2001 From: sanfilippo Date: Fri, 25 Jan 2013 06:10:32 +0100 Subject: [PATCH] fsnotify, inotify: call destroy_group() in [inotify|fanotify]_release() Clearing marks and putting the group in inotify_release() is not enough. We also have to make sure that the events queue is flushed (since each event holds a ref on an inotify group a group would never be freed otherwise). The same applies for fanotify_release(). In both functions, call fsnotify_destroy() which does the proper work for us. Signed-off-by: Lino Sanfilippo --- fs/notify/fanotify/fanotify_user.c | 2 +- fs/notify/group.c | 2 +- fs/notify/inotify/inotify_user.c | 4 +--- include/linux/fsnotify_backend.h | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index c90fb15..e69124b4 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -417,7 +417,7 @@ static int fanotify_release(struct inode *ignored, struct file *file) wake_up(&group->fanotify_data.access_waitq); #endif /* matches the fanotify_init->fsnotify_alloc_group */ - fsnotify_put_group(group); + fsnotify_destroy_group(group); return 0; } diff --git a/fs/notify/group.c b/fs/notify/group.c index c89fcb2..2d47100 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -46,7 +46,7 @@ void fsnotify_final_destroy_group(struct fsnotify_group *group) * Note that another thread calling fsnotify_clear_marks_by_group() may still * hold a ref to the group. */ -static void fsnotify_destroy_group(struct fsnotify_group *group) +void fsnotify_destroy_group(struct fsnotify_group *group) { /* clear all inode marks for this group */ fsnotify_clear_marks_by_group(group); diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 2f61c6a..a37fe41 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -293,10 +293,8 @@ static int inotify_release(struct inode *ignored, struct file *file) pr_debug("%s: group=%p\n", __func__, group); - fsnotify_clear_marks_by_group(group); - /* free this group, matching get was inotify_init->fsnotify_obtain_group */ - fsnotify_put_group(group); + fsnotify_destroy_group(group); return 0; } diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index e18bb0a..2ec3fb8 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -366,7 +366,8 @@ extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *op extern void fsnotify_get_group(struct fsnotify_group *group); /* drop reference on a group from fsnotify_alloc_group */ extern void fsnotify_put_group(struct fsnotify_group *group); - +/* destroy group */ +extern void fsnotify_destroy_group(struct fsnotify_group *group); /* take a reference to an event */ extern void fsnotify_get_event(struct fsnotify_event *event); extern void fsnotify_put_event(struct fsnotify_event *event); -- 1.7.9.5