Skip to content

Commit

Permalink
fsnotify: remove redundant arguments to handle_event()
Browse files Browse the repository at this point in the history
inode_mark and vfsmount_mark arguments are passed to handle_event()
operation as function arguments as well as on iter_info struct.
The difference is that iter_info struct may contain marks that should
not be handled and are represented as NULL arguments to inode_mark or
vfsmount_mark.

Instead of passing the inode_mark and vfsmount_mark arguments, add
a report_mask member to iter_info struct to indicate which marks should
be handled, versus marks that should only be kept alive during user
wait.

This change is going to be used for passing more mark types
with handle_event() (i.e. super block marks).

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
  • Loading branch information
amir73il authored and jankara committed May 18, 2018
1 parent d6f7b98 commit 5b0457a
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 50 deletions.
6 changes: 3 additions & 3 deletions fs/notify/dnotify/dnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,11 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
*/
static int dnotify_handle_event(struct fsnotify_group *group,
struct inode *inode,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
u32 mask, const void *data, int data_type,
const unsigned char *file_name, u32 cookie,
struct fsnotify_iter_info *iter_info)
{
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
struct dnotify_mark *dn_mark;
struct dnotify_struct *dn;
struct dnotify_struct **prev;
Expand All @@ -95,7 +94,8 @@ static int dnotify_handle_event(struct fsnotify_group *group,
if (!S_ISDIR(inode->i_mode))
return 0;

BUG_ON(vfsmount_mark);
if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
return 0;

dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark);

Expand Down
14 changes: 6 additions & 8 deletions fs/notify/fanotify/fanotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ static int fanotify_get_response(struct fsnotify_group *group,
return ret;
}

static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmnt_mark,
u32 event_mask,
const void *data, int data_type)
static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
u32 event_mask, const void *data,
int data_type)
{
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
struct fsnotify_mark *vfsmnt_mark = fsnotify_iter_vfsmount_mark(iter_info);
__u32 marks_mask = 0, marks_ignored_mask = 0;
const struct path *path = data;

Expand Down Expand Up @@ -178,8 +179,6 @@ init: __maybe_unused

static int fanotify_handle_event(struct fsnotify_group *group,
struct inode *inode,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *fanotify_mark,
u32 mask, const void *data, int data_type,
const unsigned char *file_name, u32 cookie,
struct fsnotify_iter_info *iter_info)
Expand All @@ -199,8 +198,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);

if (!fanotify_should_send_event(inode_mark, fanotify_mark, mask, data,
data_type))
if (!fanotify_should_send_event(iter_info, mask, data, data_type))
return 0;

pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
Expand Down
38 changes: 20 additions & 18 deletions fs/notify/fsnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,22 +184,20 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask
EXPORT_SYMBOL_GPL(__fsnotify_parent);

static int send_to_group(struct inode *to_tell,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
__u32 mask, const void *data,
int data_is, u32 cookie,
const unsigned char *file_name,
struct fsnotify_iter_info *iter_info)
{
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
struct fsnotify_mark *vfsmount_mark = fsnotify_iter_vfsmount_mark(iter_info);
struct fsnotify_group *group = NULL;
__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
__u32 marks_mask = 0;
__u32 marks_ignored_mask = 0;

if (unlikely(!inode_mark && !vfsmount_mark)) {
BUG();
if (WARN_ON(!iter_info->report_mask))
return 0;
}

/* clear ignored on inode modification */
if (mask & FS_MODIFY) {
Expand Down Expand Up @@ -235,8 +233,7 @@ static int send_to_group(struct inode *to_tell,
if (!(test_mask & marks_mask & ~marks_ignored_mask))
return 0;

return group->ops->handle_event(group, to_tell, inode_mark,
vfsmount_mark, mask, data, data_is,
return group->ops->handle_event(group, to_tell, mask, data, data_is,
file_name, cookie, iter_info);
}

Expand Down Expand Up @@ -327,27 +324,32 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
while (iter_info.inode_mark || iter_info.vfsmount_mark) {
struct fsnotify_mark *inode_mark = iter_info.inode_mark;
struct fsnotify_mark *vfsmount_mark = iter_info.vfsmount_mark;
int cmp;

if (inode_mark && vfsmount_mark) {
int cmp = fsnotify_compare_groups(inode_mark->group,
vfsmount_mark->group);
if (cmp > 0)
inode_mark = NULL;
else if (cmp < 0)
vfsmount_mark = NULL;
cmp = fsnotify_compare_groups(inode_mark->group,
vfsmount_mark->group);
} else {
cmp = inode_mark ? -1 : 1;
}

ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask,
data, data_is, cookie, file_name,
&iter_info);
iter_info.report_mask = 0;
if (cmp <= 0)
iter_info.report_mask |= FSNOTIFY_OBJ_TYPE_INODE_FL;
if (cmp >= 0)
iter_info.report_mask |= FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL;

ret = send_to_group(to_tell, mask, data, data_is, cookie,
file_name, &iter_info);

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

if (inode_mark)
if (iter_info.report_mask & FSNOTIFY_OBJ_TYPE_INODE_FL)
iter_info.inode_mark =
fsnotify_next_mark(iter_info.inode_mark);
if (vfsmount_mark)

if (iter_info.report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL)
iter_info.vfsmount_mark =
fsnotify_next_mark(iter_info.vfsmount_mark);
}
Expand Down
6 changes: 0 additions & 6 deletions fs/notify/fsnotify.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@

#include "../mount.h"

struct fsnotify_iter_info {
struct fsnotify_mark *inode_mark;
struct fsnotify_mark *vfsmount_mark;
int srcu_idx;
};

/* destroy all events sitting in this groups notification queue */
extern void fsnotify_flush_notify(struct fsnotify_group *group);

Expand Down
2 changes: 0 additions & 2 deletions fs/notify/inotify/inotify.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
struct fsnotify_group *group);
extern int inotify_handle_event(struct fsnotify_group *group,
struct inode *inode,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
u32 mask, const void *data, int data_type,
const unsigned char *file_name, u32 cookie,
struct fsnotify_iter_info *iter_info);
Expand Down
6 changes: 3 additions & 3 deletions fs/notify/inotify/inotify_fsnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,20 @@ static int inotify_merge(struct list_head *list,

int inotify_handle_event(struct fsnotify_group *group,
struct inode *inode,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
u32 mask, const void *data, int data_type,
const unsigned char *file_name, u32 cookie,
struct fsnotify_iter_info *iter_info)
{
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
struct inotify_inode_mark *i_mark;
struct inotify_event_info *event;
struct fsnotify_event *fsn_event;
int ret;
int len = 0;
int alloc_len = sizeof(struct inotify_event_info);

BUG_ON(vfsmount_mark);
if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
return 0;

if ((inode_mark->mask & FS_EXCL_UNLINK) &&
(data_type == FSNOTIFY_EVENT_PATH)) {
Expand Down
8 changes: 6 additions & 2 deletions fs/notify/inotify/inotify_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,10 +485,14 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
struct fsnotify_group *group)
{
struct inotify_inode_mark *i_mark;
struct fsnotify_iter_info iter_info = {
.inode_mark = fsn_mark,
.report_mask = FSNOTIFY_OBJ_TYPE_INODE_FL,
};

/* Queue ignore event for the watch */
inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED,
NULL, FSNOTIFY_EVENT_NONE, NULL, 0, NULL);
inotify_handle_event(group, NULL, FS_IN_IGNORED, NULL,
FSNOTIFY_EVENT_NONE, NULL, 0, &iter_info);

i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
/* remove this mark from the idr */
Expand Down
20 changes: 18 additions & 2 deletions include/linux/fsnotify_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ struct fsnotify_iter_info;
struct fsnotify_ops {
int (*handle_event)(struct fsnotify_group *group,
struct inode *inode,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
u32 mask, const void *data, int data_type,
const unsigned char *file_name, u32 cookie,
struct fsnotify_iter_info *iter_info);
Expand Down Expand Up @@ -212,6 +210,24 @@ enum fsnotify_obj_type {
#define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
#define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)

struct fsnotify_iter_info {
struct fsnotify_mark *inode_mark;
struct fsnotify_mark *vfsmount_mark;
unsigned int report_mask;
int srcu_idx;
};

#define FSNOTIFY_ITER_FUNCS(name, NAME) \
static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \
struct fsnotify_iter_info *iter_info) \
{ \
return (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_##NAME##_FL) ? \
iter_info->name##_mark : NULL; \
}

FSNOTIFY_ITER_FUNCS(inode, INODE)
FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)

/*
* Inode / vfsmount point to this structure which tracks all marks attached to
* the inode / vfsmount. The reference to inode / vfsmount is held by this
Expand Down
3 changes: 1 addition & 2 deletions kernel/audit_fsnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,11 @@ static void audit_autoremove_mark_rule(struct audit_fsnotify_mark *audit_mark)
/* Update mark data in audit rules based on fsnotify events. */
static int audit_mark_handle_event(struct fsnotify_group *group,
struct inode *to_tell,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
u32 mask, const void *data, int data_type,
const unsigned char *dname, u32 cookie,
struct fsnotify_iter_info *iter_info)
{
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
struct audit_fsnotify_mark *audit_mark;
const struct inode *inode = NULL;

Expand Down
2 changes: 0 additions & 2 deletions kernel/audit_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,8 +989,6 @@ static void evict_chunk(struct audit_chunk *chunk)

static int audit_tree_handle_event(struct fsnotify_group *group,
struct inode *to_tell,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
u32 mask, const void *data, int data_type,
const unsigned char *file_name, u32 cookie,
struct fsnotify_iter_info *iter_info)
Expand Down
3 changes: 1 addition & 2 deletions kernel/audit_watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,11 @@ void audit_remove_watch_rule(struct audit_krule *krule)
/* Update watch data in audit rules based on fsnotify events. */
static int audit_watch_handle_event(struct fsnotify_group *group,
struct inode *to_tell,
struct fsnotify_mark *inode_mark,
struct fsnotify_mark *vfsmount_mark,
u32 mask, const void *data, int data_type,
const unsigned char *dname, u32 cookie,
struct fsnotify_iter_info *iter_info)
{
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
const struct inode *inode;
struct audit_parent *parent;

Expand Down

0 comments on commit 5b0457a

Please sign in to comment.