Commit aa93bdc5 authored by Amir Goldstein's avatar Amir Goldstein Committed by Jan Kara
Browse files

fsnotify: use helpers to access data by data_type

Create helpers to access path and inode from different data types.

Link: https://lore.kernel.org/r/20200319151022.31456-5-amir73il@gmail.com


Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent a1aae057
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -151,7 +151,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
{
	__u32 marks_mask = 0, marks_ignored_mask = 0;
	__u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS;
	const struct path *path = data;
	const struct path *path = fsnotify_data_path(data, data_type);
	struct fsnotify_mark *mark;
	int type;

@@ -160,7 +160,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,

	if (!FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
		/* Do we have path to open a file descriptor? */
		if (data_type != FSNOTIFY_EVENT_PATH)
		if (!path)
			return 0;
		/* Path type events are only relevant for files and dirs */
		if (!d_is_reg(path->dentry) && !d_can_lookup(path->dentry))
@@ -269,11 +269,8 @@ static struct inode *fanotify_fid_inode(struct inode *to_tell, u32 event_mask,
{
	if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS)
		return to_tell;
	else if (data_type == FSNOTIFY_EVENT_INODE)
		return (struct inode *)data;
	else if (data_type == FSNOTIFY_EVENT_PATH)
		return d_inode(((struct path *)data)->dentry);
	return NULL;

	return (struct inode *)fsnotify_data_inode(data, data_type);
}

struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
@@ -284,6 +281,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
	struct fanotify_event *event = NULL;
	gfp_t gfp = GFP_KERNEL_ACCOUNT;
	struct inode *id = fanotify_fid_inode(inode, mask, data, data_type);
	const struct path *path = fsnotify_data_path(data, data_type);

	/*
	 * For queues with unlimited length lost events are not expected and
@@ -324,10 +322,10 @@ init: __maybe_unused
	if (id && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
		/* Report the event without a file identifier on encode error */
		event->fh_type = fanotify_encode_fid(event, id, gfp, fsid);
	} else if (data_type == FSNOTIFY_EVENT_PATH) {
	} else if (path) {
		event->fh_type = FILEID_ROOT;
		event->path = *((struct path *)data);
		path_get(&event->path);
		event->path = *path;
		path_get(path);
	} else {
		event->fh_type = FILEID_INVALID;
		event->path.mnt = NULL;
+3 −2
Original line number Diff line number Diff line
@@ -318,6 +318,7 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
	     const struct qstr *file_name, u32 cookie)
{
	const struct path *path = fsnotify_data_path(data, data_is);
	struct fsnotify_iter_info iter_info = {};
	struct super_block *sb = to_tell->i_sb;
	struct mount *mnt = NULL;
@@ -325,8 +326,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
	int ret = 0;
	__u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS);

	if (data_is == FSNOTIFY_EVENT_PATH) {
		mnt = real_mount(((const struct path *)data)->mnt);
	if (path) {
		mnt = real_mount(path->mnt);
		mnt_or_sb_mask |= mnt->mnt_fsnotify_mask;
	}
	/* An event "on child" is not intended for a mount/sb mark */
+3 −5
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ int inotify_handle_event(struct fsnotify_group *group,
			 const struct qstr *file_name, u32 cookie,
			 struct fsnotify_iter_info *iter_info)
{
	const struct path *path = fsnotify_data_path(data, data_type);
	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
	struct inotify_inode_mark *i_mark;
	struct inotify_event_info *event;
@@ -73,12 +74,9 @@ int inotify_handle_event(struct fsnotify_group *group,
		return 0;

	if ((inode_mark->mask & FS_EXCL_UNLINK) &&
	    (data_type == FSNOTIFY_EVENT_PATH)) {
		const struct path *path = data;

		if (d_unlinked(path->dentry))
	    path && d_unlinked(path->dentry))
		return 0;
	}

	if (file_name) {
		len = file_name->len;
		alloc_len += len + 1;
+30 −4
Original line number Diff line number Diff line
@@ -212,10 +212,36 @@ struct fsnotify_group {
	};
};

/* when calling fsnotify tell it if the data is a path or inode */
#define FSNOTIFY_EVENT_NONE	0
#define FSNOTIFY_EVENT_PATH	1
#define FSNOTIFY_EVENT_INODE	2
/* When calling fsnotify tell it if the data is a path or inode */
enum fsnotify_data_type {
	FSNOTIFY_EVENT_NONE,
	FSNOTIFY_EVENT_PATH,
	FSNOTIFY_EVENT_INODE,
};

static inline const struct inode *fsnotify_data_inode(const void *data,
						      int data_type)
{
	switch (data_type) {
	case FSNOTIFY_EVENT_INODE:
		return data;
	case FSNOTIFY_EVENT_PATH:
		return d_inode(((const struct path *)data)->dentry);
	default:
		return NULL;
	}
}

static inline const struct path *fsnotify_data_path(const void *data,
						    int data_type)
{
	switch (data_type) {
	case FSNOTIFY_EVENT_PATH:
		return data;
	default:
		return NULL;
	}
}

enum fsnotify_obj_type {
	FSNOTIFY_OBJ_TYPE_INODE,
+2 −11
Original line number Diff line number Diff line
@@ -160,23 +160,14 @@ static int audit_mark_handle_event(struct fsnotify_group *group,
{
	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
	struct audit_fsnotify_mark *audit_mark;
	const struct inode *inode = NULL;
	const struct inode *inode = fsnotify_data_inode(data, data_type);

	audit_mark = container_of(inode_mark, struct audit_fsnotify_mark, mark);

	BUG_ON(group != audit_fsnotify_group);

	switch (data_type) {
	case (FSNOTIFY_EVENT_PATH):
		inode = ((const struct path *)data)->dentry->d_inode;
		break;
	case (FSNOTIFY_EVENT_INODE):
		inode = (const struct inode *)data;
		break;
	default:
		BUG();
	if (WARN_ON(!inode))
		return 0;
	}

	if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) {
		if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL))
Loading