@@ -152,7 +152,7 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
152152{
153153 struct inode * inode = d_inode (dentry );
154154 struct dentry * parent ;
155- struct inode * p_inode ;
155+ struct inode * p_inode = NULL ;
156156 struct name_snapshot name ;
157157 struct qstr * file_name = NULL ;
158158 int ret = 0 ;
@@ -171,14 +171,13 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
171171 WARN_ON_ONCE (inode != fsnotify_data_inode (data , data_type ));
172172
173173 /* Notify both parent and child with child name info */
174- inode = p_inode ;
175174 take_dentry_name_snapshot (& name , dentry );
176175 file_name = & name .name ;
177176 mask |= FS_EVENT_ON_CHILD ;
178177 }
179178
180179notify :
181- ret = fsnotify (inode , mask , data , data_type , file_name , 0 );
180+ ret = fsnotify (mask , data , data_type , p_inode , file_name , inode , 0 );
182181
183182 if (file_name )
184183 release_dentry_name_snapshot (& name );
@@ -312,18 +311,31 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
312311}
313312
314313/*
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
319332 */
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 )
322335{
323336 const struct path * path = fsnotify_data_path (data , data_type );
324337 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 ;
327339 struct mount * mnt = NULL ;
328340 struct inode * child = NULL ;
329341 int ret = 0 ;
@@ -332,8 +344,18 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type,
332344 if (path )
333345 mnt = real_mount (path -> mnt );
334346
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 ;
337359
338360 /*
339361 * 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,
342364 * SRCU because we have no references to any objects and do not
343365 * need SRCU to keep them "alive".
344366 */
345- if (!to_tell -> i_fsnotify_marks && !sb -> s_fsnotify_marks &&
367+ if (!inode -> i_fsnotify_marks && !sb -> s_fsnotify_marks &&
346368 (!mnt || !mnt -> mnt_fsnotify_marks ) &&
347369 (!child || !child -> i_fsnotify_marks ))
348370 return 0 ;
349371
350- marks_mask = to_tell -> i_fsnotify_mask | sb -> s_fsnotify_mask ;
372+ marks_mask = inode -> i_fsnotify_mask | sb -> s_fsnotify_mask ;
351373 if (mnt )
352374 marks_mask |= mnt -> mnt_fsnotify_mask ;
353375 if (child )
@@ -365,7 +387,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type,
365387 iter_info .srcu_idx = srcu_read_lock (& fsnotify_mark_srcu );
366388
367389 iter_info .marks [FSNOTIFY_OBJ_TYPE_INODE ] =
368- fsnotify_first_mark (& to_tell -> i_fsnotify_marks );
390+ fsnotify_first_mark (& inode -> i_fsnotify_marks );
369391 iter_info .marks [FSNOTIFY_OBJ_TYPE_SB ] =
370392 fsnotify_first_mark (& sb -> s_fsnotify_marks );
371393 if (mnt ) {
0 commit comments