linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: torvalds@linux-foundation.org, viro@zeniv.linux.org.uk
Cc: dhowells@redhat.com, raven@themaw.net, mszeredi@redhat.com,
	christian@brauner.io, jannh@google.com, darrick.wong@oracle.com,
	kzak@redhat.com, jlayton@redhat.com, linux-api@vger.kernel.org,
	linux-fsdevel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH 09/14] fsinfo: Provide notification overrun handling support [ver #18]
Date: Mon, 09 Mar 2020 14:02:10 +0000	[thread overview]
Message-ID: <158376253048.344135.5312529212248513321.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <158376244589.344135.12925590041630631412.stgit@warthog.procyon.org.uk>

Provide support for the handling of an overrun in a watch queue.  In the
event that an overrun occurs, the watcher needs to be able to find out what
it was that they missed.  To this end, previous patches added event
counters to the superblock and mount object structures.

To make them accessible, they can be accessed using fsinfo() and the
FSINFO_ATTR_MOUNT_INFO attribute.

	struct fsinfo_mount_info {
		__u64	mnt_unique_id;
		__u32	sb_changes;
		__u32	sb_notifications;
		__u32	mnt_attr_changes;
		__u32	mnt_topology_changes;
		__u32	mnt_subtree_notifications;
	...
	};

There's a uniquifier and five event counters:

 (1) mnt_unique_id - This is an effectively non-repeating ID given to each
     mount object on creation.  This allows the caller to check that the
     mount ID didn't get reused (the 32-bit mount ID is more efficient to
     look up).

 (2) sb_changes - Count of superblock configuration changes.

 (3) sb_notifications - Count of other superblock notifications (errors,
     quota overruns, etc.).

 (4) mnt_attr_changes - Count of attribute changes on a mount object.

 (5) mnt_topology_changes - Count of alterations to the mount tree that
     affected this node.

 (6) mnt_subtree_notifications - Count of mount object event notifications
     that were generated in the subtree rooted at this node.  This excludes
     events generated on this node itself and does not include superblock
     events.

The counters are also accessible through the FSINFO_ATTR_MOUNT_CHILDREN
attribute, where a list of all the children of a mount can be scanned.  The
record returned for each child includes the sum of the above five counters
for that child.  An additional record is added at the end for the queried
object and that also includes the sum of its five counters

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/namespace.c              |   31 ++++++++++++++++++++++++++-----
 include/uapi/linux/fsinfo.h |    9 ++++++++-
 samples/vfs/test-fsinfo.c   |    7 +++++--
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index 88aef45bcfa8..2b651003e6af 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -4167,6 +4167,15 @@ int fsinfo_generic_mount_info(struct path *path, struct fsinfo_context *ctx)
 	p->mnt_unique_id	= m->mnt_unique_id;
 	p->mnt_id		= m->mnt_id;
 	p->parent_id		= m->mnt_parent->mnt_id;
+#ifdef CONFIG_SB_NOTIFICATIONS
+	p->sb_changes		= atomic_read(&sb->s_change_counter);
+	p->sb_notifications	= atomic_read(&sb->s_notify_counter);
+#endif
+#ifdef CONFIG_MOUNT_NOTIFICATIONS
+	p->mnt_attr_changes	= atomic_read(&m->mnt_attr_changes);
+	p->mnt_topology_changes	= atomic_read(&m->mnt_topology_changes);
+	p->mnt_subtree_notifications = atomic_read(&m->mnt_subtree_notifications);
+#endif
 
 	get_fs_root(current->fs, &root);
 	if (path->mnt == root.mnt) {
@@ -4293,17 +4302,29 @@ int fsinfo_generic_mount_point_full(struct path *path, struct fsinfo_context *ct
 static void fsinfo_store_mount(struct fsinfo_context *ctx, const struct mount *p)
 {
 	struct fsinfo_mount_child record = {};
+	const struct super_block *sb = p->mnt.mnt_sb;
 	unsigned int usage = ctx->usage;
 
 	if (ctx->usage >= INT_MAX)
 		return;
 	ctx->usage = usage + sizeof(record);
+	if (!ctx->buffer || ctx->usage > ctx->buf_size)
+		return;
 
-	if (ctx->buffer && ctx->usage <= ctx->buf_size) {
-		record.mnt_unique_id	= p->mnt_unique_id;
-		record.mnt_id		= p->mnt_id;
-		memcpy(ctx->buffer + usage, &record, sizeof(record));
-	}
+	record.mnt_unique_id	= p->mnt_unique_id;
+	record.mnt_id		= p->mnt_id;
+	record.notify_sum	= 0;
+#ifdef CONFIG_SB_NOTIFICATIONS
+	record.notify_sum	+= (atomic_read(&sb->s_change_counter) +
+				    atomic_read(&sb->s_notify_counter));
+#endif
+#ifdef CONFIG_MOUNT_NOTIFICATIONS
+	record.notify_sum	+= (atomic_read(&p->mnt_attr_changes) +
+				    atomic_read(&p->mnt_topology_changes) +
+				    atomic_read(&p->mnt_subtree_notifications));
+#endif
+
+	memcpy(ctx->buffer + usage, &record, sizeof(record));
 }
 
 /*
diff --git a/include/uapi/linux/fsinfo.h b/include/uapi/linux/fsinfo.h
index 909d6104933b..826b788b0795 100644
--- a/include/uapi/linux/fsinfo.h
+++ b/include/uapi/linux/fsinfo.h
@@ -104,6 +104,11 @@ struct fsinfo_mount_info {
 	__u32	from_id;		/* Slave propagated from ID */
 	__u32	attr;			/* MOUNT_ATTR_* flags */
 	__u32	propagation;		/* MOUNT_PROPAGATION_* flags */
+	__u32	sb_changes;		/* Number of sb configuration changes */
+	__u32	sb_notifications;	/* Number of other sb notifications */
+	__u32	mnt_attr_changes;	/* Number of attribute changes to this mount. */
+	__u32	mnt_topology_changes;	/* Number of topology changes to this mount. */
+	__u32	mnt_subtree_notifications; /* Number of notifications in mount subtree */
 };
 
 #define FSINFO_ATTR_MOUNT_INFO__STRUCT struct fsinfo_mount_info
@@ -115,7 +120,9 @@ struct fsinfo_mount_info {
 struct fsinfo_mount_child {
 	__u64	mnt_unique_id;		/* Kernel-lifetime unique mount ID */
 	__u32	mnt_id;			/* Mount identifier (use with AT_FSINFO_MOUNTID_PATH) */
-	__u32	__padding[1];
+	__u32	notify_sum;		/* Sum of sb_changes, sb_notifications, mnt_attr_changes,
+					 * mnt_topology_changes and mnt_subtree_notifications.
+					 */
 };
 
 #define FSINFO_ATTR_MOUNT_CHILDREN__STRUCT struct fsinfo_mount_child
diff --git a/samples/vfs/test-fsinfo.c b/samples/vfs/test-fsinfo.c
index bdc7ea952630..91434f459ba5 100644
--- a/samples/vfs/test-fsinfo.c
+++ b/samples/vfs/test-fsinfo.c
@@ -300,6 +300,9 @@ static void dump_fsinfo_generic_mount_info(void *reply, unsigned int size)
 	printf("\tgroup   : %x\n", r->group_id);
 	printf("\tattr    : %x\n", r->attr);
 	printf("\tpropag  : %x\n", r->propagation);
+	printf("\tsb_nfy  : changes=%u other=%u\n", r->sb_changes, r->sb_notifications);
+	printf("\tmnt_nfy : attr=%u topology=%u subtree=%u\n",
+	       r->mnt_attr_changes, r->mnt_topology_changes, r->mnt_subtree_notifications);
 }
 
 static void dump_fsinfo_generic_mount_child(void *reply, unsigned int size)
@@ -322,8 +325,8 @@ static void dump_fsinfo_generic_mount_child(void *reply, unsigned int size)
 		mp = "<this>";
 	}
 
-	printf("%8x %16llx %s\n",
-	       r->mnt_id, (unsigned long long)r->mnt_unique_id, mp);
+	printf("%8x %16llx %10u %s\n",
+	       r->mnt_id, (unsigned long long)r->mnt_unique_id, r->notify_sum, mp);
 }
 
 static void dump_string(void *reply, unsigned int size)



  parent reply	other threads:[~2020-03-09 14:02 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-09 14:00 [PATCH 00/14] VFS: Filesystem information [ver #18] David Howells
2020-03-09 14:00 ` [PATCH 01/14] VFS: Add additional RESOLVE_* flags " David Howells
2020-03-09 20:56   ` Stefan Metzmacher
2020-03-09 21:13   ` David Howells
     [not found]   ` <20200310005549.adrn3yf4mbljc5f6@yavin>
2020-03-10  1:14     ` Linus Torvalds
2020-03-10  7:25     ` David Howells
2020-03-11 17:59       ` Linus Torvalds
2020-03-12  9:08         ` Stefan Metzmacher
2020-03-12 16:24           ` Linus Torvalds
2020-03-12 17:11             ` Stefan Metzmacher
2020-03-12 19:37               ` Al Viro
2020-03-12 21:48               ` Jeremy Allison
     [not found]               ` <20200313095901.tdv4vl7envypgqfz@yavin>
2020-03-13 16:48                 ` Jeremy Allison
2020-03-13 18:28                 ` Al Viro
2020-03-13 18:35                   ` Jeremy Allison
2020-03-16 14:20                   ` Aleksa Sarai
2020-03-12 19:25             ` Al Viro
2020-03-12 16:56           ` David Howells
2020-03-12 18:09             ` Linus Torvalds
2020-03-09 14:01 ` [PATCH 02/14] fsinfo: Add fsinfo() syscall to query filesystem information " David Howells
2020-03-10  9:31   ` Christian Brauner
2020-03-10  9:32     ` [PATCH v19 01/14] fsinfo: Add fsinfo() syscall to query filesystem information Christian Brauner
2020-03-10  9:32       ` [PATCH v19 14/14] arch: wire up fsinfo syscall Christian Brauner
2020-03-09 14:01 ` [PATCH 03/14] fsinfo: Provide a bitmap of supported features [ver #18] David Howells
2020-03-09 14:01 ` [PATCH 04/14] fsinfo: Allow retrieval of superblock devname, options and stats " David Howells
2020-03-09 14:01 ` [PATCH 05/14] fsinfo: Allow fsinfo() to look up a mount object by ID " David Howells
2020-03-09 14:01 ` [PATCH 06/14] fsinfo: Add a uniquifier ID to struct mount " David Howells
2020-03-09 14:01 ` [PATCH 07/14] fsinfo: Allow mount information to be queried " David Howells
2020-03-10  9:04   ` Miklos Szeredi
2020-03-09 14:02 ` [PATCH 08/14] fsinfo: Allow the mount topology propogation flags to be retrieved " David Howells
2020-03-10  8:42   ` Christian Brauner
2020-03-09 14:02 ` David Howells [this message]
2020-03-09 14:02 ` [PATCH 10/14] fsinfo: sample: Mount listing program " David Howells
2020-03-09 14:02 ` [PATCH 11/14] fsinfo: Add API documentation " David Howells
2020-03-09 14:02 ` [PATCH 12/14] fsinfo: Add support for AFS " David Howells
2020-03-09 14:02 ` [PATCH 13/14] fsinfo: Example support for Ext4 " David Howells
2020-03-09 14:02 ` [PATCH 14/14] fsinfo: Example support for NFS " David Howells
2020-03-09 17:50 ` [PATCH 00/14] VFS: Filesystem information " Jeff Layton
2020-03-09 19:22   ` Andres Freund
2020-03-09 22:49     ` Jeff Layton
2020-03-10  0:18       ` Andres Freund
2020-03-09 20:02 ` Miklos Szeredi
2020-03-09 22:52 ` David Howells
2020-03-10  9:18   ` Miklos Szeredi

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=158376253048.344135.5312529212248513321.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=christian@brauner.io \
    --cc=darrick.wong@oracle.com \
    --cc=jannh@google.com \
    --cc=jlayton@redhat.com \
    --cc=kzak@redhat.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mszeredi@redhat.com \
    --cc=raven@themaw.net \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /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).