diff mbox series

[RFC,1/3] fs: Add s_instance_id field to superblock for unique identification

Message ID 20201116045758.21774-2-sargun@sargun.me (mailing list archive)
State New, archived
Headers show
Series [RFC,1/3] fs: Add s_instance_id field to superblock for unique identification | expand

Commit Message

Sargun Dhillon Nov. 16, 2020, 4:57 a.m. UTC
This assigns a per-boot unique number to each superblock. This allows
other components to know whether a filesystem has been remounted
since they last interacted with it.

At every boot it is reset to 0. There is no specific reason it is set to 0,
other than repeatability versus using some random starting number. Because
of this, you must store it along some other piece of data which is
initialized at boot time.

This doesn't have any of the overhead of idr, and a u64 wont wrap any time
soon. There is no forward lookup requirement, so an idr is not needed.

In the future, we may want to expose this to userspace. Userspace programs
can benefit from this if they have large chunks of dirty or mmaped memory
that they're interacting with, and they want to see if that volume has been
unmounted, and remounted. Along with this, and a mechanism to inspect the
superblock's errseq a user can determine whether they need to throw away
their cache or similar. This is another benefit in comparison to just
using a pointer to the superblock to uniquely identify it.

Although this doesn't expose an ioctl or similar yet, in the future we
could add an ioctl that allows for fetching the s_instance_id for a given
cache, and inspection of the errseq associated with that.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Cc: David Howells <dhowells@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-unionfs@vger.kernel.org
---
 fs/super.c              | 3 +++
 include/linux/fs.h      | 7 +++++++
 include/uapi/linux/fs.h | 2 ++
 3 files changed, 12 insertions(+)

Comments

Sargun Dhillon Nov. 16, 2020, 5:07 a.m. UTC | #1
On Sun, Nov 15, 2020 at 8:58 PM Sargun Dhillon <sargun@sargun.me> wrote:
>
> This assigns a per-boot unique number to each superblock. This allows
> other components to know whether a filesystem has been remounted
> since they last interacted with it.
>
> At every boot it is reset to 0. There is no specific reason it is set to 0,
> other than repeatability versus using some random starting number. Because
> of this, you must store it along some other piece of data which is
> initialized at boot time.
>
> This doesn't have any of the overhead of idr, and a u64 wont wrap any time
> soon. There is no forward lookup requirement, so an idr is not needed.
>
> In the future, we may want to expose this to userspace. Userspace programs
> can benefit from this if they have large chunks of dirty or mmaped memory
> that they're interacting with, and they want to see if that volume has been
> unmounted, and remounted. Along with this, and a mechanism to inspect the
> superblock's errseq a user can determine whether they need to throw away
> their cache or similar. This is another benefit in comparison to just
> using a pointer to the superblock to uniquely identify it.
>
> Although this doesn't expose an ioctl or similar yet, in the future we
> could add an ioctl that allows for fetching the s_instance_id for a given
> cache, and inspection of the errseq associated with that.
>
> Signed-off-by: Sargun Dhillon <sargun@sargun.me>
> Cc: David Howells <dhowells@redhat.com>
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-unionfs@vger.kernel.org
> ---
>  fs/super.c              | 3 +++
>  include/linux/fs.h      | 7 +++++++
>  include/uapi/linux/fs.h | 2 ++
>  3 files changed, 12 insertions(+)
>
> diff --git a/fs/super.c b/fs/super.c
> index 904459b35119..e47ace7f8c3d 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -42,6 +42,7 @@
>
>  static int thaw_super_locked(struct super_block *sb);
>
> +static u64 s_instance_id_counter;
>  static LIST_HEAD(super_blocks);
>  static DEFINE_SPINLOCK(sb_lock);
>
> @@ -546,6 +547,7 @@ struct super_block *sget_fc(struct fs_context *fc,
>         s->s_iflags |= fc->s_iflags;
>         strlcpy(s->s_id, s->s_type->name, sizeof(s->s_id));
>         list_add_tail(&s->s_list, &super_blocks);
> +       s->s_instance_id = s_instance_id_counter++;
>         hlist_add_head(&s->s_instances, &s->s_type->fs_supers);
>         spin_unlock(&sb_lock);
>         get_filesystem(s->s_type);
> @@ -625,6 +627,7 @@ struct super_block *sget(struct file_system_type *type,
>         s->s_type = type;
>         strlcpy(s->s_id, type->name, sizeof(s->s_id));
>         list_add_tail(&s->s_list, &super_blocks);
> +       s->s_instance_id = s_instance_id_counter++;
>         hlist_add_head(&s->s_instances, &type->fs_supers);
>         spin_unlock(&sb_lock);
>         get_filesystem(type);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index dbbeb52ce5f3..642847c3673f 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1472,6 +1472,13 @@ struct super_block {
>         char                    s_id[32];       /* Informational name */
>         uuid_t                  s_uuid;         /* UUID */
>
> +       /*
> +        * ID identifying this particular instance of the superblock. It can
> +        * be used to determine if a particular filesystem has been remounted.
> +        * It may be exposed to userspace.
> +        */
> +       u64                     s_instance_id;
> +
>         unsigned int            s_max_links;
>         fmode_t                 s_mode;
>

Hit send a little too quickly. Please ignore this hunk as part of the RFC.
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index f44eb0a04afd..f2b126656c22 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -13,6 +13,7 @@
>  #include <linux/limits.h>
>  #include <linux/ioctl.h>
>  #include <linux/types.h>
> +#include <linux/uuid.h>
>  #ifndef __KERNEL__
>  #include <linux/fscrypt.h>
>  #endif
> @@ -203,6 +204,7 @@ struct fsxattr {
>
>  #define        FS_IOC_GETFLAGS                 _IOR('f', 1, long)
>  #define        FS_IOC_SETFLAGS                 _IOW('f', 2, long)
> +#define FS_IOC_GET_SB_INSTANCE         _IOR('f', 3, uuid_t)
>  #define        FS_IOC_GETVERSION               _IOR('v', 1, long)
>  #define        FS_IOC_SETVERSION               _IOW('v', 2, long)
>  #define FS_IOC_FIEMAP                  _IOWR('f', 11, struct fiemap)
> --
> 2.25.1
>
diff mbox series

Patch

diff --git a/fs/super.c b/fs/super.c
index 904459b35119..e47ace7f8c3d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -42,6 +42,7 @@ 
 
 static int thaw_super_locked(struct super_block *sb);
 
+static u64 s_instance_id_counter;
 static LIST_HEAD(super_blocks);
 static DEFINE_SPINLOCK(sb_lock);
 
@@ -546,6 +547,7 @@  struct super_block *sget_fc(struct fs_context *fc,
 	s->s_iflags |= fc->s_iflags;
 	strlcpy(s->s_id, s->s_type->name, sizeof(s->s_id));
 	list_add_tail(&s->s_list, &super_blocks);
+	s->s_instance_id = s_instance_id_counter++;
 	hlist_add_head(&s->s_instances, &s->s_type->fs_supers);
 	spin_unlock(&sb_lock);
 	get_filesystem(s->s_type);
@@ -625,6 +627,7 @@  struct super_block *sget(struct file_system_type *type,
 	s->s_type = type;
 	strlcpy(s->s_id, type->name, sizeof(s->s_id));
 	list_add_tail(&s->s_list, &super_blocks);
+	s->s_instance_id = s_instance_id_counter++;
 	hlist_add_head(&s->s_instances, &type->fs_supers);
 	spin_unlock(&sb_lock);
 	get_filesystem(type);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dbbeb52ce5f3..642847c3673f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1472,6 +1472,13 @@  struct super_block {
 	char			s_id[32];	/* Informational name */
 	uuid_t			s_uuid;		/* UUID */
 
+	/*
+	 * ID identifying this particular instance of the superblock. It can
+	 * be used to determine if a particular filesystem has been remounted.
+	 * It may be exposed to userspace.
+	 */
+	u64			s_instance_id;
+
 	unsigned int		s_max_links;
 	fmode_t			s_mode;
 
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index f44eb0a04afd..f2b126656c22 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -13,6 +13,7 @@ 
 #include <linux/limits.h>
 #include <linux/ioctl.h>
 #include <linux/types.h>
+#include <linux/uuid.h>
 #ifndef __KERNEL__
 #include <linux/fscrypt.h>
 #endif
@@ -203,6 +204,7 @@  struct fsxattr {
 
 #define	FS_IOC_GETFLAGS			_IOR('f', 1, long)
 #define	FS_IOC_SETFLAGS			_IOW('f', 2, long)
+#define FS_IOC_GET_SB_INSTANCE		_IOR('f', 3, uuid_t)
 #define	FS_IOC_GETVERSION		_IOR('v', 1, long)
 #define	FS_IOC_SETVERSION		_IOW('v', 2, long)
 #define FS_IOC_FIEMAP			_IOWR('f', 11, struct fiemap)