Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9385a84d authored by Jan Kara's avatar Jan Kara
Browse files

fsnotify: Pass fsnotify_iter_info into handle_event handler



Pass fsnotify_iter_info into ->handle_event() handler so that it can
release and reacquire SRCU lock via fsnotify_prepare_user_wait() and
fsnotify_finish_user_wait() functions.  These functions also make sure
current marks are appropriately pinned so that iteration protected by
srcu in fsnotify() stays safe.

Reviewed-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent abc77577
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -85,7 +85,8 @@ static int dnotify_handle_event(struct fsnotify_group *group,
				struct fsnotify_mark *inode_mark,
				struct fsnotify_mark *inode_mark,
				struct fsnotify_mark *vfsmount_mark,
				struct fsnotify_mark *vfsmount_mark,
				u32 mask, const void *data, int data_type,
				u32 mask, const void *data, int data_type,
				const unsigned char *file_name, u32 cookie)
				const unsigned char *file_name, u32 cookie,
				struct fsnotify_iter_info *iter_info)
{
{
	struct dnotify_mark *dn_mark;
	struct dnotify_mark *dn_mark;
	struct dnotify_struct *dn;
	struct dnotify_struct *dn;
+2 −1
Original line number Original line Diff line number Diff line
@@ -174,7 +174,8 @@ static int fanotify_handle_event(struct fsnotify_group *group,
				 struct fsnotify_mark *inode_mark,
				 struct fsnotify_mark *inode_mark,
				 struct fsnotify_mark *fanotify_mark,
				 struct fsnotify_mark *fanotify_mark,
				 u32 mask, const void *data, int data_type,
				 u32 mask, const void *data, int data_type,
				 const unsigned char *file_name, u32 cookie)
				 const unsigned char *file_name, u32 cookie,
				 struct fsnotify_iter_info *iter_info)
{
{
	int ret = 0;
	int ret = 0;
	struct fanotify_event_info *event;
	struct fanotify_event_info *event;
+13 −6
Original line number Original line Diff line number Diff line
@@ -127,7 +127,8 @@ static int send_to_group(struct inode *to_tell,
			 struct fsnotify_mark *vfsmount_mark,
			 struct fsnotify_mark *vfsmount_mark,
			 __u32 mask, const void *data,
			 __u32 mask, const void *data,
			 int data_is, u32 cookie,
			 int data_is, u32 cookie,
			 const unsigned char *file_name)
			 const unsigned char *file_name,
			 struct fsnotify_iter_info *iter_info)
{
{
	struct fsnotify_group *group = NULL;
	struct fsnotify_group *group = NULL;
	__u32 inode_test_mask = 0;
	__u32 inode_test_mask = 0;
@@ -178,7 +179,7 @@ static int send_to_group(struct inode *to_tell,


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


/*
/*
@@ -194,8 +195,9 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
	struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL;
	struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL;
	struct fsnotify_group *inode_group, *vfsmount_group;
	struct fsnotify_group *inode_group, *vfsmount_group;
	struct fsnotify_mark_connector *inode_conn, *vfsmount_conn;
	struct fsnotify_mark_connector *inode_conn, *vfsmount_conn;
	struct fsnotify_iter_info iter_info;
	struct mount *mnt;
	struct mount *mnt;
	int idx, ret = 0;
	int ret = 0;
	/* global tests shouldn't care about events on child only the specific event */
	/* global tests shouldn't care about events on child only the specific event */
	__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
	__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);


@@ -224,7 +226,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
	    !(mnt && test_mask & mnt->mnt_fsnotify_mask))
	    !(mnt && test_mask & mnt->mnt_fsnotify_mask))
		return 0;
		return 0;


	idx = srcu_read_lock(&fsnotify_mark_srcu);
	iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);


	if ((mask & FS_MODIFY) ||
	if ((mask & FS_MODIFY) ||
	    (test_mask & to_tell->i_fsnotify_mask)) {
	    (test_mask & to_tell->i_fsnotify_mask)) {
@@ -284,8 +286,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
				vfsmount_mark = NULL;
				vfsmount_mark = NULL;
			}
			}
		}
		}

		iter_info.inode_mark = inode_mark;
		iter_info.vfsmount_mark = vfsmount_mark;

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


		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
			goto out;
			goto out;
@@ -299,7 +306,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
	}
	}
	ret = 0;
	ret = 0;
out:
out:
	srcu_read_unlock(&fsnotify_mark_srcu, idx);
	srcu_read_unlock(&fsnotify_mark_srcu, iter_info.srcu_idx);


	return ret;
	return ret;
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -27,7 +27,8 @@ extern int inotify_handle_event(struct fsnotify_group *group,
				struct fsnotify_mark *inode_mark,
				struct fsnotify_mark *inode_mark,
				struct fsnotify_mark *vfsmount_mark,
				struct fsnotify_mark *vfsmount_mark,
				u32 mask, const void *data, int data_type,
				u32 mask, const void *data, int data_type,
				const unsigned char *file_name, u32 cookie);
				const unsigned char *file_name, u32 cookie,
				struct fsnotify_iter_info *iter_info);


extern const struct fsnotify_ops inotify_fsnotify_ops;
extern const struct fsnotify_ops inotify_fsnotify_ops;


+2 −1
Original line number Original line Diff line number Diff line
@@ -68,7 +68,8 @@ int inotify_handle_event(struct fsnotify_group *group,
			 struct fsnotify_mark *inode_mark,
			 struct fsnotify_mark *inode_mark,
			 struct fsnotify_mark *vfsmount_mark,
			 struct fsnotify_mark *vfsmount_mark,
			 u32 mask, const void *data, int data_type,
			 u32 mask, const void *data, int data_type,
			 const unsigned char *file_name, u32 cookie)
			 const unsigned char *file_name, u32 cookie,
			 struct fsnotify_iter_info *iter_info)
{
{
	struct inotify_inode_mark *i_mark;
	struct inotify_inode_mark *i_mark;
	struct inotify_event_info *event;
	struct inotify_event_info *event;
Loading