]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - repair/agheader.c
libxfs: refactor manage_zones()
[thirdparty/xfsprogs-dev.git] / repair / agheader.c
index a216afa9bff515e58c6a5575f679bc5d2f08cc05..218ee256a28987a029bcf514690f0a1eacc22822 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include "xfs/libxfs.h"
+#include "libxfs.h"
 #include "globals.h"
 #include "agheader.h"
 #include "protos.h"
@@ -69,7 +57,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)
                                be32_to_cpu(agf->agf_length), i,
                                mp->m_sb.sb_agblocks);
                        if (!no_modify)
-                               agf->agf_length = 
+                               agf->agf_length =
                                        cpu_to_be32(mp->m_sb.sb_agblocks);
                } else  {
                        agblocks = mp->m_sb.sb_dblocks -
@@ -91,18 +79,18 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)
         * check first/last AGF fields.  if need be, lose the free
         * space in the AGFL, we'll reclaim it later.
         */
-       if (be32_to_cpu(agf->agf_flfirst) >= XFS_AGFL_SIZE(mp))  {
-               do_warn(_("flfirst %d in agf %d too large (max = %zu)\n"),
+       if (be32_to_cpu(agf->agf_flfirst) >= libxfs_agfl_size(mp)) {
+               do_warn(_("flfirst %d in agf %d too large (max = %u)\n"),
                        be32_to_cpu(agf->agf_flfirst),
-                       i, XFS_AGFL_SIZE(mp));
+                       i, libxfs_agfl_size(mp) - 1);
                if (!no_modify)
                        agf->agf_flfirst = cpu_to_be32(0);
        }
 
-       if (be32_to_cpu(agf->agf_fllast) >= XFS_AGFL_SIZE(mp))  {
-               do_warn(_("fllast %d in agf %d too large (max = %zu)\n"),
+       if (be32_to_cpu(agf->agf_fllast) >= libxfs_agfl_size(mp)) {
+               do_warn(_("fllast %d in agf %d too large (max = %u)\n"),
                        be32_to_cpu(agf->agf_fllast),
-                       i, XFS_AGFL_SIZE(mp));
+                       i, libxfs_agfl_size(mp) - 1);
                if (!no_modify)
                        agf->agf_fllast = cpu_to_be32(0);
        }
@@ -112,7 +100,7 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return retval;
 
-       if (platform_uuid_compare(&agf->agf_uuid, &mp->m_sb.sb_uuid)) {
+       if (platform_uuid_compare(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) {
                char uu[64];
 
                retval = XR_AG_AGF;
@@ -120,7 +108,8 @@ verify_set_agf(xfs_mount_t *mp, xfs_agf_t *agf, xfs_agnumber_t i)
                do_warn(_("bad uuid %s for agf %d\n"), uu, i);
 
                if (!no_modify)
-                       platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
+                       platform_uuid_copy(&agf->agf_uuid,
+                                          &mp->m_sb.sb_meta_uuid);
        }
        return retval;
 }
@@ -167,7 +156,7 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)
                                be32_to_cpu(agi->agi_length), agno,
                                        mp->m_sb.sb_agblocks);
                        if (!no_modify)
-                               agi->agi_length = 
+                               agi->agi_length =
                                        cpu_to_be32(mp->m_sb.sb_agblocks);
                } else  {
                        agblocks = mp->m_sb.sb_dblocks -
@@ -190,7 +179,7 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return retval;
 
-       if (platform_uuid_compare(&agi->agi_uuid, &mp->m_sb.sb_uuid)) {
+       if (platform_uuid_compare(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) {
                char uu[64];
 
                retval = XR_AG_AGI;
@@ -198,7 +187,8 @@ verify_set_agi(xfs_mount_t *mp, xfs_agi_t *agi, xfs_agnumber_t agno)
                do_warn(_("bad uuid %s for agi %d\n"), uu, agno);
 
                if (!no_modify)
-                       platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid);
+                       platform_uuid_copy(&agi->agi_uuid,
+                                          &mp->m_sb.sb_meta_uuid);
        }
 
        return retval;
@@ -245,7 +235,7 @@ compare_sb(xfs_mount_t *mp, xfs_sb_t *sb)
  * superblocks, not just the secondary superblocks.
  */
 static int
-secondary_sb_wack(
+secondary_sb_whack(
        struct xfs_mount *mp,
        struct xfs_buf  *sbuf,
        struct xfs_sb   *sb,
@@ -255,7 +245,8 @@ secondary_sb_wack(
        int             do_bzero = 0;
        int             size;
        char            *ip;
-       int             rval = 0;;
+       int             rval = 0;
+       uuid_t          tmpuuid;
 
        rval = do_bzero = 0;
 
@@ -267,7 +258,10 @@ secondary_sb_wack(
         *
         * size is the size of data which is valid for this sb.
         */
-       if (xfs_sb_version_hascrc(sb))
+       if (xfs_sb_version_hasmetauuid(sb))
+               size = offsetof(xfs_sb_t, sb_meta_uuid)
+                       + sizeof(sb->sb_meta_uuid);
+       else if (xfs_sb_version_hascrc(sb))
                size = offsetof(xfs_sb_t, sb_lsn)
                        + sizeof(sb->sb_lsn);
        else if (xfs_sb_version_hasmorebits(sb))
@@ -284,8 +278,8 @@ secondary_sb_wack(
                        + sizeof(sb->sb_dirblklog);
 
        /* Check the buffer we read from disk for garbage outside size */
-       for (ip = XFS_BUF_PTR(sbuf) + size;
-            ip < XFS_BUF_PTR(sbuf) + mp->m_sb.sb_sectsize;
+       for (ip = (char *)sbuf->b_addr + size;
+            ip < (char *)sbuf->b_addr + mp->m_sb.sb_sectsize;
             ip++)  {
                if (*ip)  {
                        do_bzero = 1;
@@ -305,10 +299,13 @@ secondary_sb_wack(
                         * be set, and the latter is never updated past
                         * the last field - just zap them both.
                         */
+                       memcpy(&tmpuuid, &sb->sb_meta_uuid, sizeof(uuid_t));
                        memset((void *)((intptr_t)sb + size), 0,
                                mp->m_sb.sb_sectsize - size);
-                       memset(XFS_BUF_PTR(sbuf) + size, 0,
+                       memset((char *)sbuf->b_addr + size, 0,
                                mp->m_sb.sb_sectsize - size);
+                       /* Preserve meta_uuid so we don't fail uuid checks */
+                       memcpy(&sb->sb_meta_uuid, &tmpuuid, sizeof(uuid_t));
                } else
                        do_warn(
        _("would zero unused portion of %s superblock (AG #%u)\n"),
@@ -511,7 +508,7 @@ verify_set_agheader(xfs_mount_t *mp, xfs_buf_t *sbuf, xfs_sb_t *sb,
                rval |= XR_AG_SB;
        }
 
-       rval |= secondary_sb_wack(mp, sbuf, sb, i);
+       rval |= secondary_sb_whack(mp, sbuf, sb, i);
 
        rval |= verify_set_agf(mp, agf, i);
        rval |= verify_set_agi(mp, agi, i);