{
struct xfs_sb *sbp;
struct xfs_buf *bp;
+ unsigned int agcount;
int c;
setlocale(LC_ALL, "");
}
}
+ agcount = sbp->sb_agcount;
mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev,
LIBXFS_MOUNT_DEBUGGER);
if (!mp) {
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
*/
return 0;
}
+ /*
+ * on load, we sanity-checked agcount and possibly set to 1
+ * if it was corrupted and large.
+ */
+ if (mp->m_sb.sb_agcount == 1 &&
+ XFS_MAX_DBLOCKS(&mp->m_sb) < mp->m_sb.sb_dblocks) {
+ print_warning("truncated agcount, giving up");
+ return 0;
+ }
+
while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
switch (c) {
case 'a':
return NULL;
}
+ /*
+ * libxfs_initialize_perag will allocate a perag structure for each ag.
+ * If agcount is corrupted and insanely high, this will OOM the box.
+ * If the agount seems (arbitrarily) high, try to read what would be
+ * the last AG, and if that fails for a relatively high agcount, just
+ * read the first one and let the user know to check the geometry.
+ */
+ if (sbp->sb_agcount > 1000000) {
+ bp = libxfs_readbuf(mp->m_dev,
+ XFS_AG_DADDR(mp, sbp->sb_agcount - 1, 0), 1,
+ !(flags & LIBXFS_MOUNT_DEBUGGER), NULL);
+ if (bp->b_error) {
+ fprintf(stderr, _("%s: read of AG %u failed\n"),
+ progname, sbp->sb_agcount);
+ if (!(flags & LIBXFS_MOUNT_DEBUGGER))
+ return NULL;
+ fprintf(stderr, _("%s: limiting reads to AG 0\n"),
+ progname);
+ sbp->sb_agcount = 1;
+ }
+ libxfs_putbuf(bp);
+ }
+
error = libxfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
if (error) {
fprintf(stderr, _("%s: perag init failed\n"),