+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000-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 "libfrog.h"
#include "libxfs.h"
#include <ctype.h>
#include "xfs_multidisk.h"
#include "libxcmd.h"
-
+#include "fsgeom.h"
#define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
const char *value,
const char *opt)
{
- fprintf(stderr, _("Illegal value %s for -%s option\n"), value, opt);
+ fprintf(stderr, _("Invalid value %s for -%s option\n"), value, opt);
usage();
}
const char *reason)
{
fprintf(stderr,
- _("Illegal value %s for -%c %s option. %s\n"),
+ _("Invalid value %s for -%c %s option. %s\n"),
value, opts->name, opts->subopts[index],
- reason ? reason : "");
+ reason);
usage();
}
c = strtoll(str, &str_end, 0);
if (c == 0 && str_end == str)
- illegal_option(str, opts, index, NULL);
+ illegal_option(str, opts, index,
+ _("Value not recognized as number."));
if (*str_end != '\0')
- illegal_option(str, opts, index, NULL);
+ illegal_option(str, opts, index,
+ _("Unit suffixes are not allowed."));
}
/* Validity check the result. */
if (c < sp->minval)
- illegal_option(str, opts, index, _("value is too small"));
+ illegal_option(str, opts, index, _("Value is too small."));
else if (c > sp->maxval)
- illegal_option(str, opts, index, _("value is too large"));
+ illegal_option(str, opts, index, _("Value is too large."));
if (sp->is_power_2 && !ispow2(c))
- illegal_option(str, opts, index, _("value must be a power of 2"));
+ illegal_option(str, opts, index, _("Value must be a power of 2."));
return c;
}
/* inodes always aligned */
if (!cli->sb_feat.inode_align) {
fprintf(stderr,
-_("Inodes always aligned for CRC enabled filesytems\n"));
+_("Inodes always aligned for CRC enabled filesystems\n"));
usage();
}
/* lazy sb counters always on */
if (!cli->sb_feat.lazy_sb_counters) {
fprintf(stderr,
-_("Lazy superblock counted always enabled for CRC enabled filesytems\n"));
+_("Lazy superblock counters always enabled for CRC enabled filesystems\n"));
usage();
}
/* version 2 logs always on */
if (cli->sb_feat.log_version != 2) {
fprintf(stderr,
-_("V2 logs always enabled for CRC enabled filesytems\n"));
+_("V2 logs always enabled for CRC enabled filesystems\n"));
usage();
}
/* attr2 always on */
if (cli->sb_feat.attr_version != 2) {
fprintf(stderr,
-_("V2 attribute format always enabled on CRC enabled filesytems\n"));
+_("V2 attribute format always enabled on CRC enabled filesystems\n"));
usage();
}
/* attr2 always on */
if (!cli->sb_feat.projid32bit) {
fprintf(stderr,
-_("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
+_("32 bit Project IDs always enabled on CRC enabled filesystems\n"));
usage();
}
/* ftype always on */
if (!cli->sb_feat.dirftype) {
fprintf(stderr,
-_("Directory ftype field always enabled on CRC enabled filesytems\n"));
+_("Directory ftype field always enabled on CRC enabled filesystems\n"));
usage();
}
}
cli->sb_feat.finobt = false;
- if (cli->sb_feat.spinodes) {
+ if (cli->sb_feat.spinodes && cli_opt_set(&iopts, I_SPINODES)) {
fprintf(stderr,
_("sparse inodes not supported without CRC support\n"));
usage();
usage();
}
+ if (cli->sb_feat.reflink && cli->xi->rtname) {
+ fprintf(stderr,
+_("reflink not supported with realtime devices\n"));
+ usage();
+ cli->sb_feat.reflink = false;
+ }
+
if (cli->sb_feat.rmapbt && cli->xi->rtname) {
fprintf(stderr,
_("rmapbt not supported with realtime devices\n"));
int maxsz;
fprintf(stderr, _("illegal inode size %d\n"), cfg->inodesize);
- maxsz = MIN(cfg->blocksize / XFS_MIN_INODE_PERBLOCK,
+ maxsz = min(cfg->blocksize / XFS_MIN_INODE_PERBLOCK,
XFS_DINODE_MAX_SIZE);
if (XFS_DINODE_MIN_SIZE == maxsz)
fprintf(stderr,
dsw = cli->dsw;
/* data sunit/swidth options */
- if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
+ if (cli_opt_set(&dopts, D_SUNIT) != cli_opt_set(&dopts, D_SWIDTH)) {
fprintf(stderr,
_("both data sunit and data swidth options must be specified\n"));
usage();
/* convert dsu/dsw to dsunit/dswidth and use them from now on */
if (dsu || dsw) {
- if ((dsu && !dsw) || (!dsu && dsw)) {
+ if (cli_opt_set(&dopts, D_SU) != cli_opt_set(&dopts, D_SW)) {
fprintf(stderr,
_("both data su and data sw options must be specified\n"));
usage();
dswidth = big_dswidth;
}
- if (dsunit && (dswidth % dsunit != 0)) {
+ if ((dsunit && !dswidth) || (!dsunit && dswidth) ||
+ (dsunit && (dswidth % dsunit != 0))) {
fprintf(stderr,
_("data stripe width (%d) must be a multiple of the data stripe unit (%d)\n"),
dswidth, dsunit);
/* if no stripe config set, use the device default */
if (!dsunit) {
- dsunit = ft->dsunit;
- dswidth = ft->dswidth;
- use_dev = true;
+ /* Ignore nonsense from device. XXX add more validation */
+ if (ft->dsunit && ft->dswidth == 0) {
+ fprintf(stderr,
+_("%s: Volume reports stripe unit of %d bytes and stripe width of 0, ignoring.\n"),
+ progname, BBTOB(ft->dsunit));
+ ft->dsunit = 0;
+ ft->dswidth = 0;
+ } else {
+ dsunit = ft->dsunit;
+ dswidth = ft->dswidth;
+ use_dev = true;
+ }
} else {
- /* check and warn is alignment is sub-optimal */
+ /* check and warn if user-specified alignment is sub-optimal */
if (ft->dsunit && ft->dsunit != dsunit) {
fprintf(stderr,
_("%s: Specified data stripe unit %d is not the same as the volume stripe unit %d\n"),
* So, we reduce the size (in basic blocks) to a perfect
* multiple of the sector size, or 1024, whichever is larger.
*/
- sector_mask = (uint64_t)-1 << (MAX(cfg->sectorlog, 10) - BBSHIFT);
+ sector_mask = (uint64_t)-1 << (max(cfg->sectorlog, 10) - BBSHIFT);
xi->dsize &= sector_mask;
xi->rtsize &= sector_mask;
- xi->logBBsize &= (uint64_t)-1 << (MAX(cfg->lsectorlog, 10) - BBSHIFT);
+ xi->logBBsize &= (uint64_t)-1 << (max(cfg->lsectorlog, 10) - BBSHIFT);
if (!discard)
libxfs_umount(&mount);
ASSERT(min_logblocks);
- min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
+ min_logblocks = max(XFS_MIN_LOG_BLOCKS, min_logblocks);
/* if we have lots of blocks, check against XFS_MIN_LOG_BYTES, too */
if (!cli->logsize &&
cfg->dblocks >= (1024*1024*1024) >> cfg->blocklog)
- min_logblocks = MAX(min_logblocks,
+ min_logblocks = max(min_logblocks,
XFS_MIN_LOG_BYTES >> cfg->blocklog);
/*
* XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
* at all possible, ramping up to 128MB at 256GB.
*/
- cfg->logblocks = MIN(XFS_MIN_LOG_BYTES >> cfg->blocklog,
+ cfg->logblocks = min(XFS_MIN_LOG_BYTES >> cfg->blocklog,
min_logblocks * XFS_DFL_LOG_FACTOR);
} else {
/*
}
/* Ensure the chosen size meets minimum log size requirements */
- cfg->logblocks = MAX(min_logblocks, cfg->logblocks);
+ cfg->logblocks = max(min_logblocks, cfg->logblocks);
/*
* Make sure the log fits wholly within an AG
* opened to decide what is the valid maximum size of a log in
* an AG.
*/
- cfg->logblocks = MIN(cfg->logblocks,
+ cfg->logblocks = min(cfg->logblocks,
libxfs_alloc_ag_max_usable(mp) - 1);
/* and now clamp the size to the maximum supported size */
- cfg->logblocks = MIN(cfg->logblocks, XFS_MAX_LOG_BLOCKS);
+ cfg->logblocks = min(cfg->logblocks, XFS_MAX_LOG_BLOCKS);
if ((cfg->logblocks << cfg->blocklog) > XFS_MAX_LOG_BYTES)
cfg->logblocks = XFS_MAX_LOG_BYTES >> cfg->blocklog;
mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
}
-static void
-print_mkfs_cfg(
- struct mkfs_params *cfg,
- char *dfile,
- char *logfile,
- char *rtfile)
-{
- struct sb_feat_args *fp = &cfg->sb_feat;
-
- printf(_(
-"meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
-" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
-" =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u, reflink=%u\n"
-"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
-" =%-22s sunit=%-6u swidth=%u blks\n"
-"naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n"
-"log =%-22s bsize=%-6d blocks=%lld, version=%d\n"
-" =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
-"realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
- dfile, cfg->inodesize, (long long)cfg->agcount,
- (long long)cfg->agsize,
- "", cfg->sectorsize, fp->attr_version, fp->projid32bit,
- "", fp->crcs_enabled, fp->finobt, fp->spinodes, fp->rmapbt,
- fp->reflink,
- "", cfg->blocksize, (long long)cfg->dblocks, cfg->imaxpct,
- "", cfg->dsunit, cfg->dswidth,
- fp->dir_version, cfg->dirblocksize, fp->nci, fp->dirftype,
- logfile, cfg->blocksize, (long long)cfg->logblocks,
- fp->log_version,
- "", cfg->lsectorsize, cfg->lsunit, fp->lazy_sb_counters,
- rtfile, (int)cfg->rtextblocks << cfg->blocklog,
- (long long)cfg->rtblocks, (long long)cfg->rtextents);
-}
-
/*
* Format everything from the generated config into the superblock that
* will be used to initialise the on-disk superblock. This is the in-memory
*/
buf = libxfs_getbuf(mp->m_ddev_targp, (xi->dsize - whack_blks),
whack_blks);
- memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
+ memset(buf->b_addr, 0, WHACK_SIZE);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
libxfs_purgebuf(buf);
* 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);
+ memset(buf->b_addr, 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);
+ memset(buf->b_addr, 0, cfg->sectorsize);
+ libxfs_sb_to_disk(buf->b_addr, sbp);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
libxfs_purgebuf(buf);
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);
+ memset(buf->b_addr, 0, cfg->blocksize);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
libxfs_purgebuf(buf);
}
XFS_AG_DADDR(mp, agno, 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);
+ memset(buf->b_addr, 0, cfg->sectorsize);
+ libxfs_sb_to_disk(buf->b_addr, sbp);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
/*
}
agf->agf_flfirst = 0;
- agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
+ agf->agf_fllast = cpu_to_be32(libxfs_agfl_size(mp) - 1);
agf->agf_flcount = 0;
agblocks = (xfs_agblock_t)(agsize - libxfs_prealloc_blocks(mp));
agf->agf_freeblks = cpu_to_be32(agblocks);
agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
agfl->agfl_seqno = cpu_to_be32(agno);
platform_uuid_copy(&agfl->agfl_uuid, &sbp->sb_uuid);
- for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
+ for (bucket = 0; bucket < libxfs_agfl_size(mp); bucket++)
agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
}
struct xfs_trans_res tres = {0};
int c;
- c = libxfs_trans_alloc(mp, &tres, worst_freelist, 0, 0, &tp);
+ c = -libxfs_trans_alloc(mp, &tres, worst_freelist, 0, 0, &tp);
if (c)
res_failed(c);
.crcs_enabled = true,
.dirftype = true,
.finobt = true,
- .spinodes = false,
+ .spinodes = true,
.rmapbt = false,
.reflink = false,
.parent_pointers = false,
*/
calculate_log_size(&cfg, &cli, mp);
+ finish_superblock_setup(&cfg, mp, sbp);
+
+ /* Print the intended geometry of the fs. */
if (!quiet || dry_run) {
- print_mkfs_cfg(&cfg, dfile, logfile, rtfile);
+ struct xfs_fsop_geom geo;
+ int error;
+
+ error = -libxfs_fs_geometry(sbp, &geo,
+ XFS_FS_GEOM_MAX_STRUCT_VER);
+ if (error) {
+ fprintf(stderr,
+ _("%s: failed to generate filesystem geometry\n"),
+ progname);
+ exit(1);
+ }
+
+ xfs_report_geom(&geo, dfile, logfile, rtfile);
if (dry_run)
exit(0);
}
- finish_superblock_setup(&cfg, mp, sbp);
/*
* we need the libxfs buffer cache from here on in.
if (xi.logdev && xi.logdev != xi.ddev)
libxfs_device_close(xi.logdev);
libxfs_device_close(xi.ddev);
+ libxfs_destroy();
return 0;
}