@@ -152,7 +152,7 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
152
152
{
153
153
struct inode * inode = d_inode (dentry );
154
154
struct dentry * parent ;
155
- struct inode * p_inode ;
155
+ struct inode * p_inode = NULL ;
156
156
struct name_snapshot name ;
157
157
struct qstr * file_name = NULL ;
158
158
int ret = 0 ;
@@ -171,14 +171,13 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
171
171
WARN_ON_ONCE (inode != fsnotify_data_inode (data , data_type ));
172
172
173
173
/* Notify both parent and child with child name info */
174
- inode = p_inode ;
175
174
take_dentry_name_snapshot (& name , dentry );
176
175
file_name = & name .name ;
177
176
mask |= FS_EVENT_ON_CHILD ;
178
177
}
179
178
180
179
notify :
181
- ret = fsnotify (inode , mask , data , data_type , file_name , 0 );
180
+ ret = fsnotify (mask , data , data_type , p_inode , file_name , inode , 0 );
182
181
183
182
if (file_name )
184
183
release_dentry_name_snapshot (& name );
@@ -312,18 +311,31 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
312
311
}
313
312
314
313
/*
315
- * This is the main call to fsnotify. The VFS calls into hook specific functions
316
- * in linux/fsnotify.h. Those functions then in turn call here. Here will call
317
- * out to all of the registered fsnotify_group. Those groups can then use the
318
- * notification event in whatever means they feel necessary.
314
+ * fsnotify - This is the main call to fsnotify.
315
+ *
316
+ * The VFS calls into hook specific functions in linux/fsnotify.h.
317
+ * Those functions then in turn call here. Here will call out to all of the
318
+ * registered fsnotify_group. Those groups can then use the notification event
319
+ * in whatever means they feel necessary.
320
+ *
321
+ * @mask: event type and flags
322
+ * @data: object that event happened on
323
+ * @data_type: type of object for fanotify_data_XXX() accessors
324
+ * @dir: optional directory associated with event -
325
+ * if @file_name is not NULL, this is the directory that
326
+ * @file_name is relative to
327
+ * @file_name: optional file name associated with event
328
+ * @inode: optional inode associated with event -
329
+ * either @dir or @inode must be non-NULL.
330
+ * if both are non-NULL event may be reported to both.
331
+ * @cookie: inotify rename cookie
319
332
*/
320
- int fsnotify (struct inode * to_tell , __u32 mask , const void * data , int data_type ,
321
- const struct qstr * file_name , u32 cookie )
333
+ int fsnotify (__u32 mask , const void * data , int data_type , struct inode * dir ,
334
+ const struct qstr * file_name , struct inode * inode , u32 cookie )
322
335
{
323
336
const struct path * path = fsnotify_data_path (data , data_type );
324
337
struct fsnotify_iter_info iter_info = {};
325
- struct super_block * sb = to_tell -> i_sb ;
326
- struct inode * dir = file_name ? to_tell : NULL ;
338
+ struct super_block * sb ;
327
339
struct mount * mnt = NULL ;
328
340
struct inode * child = NULL ;
329
341
int ret = 0 ;
@@ -332,8 +344,18 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type,
332
344
if (path )
333
345
mnt = real_mount (path -> mnt );
334
346
335
- if (mask & FS_EVENT_ON_CHILD )
336
- child = fsnotify_data_inode (data , data_type );
347
+ if (!inode ) {
348
+ /* Dirent event - report on TYPE_INODE to dir */
349
+ inode = dir ;
350
+ } else if (mask & FS_EVENT_ON_CHILD ) {
351
+ /*
352
+ * Event on child - report on TYPE_INODE to dir
353
+ * and on TYPE_CHILD to child.
354
+ */
355
+ child = inode ;
356
+ inode = dir ;
357
+ }
358
+ sb = inode -> i_sb ;
337
359
338
360
/*
339
361
* Optimization: srcu_read_lock() has a memory barrier which can
@@ -342,12 +364,12 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type,
342
364
* SRCU because we have no references to any objects and do not
343
365
* need SRCU to keep them "alive".
344
366
*/
345
- if (!to_tell -> i_fsnotify_marks && !sb -> s_fsnotify_marks &&
367
+ if (!inode -> i_fsnotify_marks && !sb -> s_fsnotify_marks &&
346
368
(!mnt || !mnt -> mnt_fsnotify_marks ) &&
347
369
(!child || !child -> i_fsnotify_marks ))
348
370
return 0 ;
349
371
350
- marks_mask = to_tell -> i_fsnotify_mask | sb -> s_fsnotify_mask ;
372
+ marks_mask = inode -> i_fsnotify_mask | sb -> s_fsnotify_mask ;
351
373
if (mnt )
352
374
marks_mask |= mnt -> mnt_fsnotify_mask ;
353
375
if (child )
@@ -365,7 +387,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type,
365
387
iter_info .srcu_idx = srcu_read_lock (& fsnotify_mark_srcu );
366
388
367
389
iter_info .marks [FSNOTIFY_OBJ_TYPE_INODE ] =
368
- fsnotify_first_mark (& to_tell -> i_fsnotify_marks );
390
+ fsnotify_first_mark (& inode -> i_fsnotify_marks );
369
391
iter_info .marks [FSNOTIFY_OBJ_TYPE_SB ] =
370
392
fsnotify_first_mark (& sb -> s_fsnotify_marks );
371
393
if (mnt ) {
0 commit comments