diff mbox

[v2,02/20] fsnotify: fix ignore mask logic in send_to_group()

Message ID 1522934301-6520-3-git-send-email-amir73il@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Amir Goldstein April 5, 2018, 1:18 p.m. UTC
The ignore mask logic in send_to_group() does not match the logic
in fanotify_should_send_event(). In the latter, a vfsmount mark ignore
mask precedes an inode mark mask and in the former, it does not.

That difference may cause events to be sent to fanotify backend for no
reason. Fix the logic in send_to_group() to match that of
fanotify_should_send_event().

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fsnotify.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

Comments

Jan Kara April 13, 2018, 1:53 p.m. UTC | #1
On Thu 05-04-18 16:18:03, Amir Goldstein wrote:
> The ignore mask logic in send_to_group() does not match the logic
> in fanotify_should_send_event(). In the latter, a vfsmount mark ignore
> mask precedes an inode mark mask and in the former, it does not.
> 
> That difference may cause events to be sent to fanotify backend for no
> reason. Fix the logic in send_to_group() to match that of
> fanotify_should_send_event().
> 
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>

Thanks. The patch looks good and I've merged it to my tree.

								Honza

> ---
>  fs/notify/fsnotify.c | 25 +++++++++++--------------
>  1 file changed, 11 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
> index 219b269c737e..613ec7e5a465 100644
> --- a/fs/notify/fsnotify.c
> +++ b/fs/notify/fsnotify.c
> @@ -192,8 +192,9 @@ static int send_to_group(struct inode *to_tell,
>  			 struct fsnotify_iter_info *iter_info)
>  {
>  	struct fsnotify_group *group = NULL;
> -	__u32 inode_test_mask = 0;
> -	__u32 vfsmount_test_mask = 0;
> +	__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
> +	__u32 marks_mask = 0;
> +	__u32 marks_ignored_mask = 0;
>  
>  	if (unlikely(!inode_mark && !vfsmount_mark)) {
>  		BUG();
> @@ -213,29 +214,25 @@ static int send_to_group(struct inode *to_tell,
>  	/* does the inode mark tell us to do something? */
>  	if (inode_mark) {
>  		group = inode_mark->group;
> -		inode_test_mask = (mask & ~FS_EVENT_ON_CHILD);
> -		inode_test_mask &= inode_mark->mask;
> -		inode_test_mask &= ~inode_mark->ignored_mask;
> +		marks_mask |= inode_mark->mask;
> +		marks_ignored_mask |= inode_mark->ignored_mask;
>  	}
>  
>  	/* does the vfsmount_mark tell us to do something? */
>  	if (vfsmount_mark) {
> -		vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD);
>  		group = vfsmount_mark->group;
> -		vfsmount_test_mask &= vfsmount_mark->mask;
> -		vfsmount_test_mask &= ~vfsmount_mark->ignored_mask;
> -		if (inode_mark)
> -			vfsmount_test_mask &= ~inode_mark->ignored_mask;
> +		marks_mask |= vfsmount_mark->mask;
> +		marks_ignored_mask |= vfsmount_mark->ignored_mask;
>  	}
>  
>  	pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
> -		 " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
> +		 " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
>  		 " data=%p data_is=%d cookie=%d\n",
> -		 __func__, group, to_tell, mask, inode_mark,
> -		 inode_test_mask, vfsmount_mark, vfsmount_test_mask, data,
> +		 __func__, group, to_tell, mask, inode_mark, vfsmount_mark,
> +		 marks_mask, marks_ignored_mask, data,
>  		 data_is, cookie);
>  
> -	if (!inode_test_mask && !vfsmount_test_mask)
> +	if (!(test_mask & marks_mask & ~marks_ignored_mask))
>  		return 0;
>  
>  	return group->ops->handle_event(group, to_tell, inode_mark,
> -- 
> 2.7.4
>
diff mbox

Patch

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 219b269c737e..613ec7e5a465 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -192,8 +192,9 @@  static int send_to_group(struct inode *to_tell,
 			 struct fsnotify_iter_info *iter_info)
 {
 	struct fsnotify_group *group = NULL;
-	__u32 inode_test_mask = 0;
-	__u32 vfsmount_test_mask = 0;
+	__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
+	__u32 marks_mask = 0;
+	__u32 marks_ignored_mask = 0;
 
 	if (unlikely(!inode_mark && !vfsmount_mark)) {
 		BUG();
@@ -213,29 +214,25 @@  static int send_to_group(struct inode *to_tell,
 	/* does the inode mark tell us to do something? */
 	if (inode_mark) {
 		group = inode_mark->group;
-		inode_test_mask = (mask & ~FS_EVENT_ON_CHILD);
-		inode_test_mask &= inode_mark->mask;
-		inode_test_mask &= ~inode_mark->ignored_mask;
+		marks_mask |= inode_mark->mask;
+		marks_ignored_mask |= inode_mark->ignored_mask;
 	}
 
 	/* does the vfsmount_mark tell us to do something? */
 	if (vfsmount_mark) {
-		vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD);
 		group = vfsmount_mark->group;
-		vfsmount_test_mask &= vfsmount_mark->mask;
-		vfsmount_test_mask &= ~vfsmount_mark->ignored_mask;
-		if (inode_mark)
-			vfsmount_test_mask &= ~inode_mark->ignored_mask;
+		marks_mask |= vfsmount_mark->mask;
+		marks_ignored_mask |= vfsmount_mark->ignored_mask;
 	}
 
 	pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
-		 " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
+		 " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
 		 " data=%p data_is=%d cookie=%d\n",
-		 __func__, group, to_tell, mask, inode_mark,
-		 inode_test_mask, vfsmount_mark, vfsmount_test_mask, data,
+		 __func__, group, to_tell, mask, inode_mark, vfsmount_mark,
+		 marks_mask, marks_ignored_mask, data,
 		 data_is, cookie);
 
-	if (!inode_test_mask && !vfsmount_test_mask)
+	if (!(test_mask & marks_mask & ~marks_ignored_mask))
 		return 0;
 
 	return group->ops->handle_event(group, to_tell, inode_mark,