diff options
| -rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 7 | ||||
| -rw-r--r-- | include/linux/fsnotify_backend.h | 15 | ||||
| -rw-r--r-- | tools/testing/selftests/filesystems/mount-notify/mount-notify_test.c | 57 | 
3 files changed, 47 insertions, 32 deletions
| diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index f2d840ae4ded..87f861e9004f 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1961,12 +1961,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,  		return -EINVAL;  	if (mark_cmd == FAN_MARK_FLUSH) { -		if (mark_type == FAN_MARK_MOUNT) -			fsnotify_clear_vfsmount_marks_by_group(group); -		else if (mark_type == FAN_MARK_FILESYSTEM) -			fsnotify_clear_sb_marks_by_group(group); -		else -			fsnotify_clear_inode_marks_by_group(group); +		fsnotify_clear_marks_by_group(group, obj_type);  		return 0;  	} diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 6cd8d1d28b8b..fc27b53c58c2 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -907,21 +907,6 @@ extern void fsnotify_wait_marks_destroyed(void);  /* Clear all of the marks of a group attached to a given object type */  extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group,  					  unsigned int obj_type); -/* run all the marks in a group, and clear all of the vfsmount marks */ -static inline void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) -{ -	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT); -} -/* run all the marks in a group, and clear all of the inode marks */ -static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group) -{ -	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE); -} -/* run all the marks in a group, and clear all of the sn marks */ -static inline void fsnotify_clear_sb_marks_by_group(struct fsnotify_group *group) -{ -	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_SB); -}  extern void fsnotify_get_mark(struct fsnotify_mark *mark);  extern void fsnotify_put_mark(struct fsnotify_mark *mark);  extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info); diff --git a/tools/testing/selftests/filesystems/mount-notify/mount-notify_test.c b/tools/testing/selftests/filesystems/mount-notify/mount-notify_test.c index 4a2d5c454fd1..59a71f22fb11 100644 --- a/tools/testing/selftests/filesystems/mount-notify/mount-notify_test.c +++ b/tools/testing/selftests/filesystems/mount-notify/mount-notify_test.c @@ -48,8 +48,16 @@ static uint64_t get_mnt_id(struct __test_metadata *const _metadata,  static const char root_mntpoint_templ[] = "/tmp/mount-notify_test_root.XXXXXX"; +static const int mark_cmds[] = { +	FAN_MARK_ADD, +	FAN_MARK_REMOVE, +	FAN_MARK_FLUSH +}; + +#define NUM_FAN_FDS ARRAY_SIZE(mark_cmds) +  FIXTURE(fanotify) { -	int fan_fd; +	int fan_fd[NUM_FAN_FDS];  	char buf[256];  	unsigned int rem;  	void *next; @@ -61,7 +69,7 @@ FIXTURE(fanotify) {  FIXTURE_SETUP(fanotify)  { -	int ret; +	int i, ret;  	ASSERT_EQ(unshare(CLONE_NEWNS), 0); @@ -89,20 +97,34 @@ FIXTURE_SETUP(fanotify)  	self->root_id = get_mnt_id(_metadata, "/");  	ASSERT_NE(self->root_id, 0); -	self->fan_fd = fanotify_init(FAN_REPORT_MNT, 0); -	ASSERT_GE(self->fan_fd, 0); - -	ret = fanotify_mark(self->fan_fd, FAN_MARK_ADD | FAN_MARK_MNTNS, -			    FAN_MNT_ATTACH | FAN_MNT_DETACH, self->ns_fd, NULL); -	ASSERT_EQ(ret, 0); +	for (i = 0; i < NUM_FAN_FDS; i++) { +		self->fan_fd[i] = fanotify_init(FAN_REPORT_MNT | FAN_NONBLOCK, +						0); +		ASSERT_GE(self->fan_fd[i], 0); +		ret = fanotify_mark(self->fan_fd[i], FAN_MARK_ADD | +				    FAN_MARK_MNTNS, +				    FAN_MNT_ATTACH | FAN_MNT_DETACH, +				    self->ns_fd, NULL); +		ASSERT_EQ(ret, 0); +		// On fd[0] we do an extra ADD that changes nothing. +		// On fd[1]/fd[2] we REMOVE/FLUSH which removes the mark. +		ret = fanotify_mark(self->fan_fd[i], mark_cmds[i] | +				    FAN_MARK_MNTNS, +				    FAN_MNT_ATTACH | FAN_MNT_DETACH, +				    self->ns_fd, NULL); +		ASSERT_EQ(ret, 0); +	}  	self->rem = 0;  }  FIXTURE_TEARDOWN(fanotify)  { +	int i; +  	ASSERT_EQ(self->rem, 0); -	close(self->fan_fd); +	for (i = 0; i < NUM_FAN_FDS; i++) +		close(self->fan_fd[i]);  	ASSERT_EQ(fchdir(self->orig_root), 0); @@ -123,8 +145,21 @@ static uint64_t expect_notify(struct __test_metadata *const _metadata,  	unsigned int thislen;  	if (!self->rem) { -		ssize_t len = read(self->fan_fd, self->buf, sizeof(self->buf)); -		ASSERT_GT(len, 0); +		ssize_t len; +		int i; + +		for (i = NUM_FAN_FDS - 1; i >= 0; i--) { +			len = read(self->fan_fd[i], self->buf, +				   sizeof(self->buf)); +			if (i > 0) { +				// Groups 1,2 should get EAGAIN +				ASSERT_EQ(len, -1); +				ASSERT_EQ(errno, EAGAIN); +			} else { +				// Group 0 should get events +				ASSERT_GT(len, 0); +			} +		}  		self->rem = len;  		self->next = (void *) self->buf; | 
