fs: super_set_uuid()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 7 Feb 2024 02:56:15 +0000 (21:56 -0500)
committerChristian Brauner <brauner@kernel.org>
Thu, 8 Feb 2024 20:19:59 +0000 (21:19 +0100)
Some weird old filesytems have UUID-like things that we wish to expose
as UUIDs, but are smaller; add a length field so that the new
FS_IOC_(GET|SET)UUID ioctls can handle them in generic code.

And add a helper super_set_uuid(), for setting nonstandard length uuids.

Helper is now required for the new FS_IOC_GETUUID ioctl; if
super_set_uuid() hasn't been called, the ioctl won't be supported.

Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Link: https://lore.kernel.org/r/20240207025624.1019754-2-kent.overstreet@linux.dev
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/ext4/super.c
fs/f2fs/super.c
fs/gfs2/ops_fstype.c
fs/kernfs/mount.c
fs/ocfs2/super.c
fs/ubifs/super.c
fs/xfs/xfs_mount.c
include/linux/fs.h
mm/shmem.c

index dcba0f85dfe245ab83598d5a451783b02044be52..9e28ebd0869a2c3b3db8479b2d8b210f269fa0ec 100644 (file)
@@ -5346,7 +5346,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                sb->s_qcop = &ext4_qctl_operations;
        sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
 #endif
-       memcpy(&sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
+       super_set_uuid(sb, es->s_uuid, sizeof(es->s_uuid));
 
        INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
        mutex_init(&sbi->s_orphan_lock);
index d45ab0992ae5947e6f89628e8e8829c548645d26..93bcd4e5864eb45fc96b6e6b65848c8cf9bb8d43 100644 (file)
@@ -4496,7 +4496,7 @@ try_onemore:
        sb->s_time_gran = 1;
        sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
                (test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0);
-       memcpy(&sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid));
+       super_set_uuid(sb, (void *) raw_super->uuid, sizeof(raw_super->uuid));
        sb->s_iflags |= SB_I_CGROUPWB;
 
        /* init f2fs-specific super block info */
index 1281e60be63900764f8c6c97973e057e02897a12..572d58e86296f9117a4e476075eaacdef52394f7 100644 (file)
@@ -214,7 +214,7 @@ static void gfs2_sb_in(struct gfs2_sbd *sdp, const void *buf)
 
        memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
        memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
-       memcpy(&s->s_uuid, str->sb_uuid, 16);
+       super_set_uuid(s, str->sb_uuid, 16);
 }
 
 /**
index 0c93cad0f0acac80425dcdbd21b1eedaffe8c4d6..e29f4edf9572e739c5da8e30f51ebfa05c4eb5ee 100644 (file)
@@ -358,7 +358,9 @@ int kernfs_get_tree(struct fs_context *fc)
                }
                sb->s_flags |= SB_ACTIVE;
 
-               uuid_gen(&sb->s_uuid);
+               uuid_t uuid;
+               uuid_gen(&uuid);
+               super_set_uuid(sb, uuid.b, sizeof(uuid));
 
                down_write(&root->kernfs_supers_rwsem);
                list_add(&info->node, &info->root->supers);
index 6b906424902b46b9b17e1fb2102e916fcb89d1fc..a70aff17d4554af8478308dc6c2b5b5cd3122d23 100644 (file)
@@ -2027,8 +2027,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
        cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits);
        bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
        sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);
-       memcpy(&sb->s_uuid, di->id2.i_super.s_uuid,
-              sizeof(di->id2.i_super.s_uuid));
+       super_set_uuid(sb, di->id2.i_super.s_uuid,
+                      sizeof(di->id2.i_super.s_uuid));
 
        osb->osb_dx_mask = (1 << (cbits - bbits)) - 1;
 
index 09e270d6ed0258923ccc7680025fad26d1cac5c6..f780729eec067740e6841ee50c594fc1baa03956 100644 (file)
@@ -2245,7 +2245,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
                goto out_umount;
        }
 
-       import_uuid(&sb->s_uuid, c->uuid);
+       super_set_uuid(sb, c->uuid, sizeof(c->uuid));
 
        mutex_unlock(&c->umount_mutex);
        return 0;
index aabb25dc3efab2ed57e8e1a99ec1aa0bfd503297..4a46bc44088fbf3c4a99fbce65e2b26ed8cc8177 100644 (file)
@@ -62,7 +62,7 @@ xfs_uuid_mount(
        int                     hole, i;
 
        /* Publish UUID in struct super_block */
-       uuid_copy(&mp->m_super->s_uuid, uuid);
+       super_set_uuid(mp->m_super, uuid->b, sizeof(*uuid));
 
        if (xfs_has_nouuid(mp))
                return 0;
index ed5966a70495129be1d6729eed2918240db62df1..acdc56987cb15268ceca495893eec2758c3041b3 100644 (file)
@@ -1257,6 +1257,7 @@ struct super_block {
 
        char                    s_id[32];       /* Informational name */
        uuid_t                  s_uuid;         /* UUID */
+       u8                      s_uuid_len;     /* Default 16, possibly smaller for weird filesystems */
 
        unsigned int            s_max_links;
 
@@ -2532,6 +2533,14 @@ extern __printf(2, 3)
 int super_setup_bdi_name(struct super_block *sb, char *fmt, ...);
 extern int super_setup_bdi(struct super_block *sb);
 
+static inline void super_set_uuid(struct super_block *sb, const u8 *uuid, unsigned len)
+{
+       if (WARN_ON(len > sizeof(sb->s_uuid)))
+               len = sizeof(sb->s_uuid);
+       sb->s_uuid_len = len;
+       memcpy(&sb->s_uuid, uuid, len);
+}
+
 extern int current_umask(void);
 
 extern void ihold(struct inode * inode);
index d7c84ff621860b85090cf61d9b2970357da01b76..be41955e52da120d34fcdca96b89368f5f7a3971 100644 (file)
@@ -4355,7 +4355,9 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
 #ifdef CONFIG_TMPFS_POSIX_ACL
        sb->s_flags |= SB_POSIXACL;
 #endif
-       uuid_gen(&sb->s_uuid);
+       uuid_t uuid;
+       uuid_gen(&uuid);
+       super_set_uuid(sb, uuid.b, sizeof(uuid));
 
 #ifdef CONFIG_TMPFS_QUOTA
        if (ctx->seen & SHMEM_SEEN_QUOTA) {