]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_db: support changing the label and uuid of rt superblocks
authorDarrick J. Wong <djwong@kernel.org>
Wed, 3 Jul 2024 21:22:07 +0000 (14:22 -0700)
committerChristoph Hellwig <hch@lst.de>
Tue, 6 Aug 2024 12:53:50 +0000 (05:53 -0700)
Update the label and uuid commands to change the rt superblocks along
with the filesystem superblocks.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
db/sb.c

diff --git a/db/sb.c b/db/sb.c
index 80ac05c36ec2a2626afd67d0043f7da9d8e69838..7b1c0f6d7d14e2b01eda046ee41be6019e9782b1 100644 (file)
--- a/db/sb.c
+++ b/db/sb.c
@@ -27,6 +27,7 @@ static int    label_f(int argc, char **argv);
 static void     label_help(void);
 static int     version_f(int argc, char **argv);
 static void     version_help(void);
+static size_t check_label(char *label, bool can_warn);
 
 static const cmdinfo_t sb_cmd =
        { "sb", NULL, sb_f, 0, 1, 1, N_("[agno]"),
@@ -339,6 +340,65 @@ uuid_help(void)
 ));
 }
 
+static bool
+check_rtsb(
+       struct xfs_mount        *mp)
+{
+       int                     error;
+
+       if (!xfs_has_rtsb(mp) || !xfs_has_realtime(mp))
+               return false;
+
+       push_cur();
+       error = set_rt_cur(&typtab[TYP_RTSB], XFS_RTSB_DADDR,
+                       XFS_FSB_TO_BB(mp, 1), DB_RING_ADD, NULL);
+       if (error == ENODEV) {
+               /* no rt dev means we should just bail out */
+               pop_cur();
+               return true;
+       }
+
+       pop_cur();
+       return false;
+}
+
+static int
+update_rtsb(
+       struct xfs_mount        *mp,
+       uuid_t                  *uuid,
+       char                    *label)
+{
+       struct xfs_rtsb         *rsb;
+       int                     error;
+
+       if (!xfs_has_rtsb(mp) || !xfs_has_realtime(mp))
+               return false;
+
+       push_cur();
+       error = set_rt_cur(&typtab[TYP_RTSB], XFS_RTSB_DADDR,
+                       XFS_FSB_TO_BB(mp, 1), DB_RING_ADD, NULL);
+       if (error == ENODEV) {
+               /* no rt dev means we should just bail out */
+               exitcode = 1;
+               pop_cur();
+               return 1;
+       }
+
+       rsb = iocur_top->data;
+       if (label) {
+               size_t  len = check_label(label, false);
+
+               memset(&rsb->rsb_fname, 0, XFSLABEL_MAX);
+               memcpy(&rsb->rsb_fname, label, len);
+       }
+       if (uuid)
+               memcpy(&rsb->rsb_uuid, uuid, sizeof(rsb->rsb_uuid));
+       write_cur();
+       pop_cur();
+
+       return 0;
+}
+
 static uuid_t *
 do_uuid(xfs_agnumber_t agno, uuid_t *uuid)
 {
@@ -383,6 +443,7 @@ write:
        memcpy(&tsb.sb_uuid, uuid, sizeof(uuid_t));
        libxfs_sb_to_disk(iocur_top->data, &tsb);
        write_cur();
+       memcpy(&mp->m_sb.sb_uuid, uuid, sizeof(uuid_t));
        return uuid;
 }
 
@@ -445,11 +506,18 @@ uuid_f(
                        }
                }
 
+               if (check_rtsb(mp)) {
+                       exitcode = 1;
+                       return 0;
+               }
+
                /* clear the log (setting uuid) if it's not dirty */
                if (!sb_logzero(&uu))
                        return 0;
 
                dbprintf(_("writing all SBs\n"));
+               if (update_rtsb(mp, &uu, NULL))
+                       return 1;
                for (agno = 0; agno < mp->m_sb.sb_agcount; agno++)
                        if (!do_uuid(agno, &uu)) {
                                dbprintf(_("failed to set UUID in AG %d\n"), agno);
@@ -518,6 +586,27 @@ label_help(void)
 ));
 }
 
+static size_t
+check_label(
+       char    *label,
+       bool    can_warn)
+{
+       size_t  len = strlen(label);
+
+       if (len > XFSLABEL_MAX) {
+               if (can_warn)
+                       dbprintf(_("%s: truncating label length from %d to %d\n"),
+                               progname, (int)len, XFSLABEL_MAX);
+               len = XFSLABEL_MAX;
+       }
+       if ( len == 2 &&
+            (strcmp(label, "\"\"") == 0 ||
+             strcmp(label, "''")   == 0 ||
+             strcmp(label, "--")   == 0) )
+               label[0] = label[1] = '\0';
+       return len;
+}
+
 static char *
 do_label(xfs_agnumber_t agno, char *label)
 {
@@ -536,22 +625,13 @@ do_label(xfs_agnumber_t agno, char *label)
                return &lbl[0];
        }
        /* set label */
-       if ((len = strlen(label)) > sizeof(tsb.sb_fname)) {
-               if (agno == 0)
-                       dbprintf(_("%s: truncating label length from %d to %d\n"),
-                               progname, (int)len, (int)sizeof(tsb.sb_fname));
-               len = sizeof(tsb.sb_fname);
-       }
-       if ( len == 2 &&
-            (strcmp(label, "\"\"") == 0 ||
-             strcmp(label, "''")   == 0 ||
-             strcmp(label, "--")   == 0) )
-               label[0] = label[1] = '\0';
+       len = check_label(label, agno == 0);
        memset(&tsb.sb_fname, 0, sizeof(tsb.sb_fname));
        memcpy(&tsb.sb_fname, label, len);
        memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname));
        libxfs_sb_to_disk(iocur_top->data, &tsb);
        write_cur();
+       memcpy(&mp->m_sb.sb_fname, &tsb.sb_fname, XFSLABEL_MAX);
        return &lbl[0];
 }
 
@@ -583,7 +663,14 @@ label_f(
                        return 0;
                }
 
+               if (check_rtsb(mp)) {
+                       exitcode = 1;
+                       return 0;
+               }
+
                dbprintf(_("writing all SBs\n"));
+               if (update_rtsb(mp, NULL, argv[1]))
+                       return 1;
                for (ag = 0; ag < mp->m_sb.sb_agcount; ag++)
                        if ((p = do_label(ag, argv[1])) == NULL) {
                                dbprintf(_("failed to set label in AG %d\n"), ag);