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@xxxxxxxxx> Cc: David Howells <dhowells@xxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: linux-fsdevel@xxxxxxxxxxxxxxx Cc: linux-unionfs@xxxxxxxxxxxxxxx --- 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; 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