History

Merge tag 'fsnotify_for_v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull fsnotify updates from Jan Kara: "A few fsnotify fixes from Amir fixing fallout from big fsnotify overhaul a few months back and an improvement of defaults limiting maximum number of inotify watches from Waiman" * tag 'fsnotify_for_v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fsnotify: fix events reported to watching parent and child inotify: convert to handle_inode_event() interface fsnotify: generalize handle_inode_event() inotify: Increase default inotify.max_user_watches limit to 1048576

Linus Torvalds committed 5 years ago

Commit 14bd41e2 parents d652d5f fecc45511 files · +120 −104Browse files

Unified · Split

11 files
  1. fs/nfsd/filecache.c +1 −1
  2. fs/notify/dnotify/dnotify.c +1 −1
  3. fs/notify/fanotify/fanotify.c +3 −4
  4. fs/notify/fsnotify.c +71 −36
  5. fs/notify/inotify/inotify.h +4 −5
  6. fs/notify/inotify/inotify_fsnotify.c +8 −43
  7. fs/notify/inotify/inotify_user.c +24 −7
  8. include/linux/fsnotify_backend.h +5 −4
  9. kernel/audit_fsnotify.c +1 −1
  10. kernel/audit_tree.c +1 −1
  11. kernel/audit_watch.c +1 −1
fs/nfsd/filecache.c+1−1
@@ -600,7 +600,7 @@ static struct notifier_block nfsd_file_lease_notifier = { · 599 unmodified lines
600600 static int
601601 nfsd_file_fsnotify_handle_event(struct fsnotify_mark *mark, u32 mask,
602602 struct inode *inode, struct inode *dir,
603− const struct qstr *name)
603+ const struct qstr *name, u32 cookie)
604604 {
605605 trace_nfsd_file_fsnotify_handle_event(inode, mask);
606606
fs/notify/dnotify/dnotify.c+1−1
@@ -72,7 +72,7 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) · 71 unmodified lines
7272 */
7373 static int dnotify_handle_event(struct fsnotify_mark *inode_mark, u32 mask,
7474 struct inode *inode, struct inode *dir,
75− const struct qstr *name)
75+ const struct qstr *name, u32 cookie)
7676 {
7777 struct dnotify_mark *dn_mark;
7878 struct dnotify_struct *dn;
fs/notify/fanotify/fanotify.c+3−4
@@ -268,12 +268,11 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, · 267 unmodified lines
268268 continue;
269269
270270 /*
271− * If the event is for a child and this mark is on a parent not
271+ * If the event is on a child and this mark is on a parent not
272272 * watching children, don't send it!
273273 */
274− if (event_mask & FS_EVENT_ON_CHILD &&
275− type == FSNOTIFY_OBJ_TYPE_INODE &&
276− !(mark->mask & FS_EVENT_ON_CHILD))
274+ if (type == FSNOTIFY_OBJ_TYPE_PARENT &&
275+ !(mark->mask & FS_EVENT_ON_CHILD))
277276 continue;
278277
279278 marks_mask |= mark->mask;
fs/notify/fsnotify.c+71−36
@@ -152,6 +152,13 @@ static bool fsnotify_event_needs_parent(struct inode *inode, struct mount *mnt, · 151 unmodified lines
152152 if (mask & FS_ISDIR)
153153 return false;
154154
155+ /*
156+ * All events that are possible on child can also may be reported with
157+ * parent/name info to inode/sb/mount. Otherwise, a watching parent
158+ * could result in events reported with unexpected name info to sb/mount.
159+ */
160+ BUILD_BUG_ON(FS_EVENTS_POSS_ON_CHILD & ~FS_EVENTS_POSS_TO_PARENT);
161+
155162 /* Did either inode/sb/mount subscribe for events with parent/name? */
156163 marks_mask |= fsnotify_parent_needed_mask(inode->i_fsnotify_mask);
157164 marks_mask |= fsnotify_parent_needed_mask(inode->i_sb->s_fsnotify_mask);
@@ -232,47 +239,76 @@ notify: · 74 unmodified lines
232239 }
233240 EXPORT_SYMBOL_GPL(__fsnotify_parent);
234241
242+static int fsnotify_handle_inode_event(struct fsnotify_group *group,
243+ struct fsnotify_mark *inode_mark,
244+ u32 mask, const void *data, int data_type,
245+ struct inode *dir, const struct qstr *name,
246+ u32 cookie)
247+{
248+ const struct path *path = fsnotify_data_path(data, data_type);
249+ struct inode *inode = fsnotify_data_inode(data, data_type);
250+ const struct fsnotify_ops *ops = group->ops;
251+
252+ if (WARN_ON_ONCE(!ops->handle_inode_event))
253+ return 0;
254+
255+ if ((inode_mark->mask & FS_EXCL_UNLINK) &&
256+ path && d_unlinked(path->dentry))
257+ return 0;
258+
259+ /* Check interest of this mark in case event was sent with two marks */
260+ if (!(mask & inode_mark->mask & ALL_FSNOTIFY_EVENTS))
261+ return 0;
262+
263+ return ops->handle_inode_event(inode_mark, mask, inode, dir, name, cookie);
264+}
265+
235266 static int fsnotify_handle_event(struct fsnotify_group *group, __u32 mask,
236267 const void *data, int data_type,
237268 struct inode *dir, const struct qstr *name,
238269 u32 cookie, struct fsnotify_iter_info *iter_info)
239270 {
240271 struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
241− struct fsnotify_mark *child_mark = fsnotify_iter_child_mark(iter_info);
242− struct inode *inode = fsnotify_data_inode(data, data_type);
243− const struct fsnotify_ops *ops = group->ops;
272+ struct fsnotify_mark *parent_mark = fsnotify_iter_parent_mark(iter_info);
244273 int ret;
245274
246− if (WARN_ON_ONCE(!ops->handle_inode_event))
247− return 0;
248−
249275 if (WARN_ON_ONCE(fsnotify_iter_sb_mark(iter_info)) ||
250276 WARN_ON_ONCE(fsnotify_iter_vfsmount_mark(iter_info)))
251277 return 0;
252278
253− /*
254− * An event can be sent on child mark iterator instead of inode mark
255− * iterator because of other groups that have interest of this inode
256− * and have marks on both parent and child. We can simplify this case.
257− */
258− if (!inode_mark) {
259− inode_mark = child_mark;
260− child_mark = NULL;
279+ if (parent_mark) {
280+ /*
281+ * parent_mark indicates that the parent inode is watching
282+ * children and interested in this event, which is an event
283+ * possible on child. But is *this mark* watching children and
284+ * interested in this event?
285+ */
286+ if (parent_mark->mask & FS_EVENT_ON_CHILD) {
287+ ret = fsnotify_handle_inode_event(group, parent_mark, mask,
288+ data, data_type, dir, name, 0);
289+ if (ret)
290+ return ret;
291+ }
292+ if (!inode_mark)
293+ return 0;
294+ }
295+
296+ if (mask & FS_EVENT_ON_CHILD) {
297+ /*
298+ * Some events can be sent on both parent dir and child marks
299+ * (e.g. FS_ATTRIB). If both parent dir and child are
300+ * watching, report the event once to parent dir with name (if
301+ * interested) and once to child without name (if interested).
302+ * The child watcher is expecting an event without a file name
303+ * and without the FS_EVENT_ON_CHILD flag.
304+ */
305+ mask &= ~FS_EVENT_ON_CHILD;
261306 dir = NULL;
262307 name = NULL;
263308 }
264309
265− ret = ops->handle_inode_event(inode_mark, mask, inode, dir, name);
266− if (ret || !child_mark)
267− return ret;
268−
269− /*
270− * Some events can be sent on both parent dir and child marks
271− * (e.g. FS_ATTRIB). If both parent dir and child are watching,
272− * report the event once to parent dir with name and once to child
273− * without name.
274− */
275− return ops->handle_inode_event(child_mark, mask, inode, NULL, NULL);
310+ return fsnotify_handle_inode_event(group, inode_mark, mask, data, data_type,
311+ dir, name, cookie);
276312 }
277313
278314 static int send_to_group(__u32 mask, const void *data, int data_type,
@@ -430,7 +466,7 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, · 151 unmodified lines
430466 struct fsnotify_iter_info iter_info = {};
431467 struct super_block *sb;
432468 struct mount *mnt = NULL;
433− struct inode *child = NULL;
469+ struct inode *parent = NULL;
434470 int ret = 0;
435471 __u32 test_mask, marks_mask;
436472
@@ -442,11 +478,10 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, · 5 unmodified lines
442478 inode = dir;
443479 } else if (mask & FS_EVENT_ON_CHILD) {
444480 /*
445− * Event on child - report on TYPE_INODE to dir if it is
446− * watching children and on TYPE_CHILD to child.
481+ * Event on child - report on TYPE_PARENT to dir if it is
482+ * watching children and on TYPE_INODE to child.
447483 */
448− child = inode;
449− inode = dir;
484+ parent = dir;
450485 }
451486 sb = inode->i_sb;
452487
@@ -460,7 +495,7 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, · 7 unmodified lines
460495 if (!sb->s_fsnotify_marks &&
461496 (!mnt || !mnt->mnt_fsnotify_marks) &&
462497 (!inode || !inode->i_fsnotify_marks) &&
463− (!child || !child->i_fsnotify_marks))
498+ (!parent || !parent->i_fsnotify_marks))
464499 return 0;
465500
466501 marks_mask = sb->s_fsnotify_mask;
@@ -468,8 +503,8 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, · 1 unmodified line
468503 marks_mask |= mnt->mnt_fsnotify_mask;
469504 if (inode)
470505 marks_mask |= inode->i_fsnotify_mask;
471− if (child)
472− marks_mask |= child->i_fsnotify_mask;
506+ if (parent)
507+ marks_mask |= parent->i_fsnotify_mask;
473508
474509
475510 /*
@@ -492,9 +527,9 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, · 16 unmodified lines
492527 iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
493528 fsnotify_first_mark(&inode->i_fsnotify_marks);
494529 }
495− if (child) {
496− iter_info.marks[FSNOTIFY_OBJ_TYPE_CHILD] =
497− fsnotify_first_mark(&child->i_fsnotify_marks);
530+ if (parent) {
531+ iter_info.marks[FSNOTIFY_OBJ_TYPE_PARENT] =
532+ fsnotify_first_mark(&parent->i_fsnotify_marks);
498533 }
499534
500535 /*
fs/notify/inotify/inotify.h+4−5
@@ -24,11 +24,10 @@ static inline struct inotify_event_info *INOTIFY_E(struct fsnotify_event *fse) · 23 unmodified lines
2424
2525 extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
2626 struct fsnotify_group *group);
27−extern int inotify_handle_event(struct fsnotify_group *group, u32 mask,
28− const void *data, int data_type,
29− struct inode *dir,
30− const struct qstr *file_name, u32 cookie,
31− struct fsnotify_iter_info *iter_info);
27+extern int inotify_handle_inode_event(struct fsnotify_mark *inode_mark,
28+ u32 mask, struct inode *inode,
29+ struct inode *dir,
30+ const struct qstr *name, u32 cookie);
3231
3332 extern const struct fsnotify_ops inotify_fsnotify_ops;
3433 extern struct kmem_cache *inotify_inode_mark_cachep;
fs/notify/inotify/inotify_fsnotify.c+8−43
@@ -55,25 +55,21 @@ static int inotify_merge(struct list_head *list, · 54 unmodified lines
5555 return event_compare(last_event, event);
5656 }
5757
58−static int inotify_one_event(struct fsnotify_group *group, u32 mask,
59− struct fsnotify_mark *inode_mark,
60− const struct path *path,
61− const struct qstr *file_name, u32 cookie)
58+int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
59+ struct inode *inode, struct inode *dir,
60+ const struct qstr *name, u32 cookie)
6261 {
6362 struct inotify_inode_mark *i_mark;
6463 struct inotify_event_info *event;
6564 struct fsnotify_event *fsn_event;
65+ struct fsnotify_group *group = inode_mark->group;
6666 int ret;
6767 int len = 0;
6868 int alloc_len = sizeof(struct inotify_event_info);
6969 struct mem_cgroup *old_memcg;
7070
71− if ((inode_mark->mask & FS_EXCL_UNLINK) &&
72− path && d_unlinked(path->dentry))
73− return 0;
74−
75− if (file_name) {
76− len = file_name->len;
71+ if (name) {
72+ len = name->len;
7773 alloc_len += len + 1;
7874 }
7975
@@ -117,7 +113,7 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask, · 37 unmodified lines
117113 event->sync_cookie = cookie;
118114 event->name_len = len;
119115 if (len)
120− strcpy(event->name, file_name->name);
116+ strcpy(event->name, name->name);
121117
122118 ret = fsnotify_add_event(group, fsn_event, inotify_merge);
123119 if (ret) {
@@ -131,37 +127,6 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask, · 7 unmodified lines
131127 return 0;
132128 }
133129
134−int inotify_handle_event(struct fsnotify_group *group, u32 mask,
135− const void *data, int data_type, struct inode *dir,
136− const struct qstr *file_name, u32 cookie,
137− struct fsnotify_iter_info *iter_info)
138−{
139− const struct path *path = fsnotify_data_path(data, data_type);
140− struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
141− struct fsnotify_mark *child_mark = fsnotify_iter_child_mark(iter_info);
142− int ret = 0;
143−
144− if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
145− return 0;
146−
147− /*
148− * Some events cannot be sent on both parent and child marks
149− * (e.g. IN_CREATE). Those events are always sent on inode_mark.
150− * For events that are possible on both parent and child (e.g. IN_OPEN),
151− * event is sent on inode_mark with name if the parent is watching and
152− * is sent on child_mark without name if child is watching.
153− * If both parent and child are watching, report the event with child's
154− * name here and report another event without child's name below.
155− */
156− if (inode_mark)
157− ret = inotify_one_event(group, mask, inode_mark, path,
158− file_name, cookie);
159− if (ret || !child_mark)
160− return ret;
161−
162− return inotify_one_event(group, mask, child_mark, path, NULL, 0);
163−}
164−
165130 static void inotify_freeing_mark(struct fsnotify_mark *fsn_mark, struct fsnotify_group *group)
166131 {
167132 inotify_ignored_and_remove_idr(fsn_mark, group);
@@ -227,7 +192,7 @@ static void inotify_free_mark(struct fsnotify_mark *fsn_mark) · 59 unmodified lines
227192 }
228193
229194 const struct fsnotify_ops inotify_fsnotify_ops = {
230− .handle_event = inotify_handle_event,
195+ .handle_inode_event = inotify_handle_inode_event,
231196 .free_group_priv = inotify_free_group_priv,
232197 .free_event = inotify_free_event,
233198 .freeing_mark = inotify_freeing_mark,
fs/notify/inotify/inotify_user.c+24−7
@@ -37,6 +37,15 @@ · 36 unmodified lines
3737
3838 #include <asm/ioctls.h>
3939
40+/*
41+ * An inotify watch requires allocating an inotify_inode_mark structure as
42+ * well as pinning the watched inode. Doubling the size of a VFS inode
43+ * should be more than enough to cover the additional filesystem inode
44+ * size increase.
45+ */
46+#define INOTIFY_WATCH_COST (sizeof(struct inotify_inode_mark) + \
47+ 2 * sizeof(struct inode))
48+
4049 /* configurable via /proc/sys/fs/inotify/ */
4150 static int inotify_max_queued_events __read_mostly;
4251
@@ -486,14 +495,10 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, · 443 unmodified lines
486495 struct fsnotify_group *group)
487496 {
488497 struct inotify_inode_mark *i_mark;
489− struct fsnotify_iter_info iter_info = { };
490−
491− fsnotify_iter_set_report_type_mark(&iter_info, FSNOTIFY_OBJ_TYPE_INODE,
492− fsn_mark);
493498
494499 /* Queue ignore event for the watch */
495− inotify_handle_event(group, FS_IN_IGNORED, NULL, FSNOTIFY_EVENT_NONE,
496− NULL, NULL, 0, &iter_info);
500+ inotify_handle_inode_event(fsn_mark, FS_IN_IGNORED, NULL, NULL, NULL,
501+ 0);
497502
498503 i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
499504 /* remove this mark from the idr */
@@ -801,6 +806,18 @@ out: · 301 unmodified lines
801806 */
802807 static int __init inotify_user_setup(void)
803808 {
809+ unsigned long watches_max;
810+ struct sysinfo si;
811+
812+ si_meminfo(&si);
813+ /*
814+ * Allow up to 1% of addressable memory to be allocated for inotify
815+ * watches (per user) limited to the range [8192, 1048576].
816+ */
817+ watches_max = (((si.totalram - si.totalhigh) / 100) << PAGE_SHIFT) /
818+ INOTIFY_WATCH_COST;
819+ watches_max = clamp(watches_max, 8192UL, 1048576UL);
820+
804821 BUILD_BUG_ON(IN_ACCESS != FS_ACCESS);
805822 BUILD_BUG_ON(IN_MODIFY != FS_MODIFY);
806823 BUILD_BUG_ON(IN_ATTRIB != FS_ATTRIB);
@@ -827,7 +844,7 @@ static int __init inotify_user_setup(void) · 20 unmodified lines
827844
828845 inotify_max_queued_events = 16384;
829846 init_user_ns.ucount_max[UCOUNT_INOTIFY_INSTANCES] = 128;
830− init_user_ns.ucount_max[UCOUNT_INOTIFY_WATCHES] = 8192;
847+ init_user_ns.ucount_max[UCOUNT_INOTIFY_WATCHES] = watches_max;
831848
832849 return 0;
833850 }
include/linux/fsnotify_backend.h+5−4
@@ -137,6 +137,7 @@ struct mem_cgroup; · 136 unmodified lines
137137 * if @file_name is not NULL, this is the directory that
138138 * @file_name is relative to.
139139 * @file_name: optional file name associated with event
140+ * @cookie: inotify rename cookie
140141 *
141142 * free_group_priv - called when a group refcnt hits 0 to clean up the private union
142143 * freeing_mark - called when a mark is being destroyed for some reason. The group
@@ -151,7 +152,7 @@ struct fsnotify_ops { · 8 unmodified lines
151152 struct fsnotify_iter_info *iter_info);
152153 int (*handle_inode_event)(struct fsnotify_mark *mark, u32 mask,
153154 struct inode *inode, struct inode *dir,
154− const struct qstr *file_name);
155+ const struct qstr *file_name, u32 cookie);
155156 void (*free_group_priv)(struct fsnotify_group *group);
156157 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);
157158 void (*free_event)(struct fsnotify_event *event);
@@ -277,7 +278,7 @@ static inline const struct path *fsnotify_data_path(const void *data, · 119 unmodified lines
277278
278279 enum fsnotify_obj_type {
279280 FSNOTIFY_OBJ_TYPE_INODE,
280− FSNOTIFY_OBJ_TYPE_CHILD,
281+ FSNOTIFY_OBJ_TYPE_PARENT,
281282 FSNOTIFY_OBJ_TYPE_VFSMOUNT,
282283 FSNOTIFY_OBJ_TYPE_SB,
283284 FSNOTIFY_OBJ_TYPE_COUNT,
@@ -285,7 +286,7 @@ enum fsnotify_obj_type { · 1 unmodified line
285286 };
286287
287288 #define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE)
288−#define FSNOTIFY_OBJ_TYPE_CHILD_FL (1U << FSNOTIFY_OBJ_TYPE_CHILD)
289+#define FSNOTIFY_OBJ_TYPE_PARENT_FL (1U << FSNOTIFY_OBJ_TYPE_PARENT)
289290 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
290291 #define FSNOTIFY_OBJ_TYPE_SB_FL (1U << FSNOTIFY_OBJ_TYPE_SB)
291292 #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
@@ -330,7 +331,7 @@ static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \ · 38 unmodified lines
330331 }
331332
332333 FSNOTIFY_ITER_FUNCS(inode, INODE)
333−FSNOTIFY_ITER_FUNCS(child, CHILD)
334+FSNOTIFY_ITER_FUNCS(parent, PARENT)
334335 FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
335336 FSNOTIFY_ITER_FUNCS(sb, SB)
336337
kernel/audit_fsnotify.c+1−1
@@ -154,7 +154,7 @@ static void audit_autoremove_mark_rule(struct audit_fsnotify_mark *audit_mark) · 153 unmodified lines
154154 /* Update mark data in audit rules based on fsnotify events. */
155155 static int audit_mark_handle_event(struct fsnotify_mark *inode_mark, u32 mask,
156156 struct inode *inode, struct inode *dir,
157− const struct qstr *dname)
157+ const struct qstr *dname, u32 cookie)
158158 {
159159 struct audit_fsnotify_mark *audit_mark;
160160
kernel/audit_tree.c+1−1
@@ -1037,7 +1037,7 @@ static void evict_chunk(struct audit_chunk *chunk) · 1036 unmodified lines
10371037
10381038 static int audit_tree_handle_event(struct fsnotify_mark *mark, u32 mask,
10391039 struct inode *inode, struct inode *dir,
1040− const struct qstr *file_name)
1040+ const struct qstr *file_name, u32 cookie)
10411041 {
10421042 return 0;
10431043 }
kernel/audit_watch.c+1−1
@@ -466,7 +466,7 @@ void audit_remove_watch_rule(struct audit_krule *krule) · 465 unmodified lines
466466 /* Update watch data in audit rules based on fsnotify events. */
467467 static int audit_watch_handle_event(struct fsnotify_mark *inode_mark, u32 mask,
468468 struct inode *inode, struct inode *dir,
469− const struct qstr *dname)
469+ const struct qstr *dname, u32 cookie)
470470 {
471471 struct audit_parent *parent;
472472

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t