From: Catherine Hoang <catherine.hoang@oracle.com>
To: linux-xfs@vger.kernel.org
Subject: [PATCH v1 3/4] xfs: add XFS_IOC_SETFSUUID ioctl
Date: Mon, 13 Mar 2023 21:21:08 -0700 [thread overview]
Message-ID: <20230314042109.82161-4-catherine.hoang@oracle.com> (raw)
In-Reply-To: <20230314042109.82161-1-catherine.hoang@oracle.com>
Add a new ioctl to set the uuid of a mounted filesystem.
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
fs/xfs/libxfs/xfs_fs.h | 1 +
fs/xfs/xfs_ioctl.c | 107 +++++++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_log.c | 19 ++++++++
fs/xfs/xfs_log.h | 2 +
4 files changed, 129 insertions(+)
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 1cfd5bc6520a..a350966cce99 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -831,6 +831,7 @@ struct xfs_scrub_metadata {
#define XFS_IOC_FSGEOMETRY _IOR ('X', 126, struct xfs_fsop_geom)
#define XFS_IOC_BULKSTAT _IOR ('X', 127, struct xfs_bulkstat_req)
#define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req)
+#define XFS_IOC_SETFSUUID _IOR ('X', 129, uuid_t)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 55bb01173cde..f0699a7169e4 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -38,6 +38,7 @@
#include "xfs_reflink.h"
#include "xfs_ioctl.h"
#include "xfs_xattr.h"
+#include "xfs_log.h"
#include <linux/mount.h>
#include <linux/namei.h>
@@ -1861,6 +1862,109 @@ xfs_fs_eofblocks_from_user(
return 0;
}
+static int
+xfs_ioc_setfsuuid(
+ struct file *filp,
+ struct xfs_mount *mp,
+ uuid_t __user *uuid)
+{
+ uuid_t old_uuid;
+ uuid_t new_uuid;
+ uuid_t *forget_uuid = NULL;
+ int error;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (!xfs_sb_is_v5(&mp->m_sb))
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&new_uuid, uuid, sizeof(uuid_t)))
+ return -EFAULT;
+ if (uuid_is_null(&new_uuid))
+ return -EINVAL;
+
+ /* Check that the uuid is unique and save a slot in the uuid table. */
+ if (!(xfs_has_nouuid(mp))) {
+ error = xfs_uuid_remember(&new_uuid);
+ if (error)
+ return error;
+ forget_uuid = &new_uuid;
+ }
+
+ error = xfs_internal_freeze(mp);
+ if (error)
+ goto out_drop_uuid;
+
+ spin_lock(&mp->m_sb_lock);
+ uuid_copy(&old_uuid, &mp->m_sb.sb_uuid);
+
+ /*
+ * On a v5 filesystem, every metadata object has a uuid stamped into
+ * the header. The particular uuid used is either sb_uuid or
+ * sb_meta_uuid, depending on whether the meta_uuid feature is set.
+ *
+ * If the meta_uuid feature is set:
+ * - The user visible uuid is set in sb_uuid
+ * - The uuid used for metadata blocks is set in sb_meta_uuid
+ * - If new_uuid == sb_meta_uuid, then we'll deactivate the feature
+ * and set sb_uuid to the new uuid
+ *
+ * If the meta_uuid feature is not set:
+ * - The user visible uuid is set in sb_uuid
+ * - The uuid used for meta blocks should match sb_uuid
+ * - If new_uuid != sb_uuid, we need to copy sb_uuid to sb_meta_uuid,
+ * set the meta_uuid feature bit, and set sb_uuid to the new uuid
+ */
+ if (xfs_has_metauuid(mp) &&
+ uuid_equal(&new_uuid, &mp->m_sb.sb_meta_uuid)) {
+ mp->m_sb.sb_features_incompat &= ~XFS_SB_FEAT_INCOMPAT_META_UUID;
+ mp->m_features &= ~XFS_FEAT_META_UUID;
+ } else if (!xfs_has_metauuid(mp) &&
+ !uuid_equal(&new_uuid, &mp->m_sb.sb_uuid)) {
+ uuid_copy(&mp->m_sb.sb_meta_uuid, &mp->m_sb.sb_uuid);
+ mp->m_sb.sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_META_UUID;
+ mp->m_features |= XFS_FEAT_META_UUID;
+ }
+
+ uuid_copy(&mp->m_sb.sb_uuid, &new_uuid);
+ spin_unlock(&mp->m_sb_lock);
+
+ xlog_iclog_update_uuid(mp);
+
+ xfs_buf_lock(mp->m_sb_bp);
+ xfs_buf_hold(mp->m_sb_bp);
+
+ xfs_sb_to_disk(mp->m_sb_bp->b_addr, &mp->m_sb);
+ error = xfs_bwrite(mp->m_sb_bp);
+ xfs_buf_relse(mp->m_sb_bp);
+ if (error)
+ goto out_drop_freeze;
+
+ /* Update incore state and prepare to drop the old uuid. */
+ uuid_copy(&mp->m_super->s_uuid, &new_uuid);
+ if (!(xfs_has_nouuid(mp)))
+ forget_uuid = &old_uuid;
+
+ /*
+ * Update the secondary supers, being aware that growfs also updates
+ * backup supers so we need to lock against that.
+ */
+ mutex_lock(&mp->m_growlock);
+ error = xfs_update_secondary_sbs(mp);
+ mutex_unlock(&mp->m_growlock);
+
+ invalidate_bdev(mp->m_ddev_targp->bt_bdev);
+ xfs_log_clean(mp);
+
+out_drop_freeze:
+ xfs_internal_unfreeze(mp);
+out_drop_uuid:
+ if (forget_uuid)
+ xfs_uuid_forget(forget_uuid);
+ return error;
+}
+
/*
* These long-unused ioctls were removed from the official ioctl API in 5.17,
* but retain these definitions so that we can log warnings about them.
@@ -2149,6 +2253,9 @@ xfs_file_ioctl(
return error;
}
+ case XFS_IOC_SETFSUUID:
+ return xfs_ioc_setfsuuid(filp, mp, arg);
+
default:
return -ENOTTY;
}
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index fc61cc024023..d79b6065ee9c 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -3921,3 +3921,22 @@ xlog_drop_incompat_feat(
{
up_read(&log->l_incompat_users);
}
+
+/*
+ * Cycle all the iclog buffers and update the uuid.
+ */
+void
+xlog_iclog_update_uuid(
+ struct xfs_mount *mp)
+{
+ int i;
+ struct xlog *log = mp->m_log;
+ struct xlog_in_core *iclog = log->l_iclog;
+ xlog_rec_header_t *head;
+
+ for (i = 0; i < log->l_iclog_bufs; i++) {
+ head = &iclog->ic_header;
+ memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
+ iclog = iclog->ic_next;
+ }
+}
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 2728886c2963..6b607619163e 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -163,4 +163,6 @@ void xlog_use_incompat_feat(struct xlog *log);
void xlog_drop_incompat_feat(struct xlog *log);
int xfs_attr_use_log_assist(struct xfs_mount *mp);
+void xlog_iclog_update_uuid(struct xfs_mount *mp);
+
#endif /* __XFS_LOG_H__ */
--
2.34.1
next prev parent reply other threads:[~2023-03-14 4:21 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-14 4:21 [PATCH v1 0/4] setting uuid of online filesystems Catherine Hoang
2023-03-14 4:21 ` [PATCH v1 1/4] xfs: refactor xfs_uuid_mount and xfs_uuid_unmount Catherine Hoang
2023-03-14 4:21 ` [PATCH v1 2/4] xfs: implement custom freeze/thaw functions Catherine Hoang
2023-03-14 5:11 ` Amir Goldstein
2023-03-14 5:25 ` Darrick J. Wong
2023-03-14 6:00 ` Amir Goldstein
2023-03-16 5:16 ` Darrick J. Wong
2023-03-14 4:21 ` Catherine Hoang [this message]
2023-03-14 5:50 ` [PATCH v1 3/4] xfs: add XFS_IOC_SETFSUUID ioctl Amir Goldstein
2023-03-15 23:12 ` Catherine Hoang
2023-03-16 8:09 ` Amir Goldstein
2023-03-18 0:39 ` Darrick J. Wong
2023-03-18 9:31 ` Amir Goldstein
2023-03-14 4:21 ` [PATCH v1 4/4] xfs: export meta uuid via xfs_fsop_geom Catherine Hoang
2023-03-14 6:28 ` [PATCH v1 0/4] setting uuid of online filesystems Dave Chinner
2023-03-16 20:41 ` Catherine Hoang
2023-03-19 0:16 ` Dave Chinner
2023-03-28 1:38 ` Darrick J. Wong
2023-03-18 0:11 ` Darrick J. Wong
2023-03-18 9:04 ` Amir Goldstein
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=20230314042109.82161-4-catherine.hoang@oracle.com \
--to=catherine.hoang@oracle.com \
--cc=linux-xfs@vger.kernel.org \
/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