From: Jeremy Bongio <bongiojp@gmail.com>
To: Ted Tso <tytso@mit.edu>
Cc: linux-ext4@vger.kernel.org, Jeremy Bongio <bongiojp@gmail.com>
Subject: [PATCH v2] Add support for get/set UUID ioctls.
Date: Mon, 18 Jul 2022 23:56:37 -0700 [thread overview]
Message-ID: <20220719065637.154309-1-bongiojp@gmail.com> (raw)
When mounted, there is a race condition between changing the filesystem
UUID and changing other aspects of the filesystem, like mounting, resizing,
changing features, etc. Using these ioctls to get/set the UUID ensures the
filesystem is not being resized.
Signed-off-by: Jeremy Bongio <bongiojp@gmail.com>
---
fu_* fields are now named fsu_*.
Removed EXT4_IOC_SETFSUUID_FLAG_BLOCKING flag.
fsu_flags is initialized to 0.
misc/tune2fs.c | 104 ++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 86 insertions(+), 18 deletions(-)
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 6c162ba5..39399d83 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -82,11 +82,25 @@ extern int optind;
#define FS_IOC_GETFSLABEL _IOR(0x94, 49, char[FSLABEL_MAX])
#endif
+struct fsuuid {
+ __u32 fsu_len;
+ __u32 fsu_flags;
+ __u8 fsu_uuid[];
+};
+
+#ifndef EXT4_IOC_GETFSUUID
+#define EXT4_IOC_GETFSUUID _IOR('f', 44, struct fsuuid)
+#endif
+
+#ifndef EXT4_IOC_SETFSUUID
+#define EXT4_IOC_SETFSUUID _IOW('f', 44, struct fsuuid)
+#endif
+
extern int ask_yn(const char *string, int def);
const char *program_name = "tune2fs";
char *device_name;
-char *new_label, *new_last_mounted, *new_UUID;
+char *new_label, *new_last_mounted, *requested_uuid;
char *io_options;
static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
static int m_flag, M_flag, Q_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
@@ -2102,7 +2116,7 @@ static void parse_tune2fs_options(int argc, char **argv)
open_flag = EXT2_FLAG_RW;
break;
case 'U':
- new_UUID = optarg;
+ requested_uuid = optarg;
U_flag = 1;
open_flag = EXT2_FLAG_RW |
EXT2_FLAG_JOURNAL_DEV_OK;
@@ -3078,6 +3092,52 @@ int handle_fslabel(int setlabel) {
return 0;
}
+/*
+ * Use EXT4_IOC_GETFSUUID/EXT4_IOC_SETFSUUID to get/set file system UUID.
+ * Return: 0 on success
+ * 1 on error
+ * -1 when the old method should be used
+ */
+int handle_fsuuid(__u8 *uuid, bool get)
+{
+ errcode_t ret;
+ int mnt_flags, fd;
+ char label[FSLABEL_MAX];
+ int maxlen = FSLABEL_MAX - 1;
+ char mntpt[PATH_MAX + 1];
+ struct fsuuid *fsuuid = NULL;
+
+ fsuuid = malloc(sizeof(*fsuuid) + UUID_SIZE);
+ if (!fsuuid)
+ return -1;
+
+ memcpy(fsuuid->fsu_uuid, uuid, UUID_SIZE);
+ fsuuid->fsu_len = UUID_SIZE;
+ fsuuid->fsu_flags = 0;
+
+ ret = ext2fs_check_mount_point(device_name, &mnt_flags,
+ mntpt, sizeof(mntpt));
+ if (ret || !(mnt_flags & EXT2_MF_MOUNTED) ||
+ (!get && (mnt_flags & EXT2_MF_READONLY)) ||
+ !mntpt[0])
+ return -1;
+
+ fd = open(mntpt, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (get) {
+ if (ioctl(fd, EXT4_IOC_GETFSUUID, fsuuid))
+ ret = -1;
+ } else {
+ if (ioctl(fd, EXT4_IOC_SETFSUUID, fsuuid))
+ ret = -1;
+ }
+ close(fd);
+ return ret;
+}
+
+
#ifndef BUILD_AS_LIB
int main(int argc, char **argv)
#else
@@ -3454,6 +3514,7 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
dgrp_t i;
char buf[SUPERBLOCK_SIZE] __attribute__ ((aligned(8)));
__u8 old_uuid[UUID_SIZE];
+ uuid_t new_uuid;
if (ext2fs_has_feature_stable_inodes(fs->super)) {
fputs(_("Cannot change the UUID of this filesystem "
@@ -3507,25 +3568,34 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
set_csum = 1;
}
- memcpy(old_uuid, sb->s_uuid, UUID_SIZE);
- if ((strcasecmp(new_UUID, "null") == 0) ||
- (strcasecmp(new_UUID, "clear") == 0)) {
- uuid_clear(sb->s_uuid);
- } else if (strcasecmp(new_UUID, "time") == 0) {
- uuid_generate_time(sb->s_uuid);
- } else if (strcasecmp(new_UUID, "random") == 0) {
- uuid_generate(sb->s_uuid);
- } else if (uuid_parse(new_UUID, sb->s_uuid)) {
+ rc = handle_fsuuid(old_uuid, true);
+ if (rc == -1)
+ memcpy(old_uuid, sb->s_uuid, UUID_SIZE);
+
+ if ((strcasecmp(requested_uuid, "null") == 0) ||
+ (strcasecmp(requested_uuid, "clear") == 0)) {
+ uuid_clear(new_uuid);
+ } else if (strcasecmp(requested_uuid, "time") == 0) {
+ uuid_generate_time(new_uuid);
+ } else if (strcasecmp(requested_uuid, "random") == 0) {
+ uuid_generate(new_uuid);
+ } else if (uuid_parse(requested_uuid, new_uuid)) {
com_err(program_name, 0, "%s",
_("Invalid UUID format\n"));
rc = 1;
goto closefs;
}
- ext2fs_init_csum_seed(fs);
- if (set_csum) {
- for (i = 0; i < fs->group_desc_count; i++)
- ext2fs_group_desc_csum_set(fs, i);
- fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+
+ rc = handle_fsuuid(new_uuid, false);
+ if (rc == -1) {
+ memcpy(sb->s_uuid, new_uuid, UUID_SIZE);
+ ext2fs_init_csum_seed(fs);
+ if (set_csum) {
+ for (i = 0; i < fs->group_desc_count; i++)
+ ext2fs_group_desc_csum_set(fs, i);
+ fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+ }
+ ext2fs_mark_super_dirty(fs);
}
/* If this is a journal dev, we need to copy UUID into jsb */
@@ -3549,8 +3619,6 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
if ((rc = fs_update_journal_user(sb, old_uuid)))
goto closefs;
}
-
- ext2fs_mark_super_dirty(fs);
}
if (I_flag) {
--
2.37.0.170.g444d1eabd0-goog
next reply other threads:[~2022-07-19 6:56 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-19 6:56 Jeremy Bongio [this message]
2022-07-19 15:17 ` [PATCH v2] Add support for get/set UUID ioctls Darrick J. Wong
2022-07-19 21:16 ` Jeremy Bongio
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=20220719065637.154309-1-bongiojp@gmail.com \
--to=bongiojp@gmail.com \
--cc=linux-ext4@vger.kernel.org \
--cc=tytso@mit.edu \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.