@@ -260,6 +260,53 @@ static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark)
260
260
return hlist_entry_safe (node , struct fsnotify_mark , obj_list );
261
261
}
262
262
263
+ /*
264
+ * iter_info is a multi head priority queue of marks.
265
+ * Pick a subset of marks from queue heads, all with the
266
+ * same group and set the report_mask for selected subset.
267
+ * Returns the report_mask of the selected subset.
268
+ */
269
+ static unsigned int fsnotify_iter_select_report_types (
270
+ struct fsnotify_iter_info * iter_info )
271
+ {
272
+ struct fsnotify_mark * inode_mark = iter_info -> inode_mark ;
273
+ struct fsnotify_mark * vfsmount_mark = iter_info -> vfsmount_mark ;
274
+ int cmp ;
275
+
276
+ if (!inode_mark && !vfsmount_mark )
277
+ return 0 ;
278
+
279
+ if (inode_mark && vfsmount_mark ) {
280
+ cmp = fsnotify_compare_groups (inode_mark -> group ,
281
+ vfsmount_mark -> group );
282
+ } else {
283
+ cmp = inode_mark ? -1 : 1 ;
284
+ }
285
+
286
+ iter_info -> report_mask = 0 ;
287
+ if (cmp <= 0 )
288
+ iter_info -> report_mask |= FSNOTIFY_OBJ_TYPE_INODE_FL ;
289
+ if (cmp >= 0 )
290
+ iter_info -> report_mask |= FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL ;
291
+
292
+ return iter_info -> report_mask ;
293
+ }
294
+
295
+ /*
296
+ * Pop from iter_info multi head queue, the marks that were iterated in the
297
+ * current iteration step.
298
+ */
299
+ static void fsnotify_iter_next (struct fsnotify_iter_info * iter_info )
300
+ {
301
+ if (iter_info -> report_mask & FSNOTIFY_OBJ_TYPE_INODE_FL )
302
+ iter_info -> inode_mark =
303
+ fsnotify_next_mark (iter_info -> inode_mark );
304
+
305
+ if (iter_info -> report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL )
306
+ iter_info -> vfsmount_mark =
307
+ fsnotify_next_mark (iter_info -> vfsmount_mark );
308
+ }
309
+
263
310
/*
264
311
* This is the main call to fsnotify. The VFS calls into hook specific functions
265
312
* in linux/fsnotify.h. Those functions then in turn call here. Here will call
@@ -321,37 +368,14 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
321
368
* ignore masks are properly reflected for mount mark notifications.
322
369
* That's why this traversal is so complicated...
323
370
*/
324
- while (iter_info .inode_mark || iter_info .vfsmount_mark ) {
325
- struct fsnotify_mark * inode_mark = iter_info .inode_mark ;
326
- struct fsnotify_mark * vfsmount_mark = iter_info .vfsmount_mark ;
327
- int cmp ;
328
-
329
- if (inode_mark && vfsmount_mark ) {
330
- cmp = fsnotify_compare_groups (inode_mark -> group ,
331
- vfsmount_mark -> group );
332
- } else {
333
- cmp = inode_mark ? -1 : 1 ;
334
- }
335
-
336
- iter_info .report_mask = 0 ;
337
- if (cmp <= 0 )
338
- iter_info .report_mask |= FSNOTIFY_OBJ_TYPE_INODE_FL ;
339
- if (cmp >= 0 )
340
- iter_info .report_mask |= FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL ;
341
-
371
+ while (fsnotify_iter_select_report_types (& iter_info )) {
342
372
ret = send_to_group (to_tell , mask , data , data_is , cookie ,
343
373
file_name , & iter_info );
344
374
345
375
if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS ))
346
376
goto out ;
347
377
348
- if (iter_info .report_mask & FSNOTIFY_OBJ_TYPE_INODE_FL )
349
- iter_info .inode_mark =
350
- fsnotify_next_mark (iter_info .inode_mark );
351
-
352
- if (iter_info .report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL )
353
- iter_info .vfsmount_mark =
354
- fsnotify_next_mark (iter_info .vfsmount_mark );
378
+ fsnotify_iter_next (& iter_info );
355
379
}
356
380
ret = 0 ;
357
381
out :
0 commit comments