]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - db/init.c
mkfs: validate extent size hint parameters
[thirdparty/xfsprogs-dev.git] / db / init.c
index d73d5490d57870058fd4034a5d5a075a1e180d8b..455220a866f9fbe495be2f2eea5c05d264e43a89 100644 (file)
--- a/db/init.c
+++ b/db/init.c
@@ -1,22 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2000-2002,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 "libxlog.h"
 #include <signal.h>
 #include "command.h"
 #include "init.h"
 #include "malloc.h"
 #include "type.h"
 
-static char    **cmdline;
-static int     ncmdline;
-char           *fsdevice;
-int            blkbb;
-int            exitcode;
-int            expert_mode;
-int            force;
-xfs_mount_t    xmount;
-xfs_mount_t    *mp;
-libxfs_init_t  x;
-xfs_agnumber_t cur_agno = NULLAGNUMBER;
+static char            **cmdline;
+static int             ncmdline;
+char                   *fsdevice;
+int                    blkbb;
+int                    exitcode;
+int                    expert_mode;
+static int             force;
+static struct xfs_mount        xmount;
+struct xfs_mount       *mp;
+static struct xlog     xlog;
+libxfs_init_t          x;
+xfs_agnumber_t         cur_agno = NULLAGNUMBER;
 
 static void
 usage(void)
@@ -49,13 +39,14 @@ usage(void)
        exit(1);
 }
 
-void
+static void
 init(
        int             argc,
        char            **argv)
 {
-       xfs_sb_t        *sbp;
-       void            *bufp = NULL;
+       struct xfs_sb   *sbp;
+       struct xfs_buf  *bp;
+       unsigned int    agcount;
        int             c;
 
        setlocale(LC_ALL, "");
@@ -109,45 +100,44 @@ init(
        else
                x.dname = fsdevice;
 
+       x.bcache_flags = CACHE_MISCOMPARE_PURGE;
        if (!libxfs_init(&x)) {
                fputs(_("\nfatal error -- couldn't initialize XFS library\n"),
                        stderr);
                exit(1);
        }
 
-       if (read_bbs(XFS_SB_DADDR, 1, &bufp, NULL)) {
+       /*
+        * Read the superblock, but don't validate it - we are a diagnostic
+        * tool and so need to be able to mount busted filesystems.
+        */
+       memset(&xmount, 0, sizeof(struct xfs_mount));
+       libxfs_buftarg_init(&xmount, x.ddev, x.logdev, x.rtdev);
+       bp = libxfs_readbuf(xmount.m_ddev_targp, XFS_SB_DADDR,
+                           1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0, NULL);
+
+       if (!bp || bp->b_error) {
                fprintf(stderr, _("%s: %s is invalid (cannot read first 512 "
                        "bytes)\n"), progname, fsdevice);
                exit(1);
        }
 
        /* copy SB from buffer to in-core, converting architecture as we go */
-       libxfs_sb_from_disk(&xmount.m_sb, bufp);
-       xfree(bufp);
+       libxfs_sb_from_disk(&xmount.m_sb, XFS_BUF_TO_SBP(bp));
+       libxfs_putbuf(bp);
+       libxfs_purgebuf(bp);
 
        sbp = &xmount.m_sb;
        if (sbp->sb_magicnum != XFS_SB_MAGIC) {
                fprintf(stderr, _("%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n"),
                        progname, fsdevice, sbp->sb_magicnum);
-               if (!force)
-                       exit(EXIT_FAILURE);
-       }
-
-       /*
-        * Don't allow modifications to CRC enabled filesystems until we support
-        * CRC recalculation in the IO path. Unless, of course, the user is in
-        * the process of hitting us with a big hammer.
-        */
-       if (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_5 &&
-           !(x.isreadonly & LIBXFS_ISREADONLY)) {
-               fprintf(stderr, 
-       _("%s: modifications to %s are not supported in thi version.\n"
-       "Use \"-r\" to run %s in read-only mode on this filesystem .\n"),
-                       progname, fsdevice, progname);
-               if (!force)
+               if (!force) {
+                       fprintf(stderr, _("Use -F to force a read attempt.\n"));
                        exit(EXIT_FAILURE);
+               }
        }
 
+       agcount = sbp->sb_agcount;
        mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev,
                          LIBXFS_MOUNT_DEBUGGER);
        if (!mp) {
@@ -156,14 +146,19 @@ init(
                        progname, fsdevice);
                exit(1);
        }
+       mp->m_log = &xlog;
        blkbb = 1 << mp->m_blkbb_log;
 
+       /* Did we limit a broken agcount in libxfs_mount? */
+       if (sbp->sb_agcount != agcount)
+               exitcode = 1;
+
        /*
         * xfs_check needs corrected incore superblock values
         */
        if (sbp->sb_rootino != NULLFSINO &&
            xfs_sb_version_haslazysbcount(&mp->m_sb)) {
-               int error = xfs_initialize_perag_data(mp, sbp->sb_agcount);
+               int error = -libxfs_initialize_perag_data(mp, sbp->sb_agcount);
                if (error) {
                        fprintf(stderr,
        _("%s: cannot init perag data (%d). Continuing anyway.\n"),
@@ -171,7 +166,9 @@ init(
                }
        }
 
-       if (xfs_sb_version_hascrc(&mp->m_sb))
+       if (xfs_sb_version_hassparseinodes(&mp->m_sb))
+               type_set_tab_spcrc();
+       else if (xfs_sb_version_hascrc(&mp->m_sb))
                type_set_tab_crc();
 
        push_cur();
@@ -187,9 +184,10 @@ main(
        int     c, i, done = 0;
        char    *input;
        char    **v;
+       int     start_iocur_sp;
 
-       pushfile(stdin);
        init(argc, argv);
+       start_iocur_sp = iocur_sp;
 
        for (i = 0; !done && i < ncmdline; i++) {
                v = breakline(cmdline[i], &c);
@@ -202,6 +200,7 @@ main(
                goto close_devices;
        }
 
+       pushfile(stdin);
        while (!done) {
                if ((input = fetchline()) == NULL)
                        break;
@@ -212,11 +211,20 @@ main(
        }
 
 close_devices:
+       /*
+        * Make sure that we pop the all the buffer contexts we hold so that
+        * they are released before we purge the caches during unmount.
+        */
+       while (iocur_sp > start_iocur_sp)
+               pop_cur();
+       libxfs_umount(mp);
        if (x.ddev)
                libxfs_device_close(x.ddev);
        if (x.logdev && x.logdev != x.ddev)
                libxfs_device_close(x.logdev);
        if (x.rtdev)
                libxfs_device_close(x.rtdev);
+       libxfs_destroy();
+
        return exitcode;
 }