summaryrefslogtreecommitdiffstats
path: root/fs/notify/fsnotify.h
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2016-05-19 17:08:59 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-19 19:12:14 -0700
commit35e481761cdc688dbee0ef552a13f49af8eba6cc (patch)
treef04cadb49418e42a70d4d4b14ebabfb0ca48df8e /fs/notify/fsnotify.h
parent2600a46ee0ed57c0e0a382c2a37ebac64d374d20 (diff)
downloadlinux-stable-35e481761cdc688dbee0ef552a13f49af8eba6cc.tar.gz
linux-stable-35e481761cdc688dbee0ef552a13f49af8eba6cc.tar.bz2
linux-stable-35e481761cdc688dbee0ef552a13f49af8eba6cc.zip
fsnotify: avoid spurious EMFILE errors from inotify_init()
Inotify instance is destroyed when all references to it are dropped. That not only means that the corresponding file descriptor needs to be closed but also that all corresponding instance marks are freed (as each mark holds a reference to the inotify instance). However marks are freed only after SRCU period ends which can take some time and thus if user rapidly creates and frees inotify instances, number of existing inotify instances can exceed max_user_instances limit although from user point of view there is always at most one existing instance. Thus inotify_init() returns EMFILE error which is hard to justify from user point of view. This problem is exposed by LTP inotify06 testcase on some machines. We fix the problem by making sure all group marks are properly freed while destroying inotify instance. We wait for SRCU period to end in that path anyway since we have to make sure there is no event being added to the instance while we are tearing down the instance. So it takes only some plumbing to allow for marks to be destroyed in that path as well and not from a dedicated work item. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Jan Kara <jack@suse.cz> Reported-by: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com> Tested-by: Xiaoguang Wang <wangxg.fnst@cn.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/notify/fsnotify.h')
-rw-r--r--fs/notify/fsnotify.h7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index b44c68a857e7..0a3bc2cf192c 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -56,6 +56,13 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify_marks,
&mnt->mnt_root->d_lock);
}
+/* prepare for freeing all marks associated with given group */
+extern void fsnotify_detach_group_marks(struct fsnotify_group *group);
+/*
+ * wait for fsnotify_mark_srcu period to end and free all marks in destroy_list
+ */
+extern void fsnotify_mark_destroy_list(void);
+
/*
* update the dentry->d_flags of all of inode's children to indicate if inode cares
* about events that happen to its children.