linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jim Lieb <jlieb@panasas.com>
To: linux-fsdevel@vger.kernel.org
Cc: Jim Lieb <jlieb@panasas.com>
Subject: [PATCH 1/3] fsnotify: add support for ignoring events from self
Date: Wed,  4 Sep 2013 11:31:00 -0700	[thread overview]
Message-ID: <1378319462-4767-2-git-send-email-jlieb@panasas.com> (raw)
In-Reply-To: <1378319462-4767-1-git-send-email-jlieb@panasas.com>

Base support to allow inotify and fanotify instances to ignore
self generated events.  This allows user mode file servers to monitor
changes to their exported shares by other servers or other activities
on their server.  With FS_IGNORE_ME enabled, any f/s event triggered by
my pid is not queued into my watch/notify group.

Signed-off-by: Jim Lieb <jlieb@panasas.com>
---
 fs/notify/fsnotify.c             | 35 ++++++++++++++++++++++++-----------
 fs/notify/mark.c                 | 16 ++++++++++++++++
 include/linux/fsnotify_backend.h |  5 ++++-
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 4bb21d6..88770da 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -134,6 +134,7 @@ static int send_to_group(struct inode *to_tell,
 	struct fsnotify_group *group = NULL;
 	__u32 inode_test_mask = 0;
 	__u32 vfsmount_test_mask = 0;
+	struct pid *my_pid;
 
 	if (unlikely(!inode_mark && !vfsmount_mark)) {
 		BUG();
@@ -150,23 +151,35 @@ static int send_to_group(struct inode *to_tell,
 			vfsmount_mark->ignored_mask = 0;
 	}
 
+	my_pid = get_pid(task_tgid(current));
 	/* 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;
+		if (inode_mark->mask & FS_IGNORE_ME &&
+		    my_pid == inode_mark->ignore_pid) {
+			inode_test_mask = 0;
+		} else {
+			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;
+		}
 	}
 
 	/* 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;
+		if (vfsmount_mark->mask & FS_IGNORE_ME &&
+		    my_pid == vfsmount_mark->ignore_pid) {
+			vfsmount_test_mask = 0;
+		} else {
+			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;
+		}
 	}
+	put_pid(my_pid);
 
 	pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
 		 " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
@@ -300,7 +313,7 @@ static __init int fsnotify_init(void)
 {
 	int ret;
 
-	BUG_ON(hweight32(ALL_FSNOTIFY_EVENTS) != 23);
+	BUG_ON(hweight32(ALL_FSNOTIFY_EVENTS) != 24);
 
 	ret = init_srcu_struct(&fsnotify_mark_srcu);
 	if (ret)
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 923fe4a..ec08c48 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -132,6 +132,11 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark,
 
 	mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
 
+	if (mark->ignore_pid != NULL) {
+		put_pid(mark->ignore_pid);
+		mark->ignore_pid = NULL;
+	}
+
 	if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
 		inode = mark->i.inode;
 		fsnotify_destroy_inode_mark(mark);
@@ -198,6 +203,17 @@ void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
 
 	mark->mask = mask;
 
+	if (mask & FS_IGNORE_ME) {
+		if (mark->ignore_pid != NULL)
+			put_pid(mark->ignore_pid);
+		mark->ignore_pid = get_pid(task_tgid(current));
+	} else {
+		if (mark->ignore_pid != NULL) {
+			put_pid(mark->ignore_pid);
+			mark->ignore_pid = NULL;
+		}
+	}
+
 	if (mark->flags & FSNOTIFY_MARK_FLAG_INODE)
 		fsnotify_set_inode_mark_mask_locked(mark, mask);
 }
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 4b2ee8d..b219081 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -44,6 +44,8 @@
 #define FS_OPEN_PERM		0x00010000	/* open event in an permission hook */
 #define FS_ACCESS_PERM		0x00020000	/* access event in a permissions hook */
 
+#define FS_IGNORE_ME		0x00800000	/* do not send me events I caused */
+
 #define FS_EXCL_UNLINK		0x04000000	/* do not send events if object is unlinked */
 #define FS_ISDIR		0x40000000	/* event occurred against dir */
 #define FS_IN_ONESHOT		0x80000000	/* only send event once */
@@ -71,7 +73,7 @@
 			     FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
 			     FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
 			     FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
-			     FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \
+			     FS_OPEN_PERM | FS_ACCESS_PERM | FS_IGNORE_ME | FS_EXCL_UNLINK | \
 			     FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
 			     FS_DN_MULTISHOT | FS_EVENT_ON_CHILD)
 
@@ -281,6 +283,7 @@ struct fsnotify_mark {
 	/* we hold ref for each i_list and g_list.  also one ref for each 'thing'
 	 * in kernel that found and may be using this mark. */
 	atomic_t refcnt;		/* active things looking at this mark */
+	struct pid *ignore_pid;		/* ignore events generated by this thread group */
 	struct fsnotify_group *group;	/* group this mark is for */
 	struct list_head g_list;	/* list of marks by group->i_fsnotify_marks */
 	spinlock_t lock;		/* protect group and inode */
-- 
1.8.3.1


  reply	other threads:[~2013-09-04 18:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-04 18:30 RFC: fsnotify - Add support for ignoring self initiated events Jim Lieb
2013-09-04 18:31 ` Jim Lieb [this message]
2013-09-04 18:31 ` [PATCH 2/3] fanotify: enable support for ignoring self generated events Jim Lieb
2013-09-04 18:31 ` [PATCH 3/3] inotify: enable support to ignore " Jim Lieb
2013-09-11 14:27 ` RFC: fsnotify - Add support for ignoring self initiated events J. Bruce Fields
2013-09-11 17:03   ` Jim Lieb
  -- strict thread matches above, loose matches on Subject: below --
2013-10-16 19:13 [PATCH 0/3] " Jim Lieb
2013-10-16 19:13 ` [PATCH 1/3] fsnotify: add support for ignoring events from self Jim Lieb

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1378319462-4767-2-git-send-email-jlieb@panasas.com \
    --to=jlieb@panasas.com \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).