Skip to content

Commit b54cecf

Browse files
amir73iljankara
authored andcommitted
fsnotify: pass dir argument to handle_event() callback
The 'inode' argument to handle_event(), sometimes referred to as 'to_tell' is somewhat obsolete. It is a remnant from the times when a group could only have an inode mark associated with an event. We now pass an iter_info array to the callback, with all marks associated with an event. Most backends ignore this argument, with two exceptions: 1. dnotify uses it for sanity check that event is on directory 2. fanotify uses it to report fid of directory on directory entry modification events Remove the 'inode' argument and add a 'dir' argument. The callback function signature is deliberately changed, because the meaning of the argument has changed and the arguments have been documented. The 'dir' argument is set to when 'file_name' is specified and it is referring to the directory that the 'file_name' entry belongs to. Signed-off-by: Amir Goldstein <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 9c61f3b commit b54cecf

File tree

11 files changed

+62
-56
lines changed

11 files changed

+62
-56
lines changed

fs/nfsd/filecache.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,9 @@ static struct notifier_block nfsd_file_lease_notifier = {
598598
};
599599

600600
static int
601-
nfsd_file_fsnotify_handle_event(struct fsnotify_group *group,
602-
struct inode *to_tell,
603-
u32 mask, const void *data, int data_type,
601+
nfsd_file_fsnotify_handle_event(struct fsnotify_group *group, u32 mask,
602+
const void *data, int data_type,
603+
struct inode *dir,
604604
const struct qstr *file_name, u32 cookie,
605605
struct fsnotify_iter_info *iter_info)
606606
{

fs/notify/dnotify/dnotify.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
7070
* destroy the dnotify struct if it was not registered to receive multiple
7171
* events.
7272
*/
73-
static int dnotify_handle_event(struct fsnotify_group *group,
74-
struct inode *inode,
75-
u32 mask, const void *data, int data_type,
73+
static int dnotify_handle_event(struct fsnotify_group *group, u32 mask,
74+
const void *data, int data_type,
75+
struct inode *dir,
7676
const struct qstr *file_name, u32 cookie,
7777
struct fsnotify_iter_info *iter_info)
7878
{
@@ -84,7 +84,7 @@ static int dnotify_handle_event(struct fsnotify_group *group,
8484
__u32 test_mask = mask & ~FS_EVENT_ON_CHILD;
8585

8686
/* not a dir, dnotify doesn't care */
87-
if (!S_ISDIR(inode->i_mode))
87+
if (!dir && !(mask & FS_ISDIR))
8888
return 0;
8989

9090
if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))

fs/notify/fanotify/fanotify.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,11 @@ static void fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode,
335335
* FS_ATTRIB reports the child inode even if reported on a watched parent.
336336
* FS_CREATE reports the modified dir inode and not the created inode.
337337
*/
338-
static struct inode *fanotify_fid_inode(struct inode *to_tell, u32 event_mask,
339-
const void *data, int data_type)
338+
static struct inode *fanotify_fid_inode(u32 event_mask, const void *data,
339+
int data_type, struct inode *dir)
340340
{
341341
if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS)
342-
return to_tell;
342+
return dir;
343343

344344
return fsnotify_data_inode(data, data_type);
345345
}
@@ -416,14 +416,14 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id,
416416
}
417417

418418
static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
419-
struct inode *inode, u32 mask,
420-
const void *data, int data_type,
419+
u32 mask, const void *data,
420+
int data_type, struct inode *dir,
421421
const struct qstr *file_name,
422422
__kernel_fsid_t *fsid)
423423
{
424424
struct fanotify_event *event = NULL;
425425
gfp_t gfp = GFP_KERNEL_ACCOUNT;
426-
struct inode *id = fanotify_fid_inode(inode, mask, data, data_type);
426+
struct inode *id = fanotify_fid_inode(mask, data, data_type, dir);
427427
const struct path *path = fsnotify_data_path(data, data_type);
428428

429429
/*
@@ -507,9 +507,9 @@ static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info)
507507
return fsid;
508508
}
509509

510-
static int fanotify_handle_event(struct fsnotify_group *group,
511-
struct inode *inode,
512-
u32 mask, const void *data, int data_type,
510+
static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
511+
const void *data, int data_type,
512+
struct inode *dir,
513513
const struct qstr *file_name, u32 cookie,
514514
struct fsnotify_iter_info *iter_info)
515515
{
@@ -546,8 +546,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
546546
if (!mask)
547547
return 0;
548548

549-
pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
550-
mask);
549+
pr_debug("%s: group=%p mask=%x\n", __func__, group, mask);
551550

552551
if (fanotify_is_perm_event(mask)) {
553552
/*
@@ -565,7 +564,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
565564
return 0;
566565
}
567566

568-
event = fanotify_alloc_event(group, inode, mask, data, data_type,
567+
event = fanotify_alloc_event(group, mask, data, data_type, dir,
569568
file_name, &fsid);
570569
ret = -ENOMEM;
571570
if (unlikely(!event)) {

fs/notify/fsnotify.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,9 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
185185
}
186186
EXPORT_SYMBOL_GPL(__fsnotify_parent);
187187

188-
static int send_to_group(struct inode *to_tell,
189-
__u32 mask, const void *data,
190-
int data_is, u32 cookie,
191-
const struct qstr *file_name,
192-
struct fsnotify_iter_info *iter_info)
188+
static int send_to_group(__u32 mask, const void *data, int data_type,
189+
struct inode *dir, const struct qstr *file_name,
190+
u32 cookie, struct fsnotify_iter_info *iter_info)
193191
{
194192
struct fsnotify_group *group = NULL;
195193
__u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS);
@@ -225,15 +223,14 @@ static int send_to_group(struct inode *to_tell,
225223
}
226224
}
227225

228-
pr_debug("%s: group=%p to_tell=%p mask=%x marks_mask=%x marks_ignored_mask=%x"
229-
" data=%p data_is=%d cookie=%d\n",
230-
__func__, group, to_tell, mask, marks_mask, marks_ignored_mask,
231-
data, data_is, cookie);
226+
pr_debug("%s: group=%p mask=%x marks_mask=%x marks_ignored_mask=%x data=%p data_type=%d dir=%p cookie=%d\n",
227+
__func__, group, mask, marks_mask, marks_ignored_mask,
228+
data, data_type, dir, cookie);
232229

233230
if (!(test_mask & marks_mask & ~marks_ignored_mask))
234231
return 0;
235232

236-
return group->ops->handle_event(group, to_tell, mask, data, data_is,
233+
return group->ops->handle_event(group, mask, data, data_type, dir,
237234
file_name, cookie, iter_info);
238235
}
239236

@@ -317,12 +314,13 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
317314
* out to all of the registered fsnotify_group. Those groups can then use the
318315
* notification event in whatever means they feel necessary.
319316
*/
320-
int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
317+
int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type,
321318
const struct qstr *file_name, u32 cookie)
322319
{
323-
const struct path *path = fsnotify_data_path(data, data_is);
320+
const struct path *path = fsnotify_data_path(data, data_type);
324321
struct fsnotify_iter_info iter_info = {};
325322
struct super_block *sb = to_tell->i_sb;
323+
struct inode *dir = file_name ? to_tell : NULL;
326324
struct mount *mnt = NULL;
327325
int ret = 0;
328326
__u32 test_mask, marks_mask;
@@ -375,8 +373,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
375373
* That's why this traversal is so complicated...
376374
*/
377375
while (fsnotify_iter_select_report_types(&iter_info)) {
378-
ret = send_to_group(to_tell, mask, data, data_is, cookie,
379-
file_name, &iter_info);
376+
ret = send_to_group(mask, data, data_type, dir, file_name,
377+
cookie, &iter_info);
380378

381379
if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
382380
goto out;

fs/notify/inotify/inotify.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ static inline struct inotify_event_info *INOTIFY_E(struct fsnotify_event *fse)
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,
28-
struct inode *inode,
29-
u32 mask, const void *data, int data_type,
27+
extern int inotify_handle_event(struct fsnotify_group *group, u32 mask,
28+
const void *data, int data_type,
29+
struct inode *dir,
3030
const struct qstr *file_name, u32 cookie,
3131
struct fsnotify_iter_info *iter_info);
3232

fs/notify/inotify/inotify_fsnotify.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ static int inotify_merge(struct list_head *list,
5555
return event_compare(last_event, event);
5656
}
5757

58-
int inotify_handle_event(struct fsnotify_group *group,
59-
struct inode *inode,
60-
u32 mask, const void *data, int data_type,
58+
int inotify_handle_event(struct fsnotify_group *group, u32 mask,
59+
const void *data, int data_type, struct inode *dir,
6160
const struct qstr *file_name, u32 cookie,
6261
struct fsnotify_iter_info *iter_info)
6362
{
@@ -82,7 +81,7 @@ int inotify_handle_event(struct fsnotify_group *group,
8281
alloc_len += len + 1;
8382
}
8483

85-
pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
84+
pr_debug("%s: group=%p mark=%p mask=%x\n", __func__, group, inode_mark,
8685
mask);
8786

8887
i_mark = container_of(inode_mark, struct inotify_inode_mark,

fs/notify/inotify/inotify_user.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,8 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
490490
fsn_mark);
491491

492492
/* Queue ignore event for the watch */
493-
inotify_handle_event(group, NULL, FS_IN_IGNORED, NULL,
494-
FSNOTIFY_EVENT_NONE, NULL, 0, &iter_info);
493+
inotify_handle_event(group, FS_IN_IGNORED, NULL, FSNOTIFY_EVENT_NONE,
494+
NULL, NULL, 0, &iter_info);
495495

496496
i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
497497
/* remove this mark from the idr */

include/linux/fsnotify_backend.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,26 @@ struct mem_cgroup;
108108
* these operations for each relevant group.
109109
*
110110
* handle_event - main call for a group to handle an fs event
111+
* @group: group to notify
112+
* @mask: event type and flags
113+
* @data: object that event happened on
114+
* @data_type: type of object for fanotify_data_XXX() accessors
115+
* @dir: optional directory associated with event -
116+
* if @file_name is not NULL, this is the directory that
117+
* @file_name is relative to
118+
* @file_name: optional file name associated with event
119+
* @cookie: inotify rename cookie
120+
* @iter_info: array of marks from this group that are interested in the event
121+
*
111122
* free_group_priv - called when a group refcnt hits 0 to clean up the private union
112123
* freeing_mark - called when a mark is being destroyed for some reason. The group
113124
* MUST be holding a reference on each mark and that reference must be
114125
* dropped in this function. inotify uses this function to send
115126
* userspace messages that marks have been removed.
116127
*/
117128
struct fsnotify_ops {
118-
int (*handle_event)(struct fsnotify_group *group,
119-
struct inode *inode,
120-
u32 mask, const void *data, int data_type,
129+
int (*handle_event)(struct fsnotify_group *group, u32 mask,
130+
const void *data, int data_type, struct inode *dir,
121131
const struct qstr *file_name, u32 cookie,
122132
struct fsnotify_iter_info *iter_info);
123133
void (*free_group_priv)(struct fsnotify_group *group);

kernel/audit_fsnotify.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ static void audit_autoremove_mark_rule(struct audit_fsnotify_mark *audit_mark)
152152
}
153153

154154
/* Update mark data in audit rules based on fsnotify events. */
155-
static int audit_mark_handle_event(struct fsnotify_group *group,
156-
struct inode *to_tell,
157-
u32 mask, const void *data, int data_type,
158-
const struct qstr *dname, u32 cookie,
159-
struct fsnotify_iter_info *iter_info)
155+
static int audit_mark_handle_event(struct fsnotify_group *group, u32 mask,
156+
const void *data, int data_type,
157+
struct inode *dir,
158+
const struct qstr *dname, u32 cookie,
159+
struct fsnotify_iter_info *iter_info)
160160
{
161161
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
162162
struct audit_fsnotify_mark *audit_mark;

kernel/audit_tree.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,9 +1037,9 @@ static void evict_chunk(struct audit_chunk *chunk)
10371037
audit_schedule_prune();
10381038
}
10391039

1040-
static int audit_tree_handle_event(struct fsnotify_group *group,
1041-
struct inode *to_tell,
1042-
u32 mask, const void *data, int data_type,
1040+
static int audit_tree_handle_event(struct fsnotify_group *group, u32 mask,
1041+
const void *data, int data_type,
1042+
struct inode *dir,
10431043
const struct qstr *file_name, u32 cookie,
10441044
struct fsnotify_iter_info *iter_info)
10451045
{

0 commit comments

Comments
 (0)