aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2017-12-06 17:14:27 -0600
committerEric Sandeen <sandeen@redhat.com>2017-12-06 17:14:27 -0600
commite99bf83d96b805e142010ea91dfee83cdf8b4248 (patch)
tree73e05305bea58a9deea3e72dfcba59cc9dd78a85
parentafda75a52911fa2bd4e7a06e00ddb78ec8e0efa7 (diff)
downloadxfsprogs-dev-e99bf83d96b805e142010ea91dfee83cdf8b4248.tar.gz
mkfs: factor out device preparation
Prior to formating the device(s), we have to take several steps to prepare them and check that they are appropriate for the formatting that is about to take place. Pull all this into a single function that is run before mounting the libxfs infrastructure. Signed-Off-By: Dave Chinner <dchinner@redhat.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r--mkfs/xfs_mkfs.c172
1 files changed, 101 insertions, 71 deletions
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index bdabdea593..95032e3101 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2009,6 +2009,102 @@ setup_superblock(
}
}
+/*
+ * Sanitise the data and log devices and prepare them so libxfs can mount the
+ * device successfully. Also check we can access the rt device if configured.
+ */
+static void
+prepare_devices(
+ struct mkfs_params *cfg,
+ struct libxfs_xinit *xi,
+ struct xfs_mount *mp,
+ struct xfs_sb *sbp,
+ bool clear_stale)
+{
+ struct xfs_buf *buf;
+ int whack_blks = BTOBB(WHACK_SIZE);
+ int lsunit;
+
+ /*
+ * If there's an old XFS filesystem on the device with enough intact
+ * information that we can parse the superblock, there's enough
+ * information on disk to confuse a future xfs_repair call. To avoid
+ * this, whack all the old secondary superblocks that we can find.
+ */
+ if (clear_stale)
+ zero_old_xfs_structures(xi, sbp);
+
+ /*
+ * If the data device is a file, grow out the file to its final size if
+ * needed so that the reads for the end of the device in the mount code
+ * will succeed.
+ */
+ if (xi->disfile &&
+ xi->dsize * xi->dbsize < cfg->dblocks * cfg->blocksize) {
+ if (ftruncate(xi->dfd, cfg->dblocks * cfg->blocksize) < 0) {
+ fprintf(stderr,
+ _("%s: Growing the data section failed\n"),
+ progname);
+ exit(1);
+ }
+
+ /* update size to be able to whack blocks correctly */
+ xi->dsize = BTOBB(cfg->dblocks * cfg->blocksize);
+ }
+
+ /*
+ * Zero out the end to obliterate any old MD RAID (or other) metadata at
+ * the end of the device. (MD sb is ~64k from the end, take out a wider
+ * swath to be sure)
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp, (xi->dsize - whack_blks),
+ whack_blks);
+ memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ libxfs_purgebuf(buf);
+
+ /*
+ * Now zero out the beginning of the device, to obliterate any old
+ * filesystem signatures out there. This should take care of
+ * swap (somewhere around the page size), jfs (32k),
+ * ext[2,3] and reiserfs (64k) - and hopefully all else.
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp, 0, whack_blks);
+ memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ libxfs_purgebuf(buf);
+
+ /* OK, now write the superblock... */
+ buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
+ buf->b_ops = &xfs_sb_buf_ops;
+ memset(XFS_BUF_PTR(buf), 0, cfg->sectorsize);
+ libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ libxfs_purgebuf(buf);
+
+ /* ...and zero the log.... */
+ lsunit = sbp->sb_logsunit;
+ if (lsunit == 1)
+ lsunit = sbp->sb_logsectsize;
+
+ libxfs_log_clear(mp->m_logdev_targp, NULL,
+ XFS_FSB_TO_DADDR(mp, cfg->logstart),
+ (xfs_extlen_t)XFS_FSB_TO_BB(mp, cfg->logblocks),
+ &sbp->sb_uuid, cfg->sb_feat.log_version,
+ lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
+
+ /* finally, check we can write the last block in the realtime area */
+ if (mp->m_rtdev_targp->dev && cfg->rtblocks > 0) {
+ buf = libxfs_getbuf(mp->m_rtdev_targp,
+ XFS_FSB_TO_BB(mp, cfg->rtblocks - 1LL),
+ BTOBB(cfg->blocksize));
+ memset(XFS_BUF_PTR(buf), 0, cfg->blocksize);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ libxfs_purgebuf(buf);
+ }
+
+}
+
int
main(
int argc,
@@ -3197,65 +3293,17 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
*/
setup_superblock(&cfg, mp, sbp);
- if (force_overwrite)
- zero_old_xfs_structures(&xi, sbp);
-
/*
- * Zero out the beginning of the device, to obliterate any old
- * filesystem signatures out there. This should take care of
- * swap (somewhere around the page size), jfs (32k),
- * ext[2,3] and reiserfs (64k) - and hopefully all else.
+ * we need the libxfs buffer cache from here on in.
*/
libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev);
- buf = libxfs_getbuf(mp->m_ddev_targp, 0, BTOBB(WHACK_SIZE));
- memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
- libxfs_purgebuf(buf);
-
- /* OK, now write the superblock */
- buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
- buf->b_ops = &xfs_sb_buf_ops;
- memset(XFS_BUF_PTR(buf), 0, sectorsize);
- libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
- libxfs_purgebuf(buf);
/*
- * If the data area is a file, then grow it out to its final size
- * if needed so that the reads for the end of the device in the mount
- * code will succeed.
+ * Before we mount the filesystem we need to make sure the devices have
+ * enough of the filesystem structure on them that allows libxfs to
+ * mount.
*/
- if (xi.disfile && xi.dsize * xi.dbsize < dblocks * blocksize) {
- if (ftruncate(xi.dfd, dblocks * blocksize) < 0) {
- fprintf(stderr,
- _("%s: Growing the data section failed\n"),
- progname);
- exit(1);
- }
- }
-
- /*
- * Zero out the end of the device, to obliterate any
- * old MD RAID (or other) metadata at the end of the device.
- * (MD sb is ~64k from the end, take out a wider swath to be sure)
- */
- if (!xi.disfile) {
- buf = libxfs_getbuf(mp->m_ddev_targp,
- (xi.dsize - BTOBB(WHACK_SIZE)),
- BTOBB(WHACK_SIZE));
- memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
- libxfs_purgebuf(buf);
- }
-
- /*
- * Zero the log....
- */
- libxfs_log_clear(mp->m_logdev_targp, NULL,
- XFS_FSB_TO_DADDR(mp, logstart),
- (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks),
- &sbp->sb_uuid, sb_feat.log_version, lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
-
+ prepare_devices(&cfg, &xi, mp, sbp, force_overwrite);
mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
if (mp == NULL) {
fprintf(stderr, _("%s: filesystem failed to initialize\n"),
@@ -3599,24 +3647,6 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
}
/*
- * Touch last block, make fs the right size if it's a file.
- */
- buf = libxfs_getbuf(mp->m_ddev_targp,
- (xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize);
- memset(XFS_BUF_PTR(buf), 0, blocksize);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
-
- /*
- * Make sure we can write the last block in the realtime area.
- */
- if (mp->m_rtdev_targp->dev && rtblocks > 0) {
- buf = libxfs_getbuf(mp->m_rtdev_targp,
- XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize);
- memset(XFS_BUF_PTR(buf), 0, blocksize);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
- }
-
- /*
* BNO, CNT free block list
*/
for (agno = 0; agno < agcount; agno++) {