2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "xfs_multidisk.h"
25 * Prototypes for internal functions.
27 static void conflict(char opt
, char *tab
[], int oldidx
, int newidx
);
28 static void illegal(const char *value
, const char *opt
);
29 static __attribute__((noreturn
)) void usage (void);
30 static __attribute__((noreturn
)) void reqval(char opt
, char *tab
[], int idx
);
31 static void respec(char opt
, char *tab
[], int idx
);
32 static void unknown(char opt
, char *s
);
33 static int ispow2(unsigned int i
);
36 * The configured block and sector sizes are defined as global variables so
37 * that they don't need to be passed to functions that require them.
39 unsigned int blocksize
;
40 unsigned int sectorsize
;
42 #define MAX_SUBOPTS 16
43 #define SUBOPT_NEEDS_VAL (-1LL)
44 #define MAX_CONFLICTS 8
45 #define LAST_CONFLICT (-1)
48 * Table for parsing mkfs parameters.
50 * Description of the structure members follows:
53 * Name is a single char, e.g., for '-d file', name is 'd'.
56 * Subopts is a list of strings naming suboptions. In the example above,
57 * it would contain "file". The last entry of this list has to be NULL.
59 * subopt_params MANDATORY
60 * This is a list of structs tied with subopts. For each entry in subopts,
61 * a corresponding entry has to be defined:
63 * subopt_params struct:
65 * This number, starting from zero, denotes which item in subopt_params
66 * it is. The index has to be the same as is the order in subopts list,
67 * so we can access the right item both in subopt_param and subopts.
70 * Do not set this flag when definning a subopt. It is used to remeber that
71 * this subopt was already seen, for example for conflicts detection.
74 * Do not set. It is used internally for respecification, when some options
75 * has to be parsed twice - at first as a string, then later as a number.
78 * A flag signalling whether the user-given value can use suffixes.
79 * If you want to allow the use of user-friendly values like 13k, 42G,
83 * An optional flag for subopts where the given value has to be a power
87 * If your subopt is in a conflict with some other option, specify it.
88 * Accepts the .index values of the conflicting subopts and the last
89 * member of this list has to be LAST_CONFLICT.
91 * minval, maxval OPTIONAL
92 * These options are used for automatic range check and they have to be
93 * always used together in pair. If you don't want to limit the max value,
94 * use something like UINT_MAX. If no value is given, then you must either
95 * supply your own validation, or refuse any value in the 'case
96 * X_SOMETHING' block. If you forget to define the min and max value, but
97 * call a standard function for validating user's value, it will cause an
98 * error message notifying you about this issue.
100 * (Said in another way, you can't have minval and maxval both equal
101 * to zero. But if one value is different: minval=0 and maxval=1,
104 * defaultval MANDATORY
105 * The value used if user specifies the subopt, but no value.
106 * If the subopt accepts some values (-d file=[1|0]), then this
107 * sets what is used with simple specifying the subopt (-d file).
108 * A special SUBOPT_NEEDS_VAL can be used to require a user-given
113 const char *subopts
[MAX_SUBOPTS
];
115 struct subopt_param
{
121 int conflicts
[MAX_CONFLICTS
];
124 long long defaultval
;
125 } subopt_params
[MAX_SUBOPTS
];
128 struct opt_params bopts
= {
139 .conflicts
= { B_SIZE
,
141 .minval
= XFS_MIN_BLOCKSIZE_LOG
,
142 .maxval
= XFS_MAX_BLOCKSIZE_LOG
,
143 .defaultval
= SUBOPT_NEEDS_VAL
,
148 .conflicts
= { B_LOG
,
150 .minval
= XFS_MIN_BLOCKSIZE
,
151 .maxval
= XFS_MAX_BLOCKSIZE
,
152 .defaultval
= SUBOPT_NEEDS_VAL
,
157 struct opt_params dopts
= {
180 #define D_SECTSIZE 10
184 #define D_RTINHERIT 12
186 #define D_PROJINHERIT 13
188 #define D_EXTSZINHERIT 14
193 { .index
= D_AGCOUNT
,
194 .conflicts
= { D_AGSIZE
,
197 .maxval
= XFS_MAX_AGNUMBER
,
198 .defaultval
= SUBOPT_NEEDS_VAL
,
201 .conflicts
= { LAST_CONFLICT
},
207 .conflicts
= { LAST_CONFLICT
},
208 .defaultval
= SUBOPT_NEEDS_VAL
,
211 .conflicts
= { LAST_CONFLICT
},
213 .minval
= XFS_AG_MIN_BYTES
,
215 .defaultval
= SUBOPT_NEEDS_VAL
,
218 .conflicts
= { D_NOALIGN
,
224 .defaultval
= SUBOPT_NEEDS_VAL
,
227 .conflicts
= { D_NOALIGN
,
233 .defaultval
= SUBOPT_NEEDS_VAL
,
236 .conflicts
= { D_AGCOUNT
,
239 .minval
= XFS_AG_MIN_BYTES
,
240 .maxval
= XFS_AG_MAX_BYTES
,
241 .defaultval
= SUBOPT_NEEDS_VAL
,
244 .conflicts
= { D_NOALIGN
,
251 .defaultval
= SUBOPT_NEEDS_VAL
,
254 .conflicts
= { D_NOALIGN
,
260 .defaultval
= SUBOPT_NEEDS_VAL
,
262 { .index
= D_SECTLOG
,
263 .conflicts
= { D_SECTSIZE
,
265 .minval
= XFS_MIN_SECTORSIZE_LOG
,
266 .maxval
= XFS_MAX_SECTORSIZE_LOG
,
267 .defaultval
= SUBOPT_NEEDS_VAL
,
269 { .index
= D_SECTSIZE
,
270 .conflicts
= { D_SECTLOG
,
274 .minval
= XFS_MIN_SECTORSIZE
,
275 .maxval
= XFS_MAX_SECTORSIZE
,
276 .defaultval
= SUBOPT_NEEDS_VAL
,
278 { .index
= D_NOALIGN
,
288 { .index
= D_RTINHERIT
,
289 .conflicts
= { LAST_CONFLICT
},
294 { .index
= D_PROJINHERIT
,
295 .conflicts
= { LAST_CONFLICT
},
298 .defaultval
= SUBOPT_NEEDS_VAL
,
300 { .index
= D_EXTSZINHERIT
,
301 .conflicts
= { LAST_CONFLICT
},
304 .defaultval
= SUBOPT_NEEDS_VAL
,
310 struct opt_params iopts
= {
325 #define I_PROJID32BIT 6
333 .conflicts
= { LAST_CONFLICT
},
339 .conflicts
= { I_PERBLOCK
,
342 .minval
= XFS_DINODE_MIN_LOG
,
343 .maxval
= XFS_DINODE_MAX_LOG
,
344 .defaultval
= SUBOPT_NEEDS_VAL
,
347 .conflicts
= { LAST_CONFLICT
},
350 .defaultval
= SUBOPT_NEEDS_VAL
,
352 { .index
= I_PERBLOCK
,
353 .conflicts
= { I_LOG
,
357 .minval
= XFS_MIN_INODE_PERBLOCK
,
358 .maxval
= XFS_MAX_BLOCKSIZE
/ XFS_DINODE_MIN_SIZE
,
359 .defaultval
= SUBOPT_NEEDS_VAL
,
362 .conflicts
= { I_PERBLOCK
,
366 .minval
= XFS_DINODE_MIN_SIZE
,
367 .maxval
= XFS_DINODE_MAX_SIZE
,
368 .defaultval
= SUBOPT_NEEDS_VAL
,
371 .conflicts
= { LAST_CONFLICT
},
374 .defaultval
= SUBOPT_NEEDS_VAL
,
376 { .index
= I_PROJID32BIT
,
377 .conflicts
= { LAST_CONFLICT
},
382 { .index
= I_SPINODES
,
383 .conflicts
= { LAST_CONFLICT
},
391 struct opt_params lopts
= {
416 #define L_LAZYSBCNTR 11
422 .conflicts
= { L_DEV
,
426 .defaultval
= SUBOPT_NEEDS_VAL
,
428 { .index
= L_INTERNAL
,
429 .conflicts
= { L_FILE
,
437 .conflicts
= { LAST_CONFLICT
},
439 .minval
= 2 * 1024 * 1024LL, /* XXX: XFS_MIN_LOG_BYTES */
440 .maxval
= XFS_MAX_LOG_BYTES
,
441 .defaultval
= SUBOPT_NEEDS_VAL
,
443 { .index
= L_VERSION
,
444 .conflicts
= { LAST_CONFLICT
},
447 .defaultval
= SUBOPT_NEEDS_VAL
,
453 .maxval
= BTOBB(XLOG_MAX_RECORD_BSIZE
),
454 .defaultval
= SUBOPT_NEEDS_VAL
,
457 .conflicts
= { L_SUNIT
,
461 .maxval
= XLOG_MAX_RECORD_BSIZE
,
462 .defaultval
= SUBOPT_NEEDS_VAL
,
465 .conflicts
= { L_AGNUM
,
468 .defaultval
= SUBOPT_NEEDS_VAL
,
470 { .index
= L_SECTLOG
,
471 .conflicts
= { L_SECTSIZE
,
473 .minval
= XFS_MIN_SECTORSIZE_LOG
,
474 .maxval
= XFS_MAX_SECTORSIZE_LOG
,
475 .defaultval
= SUBOPT_NEEDS_VAL
,
477 { .index
= L_SECTSIZE
,
478 .conflicts
= { L_SECTLOG
,
482 .minval
= XFS_MIN_SECTORSIZE
,
483 .maxval
= XFS_MAX_SECTORSIZE
,
484 .defaultval
= SUBOPT_NEEDS_VAL
,
487 .conflicts
= { L_INTERNAL
,
494 .conflicts
= { L_AGNUM
,
497 .defaultval
= SUBOPT_NEEDS_VAL
,
499 { .index
= L_LAZYSBCNTR
,
500 .conflicts
= { LAST_CONFLICT
},
508 struct opt_params nopts
= {
523 .conflicts
= { N_SIZE
,
525 .minval
= XFS_MIN_REC_DIRSIZE
,
526 .maxval
= XFS_MAX_BLOCKSIZE_LOG
,
527 .defaultval
= SUBOPT_NEEDS_VAL
,
530 .conflicts
= { N_LOG
,
534 .minval
= 1 << XFS_MIN_REC_DIRSIZE
,
535 .maxval
= XFS_MAX_BLOCKSIZE
,
536 .defaultval
= SUBOPT_NEEDS_VAL
,
538 { .index
= N_VERSION
,
539 .conflicts
= { LAST_CONFLICT
},
542 .defaultval
= SUBOPT_NEEDS_VAL
,
545 .conflicts
= { LAST_CONFLICT
},
553 struct opt_params ropts
= {
571 { .index
= R_EXTSIZE
,
572 .conflicts
= { LAST_CONFLICT
},
574 .minval
= XFS_MIN_RTEXTSIZE
,
575 .maxval
= XFS_MAX_RTEXTSIZE
,
576 .defaultval
= SUBOPT_NEEDS_VAL
,
579 .conflicts
= { LAST_CONFLICT
},
583 .defaultval
= SUBOPT_NEEDS_VAL
,
586 .conflicts
= { LAST_CONFLICT
},
587 .defaultval
= SUBOPT_NEEDS_VAL
,
593 .conflicts
= { LAST_CONFLICT
},
596 .conflicts
= { LAST_CONFLICT
},
597 .defaultval
= SUBOPT_NEEDS_VAL
,
599 { .index
= R_NOALIGN
,
603 .conflicts
= { LAST_CONFLICT
},
608 struct opt_params sopts
= {
623 .conflicts
= { S_SIZE
,
626 .minval
= XFS_MIN_SECTORSIZE_LOG
,
627 .maxval
= XFS_MAX_SECTORSIZE_LOG
,
628 .defaultval
= SUBOPT_NEEDS_VAL
,
630 { .index
= S_SECTLOG
,
631 .conflicts
= { S_SIZE
,
634 .minval
= XFS_MIN_SECTORSIZE_LOG
,
635 .maxval
= XFS_MAX_SECTORSIZE_LOG
,
636 .defaultval
= SUBOPT_NEEDS_VAL
,
639 .conflicts
= { S_LOG
,
644 .minval
= XFS_MIN_SECTORSIZE
,
645 .maxval
= XFS_MAX_SECTORSIZE
,
646 .defaultval
= SUBOPT_NEEDS_VAL
,
648 { .index
= S_SECTSIZE
,
649 .conflicts
= { S_LOG
,
654 .minval
= XFS_MIN_SECTORSIZE
,
655 .maxval
= XFS_MAX_SECTORSIZE
,
656 .defaultval
= SUBOPT_NEEDS_VAL
,
661 struct opt_params mopts
= {
678 .conflicts
= { LAST_CONFLICT
},
684 .conflicts
= { LAST_CONFLICT
},
690 .conflicts
= { LAST_CONFLICT
},
691 .defaultval
= SUBOPT_NEEDS_VAL
,
694 .conflicts
= { LAST_CONFLICT
},
699 { .index
= M_REFLINK
,
700 .conflicts
= { LAST_CONFLICT
},
708 #define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
709 #define GIGABYTES(count, blog) ((uint64_t)(count) << (30 - (blog)))
710 #define MEGABYTES(count, blog) ((uint64_t)(count) << (20 - (blog)))
713 * Use this macro before we have superblock and mount structure
715 #define DTOBT(d) ((xfs_rfsblock_t)((d) >> (blocklog - BBSHIFT)))
718 * Use this for block reservations needed for mkfs's conditions
719 * (basically no fragmentation).
721 #define MKFS_BLOCKRES_INODE \
722 ((uint)(mp->m_ialloc_blks + (mp->m_in_maxlevels - 1)))
723 #define MKFS_BLOCKRES(rb) \
724 ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \
725 (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb)))
727 /* amount (in bytes) we zero at the beginning and end of the device to
728 * remove traces of other filesystems, raid superblocks, etc.
730 #define WHACK_SIZE (128 * 1024)
733 * Convert lsu to lsunit for 512 bytes blocks and check validity of the values.
746 /* Handle data sunit/swidth options */
747 if ((*dsunit
&& !*dswidth
) || (!*dsunit
&& *dswidth
)) {
749 _("both data sunit and data swidth options "
750 "must be specified\n"));
755 if ((dsu
&& !dsw
) || (!dsu
&& dsw
)) {
757 _("both data su and data sw options "
758 "must be specified\n"));
764 _("data su must be a multiple of the "
765 "sector size (%d)\n"), dsectsz
);
769 *dsunit
= (int)BTOBBT(dsu
);
770 *dswidth
= *dsunit
* dsw
;
773 if (*dsunit
&& (*dswidth
% *dsunit
!= 0)) {
775 _("data stripe width (%d) must be a multiple of the "
776 "data stripe unit (%d)\n"), *dswidth
, *dsunit
);
780 /* Handle log sunit options */
783 *lsunit
= (int)BTOBBT(lsu
);
785 /* verify if lsu/lsunit is a multiple block size */
786 if (lsu
% blocksize
!= 0) {
788 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
792 if ((BBTOB(*lsunit
) % blocksize
!= 0)) {
794 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
795 BBTOB(*lsunit
), blocksize
);
807 bool force_overwrite
,
812 if (*isfile
&& (no_size
|| no_name
)) {
814 _("if -%s file then -%s name and -%s size are required\n"),
815 optname
, optname
, optname
);
820 fprintf(stderr
, _("No device name specified\n"));
824 if (stat(name
, &statbuf
)) {
825 if (errno
== ENOENT
&& *isfile
) {
832 _("Error accessing specified device %s: %s\n"),
833 name
, strerror(errno
));
838 if (!force_overwrite
&& check_overwrite(name
)) {
840 _("%s: Use the -f option to force overwrite.\n"),
846 * We only want to completely truncate and recreate an existing file if
847 * we were specifically told it was a file. Set the create flag only in
848 * this case to trigger that behaviour.
850 if (S_ISREG(statbuf
.st_mode
)) {
858 if (S_ISBLK(statbuf
.st_mode
)) {
861 _("specified \"-%s file\" on a block device %s\n"),
869 _("specified device %s not a file or block device\n"),
875 fixup_log_stripe_unit(
878 xfs_rfsblock_t
*logblocks
,
881 uint64_t tmp_logblocks
;
884 * Make sure that the log size is a multiple of the stripe unit
886 if ((*logblocks
% sunit
) != 0) {
888 tmp_logblocks
= ((*logblocks
+ (sunit
- 1))
891 * If the log is too large, round down
892 * instead of round up
894 if ((tmp_logblocks
> XFS_MAX_LOG_BLOCKS
) ||
895 ((tmp_logblocks
<< blocklog
) > XFS_MAX_LOG_BYTES
)) {
896 tmp_logblocks
= (*logblocks
/ sunit
) * sunit
;
898 *logblocks
= tmp_logblocks
;
900 fprintf(stderr
, _("log size %lld is not a multiple "
901 "of the log stripe unit %d\n"),
902 (long long) *logblocks
, sunit
);
909 fixup_internal_log_stripe(
912 xfs_fsblock_t logstart
,
915 xfs_rfsblock_t
*logblocks
,
919 if ((logstart
% sunit
) != 0) {
920 logstart
= ((logstart
+ (sunit
- 1))/sunit
) * sunit
;
924 fixup_log_stripe_unit(lsflag
, sunit
, logblocks
, blocklog
);
926 if (*logblocks
> agsize
- XFS_FSB_TO_AGBNO(mp
, logstart
)) {
928 _("Due to stripe alignment, the internal log size "
929 "(%lld) is too large.\n"), (long long) *logblocks
);
930 fprintf(stderr
, _("Must fit within an allocation group.\n"));
937 validate_log_size(uint64_t logblocks
, int blocklog
, int min_logblocks
)
939 if (logblocks
< min_logblocks
) {
941 _("log size %lld blocks too small, minimum size is %d blocks\n"),
942 (long long)logblocks
, min_logblocks
);
945 if (logblocks
> XFS_MAX_LOG_BLOCKS
) {
947 _("log size %lld blocks too large, maximum size is %lld blocks\n"),
948 (long long)logblocks
, XFS_MAX_LOG_BLOCKS
);
951 if ((logblocks
<< blocklog
) > XFS_MAX_LOG_BYTES
) {
953 _("log size %lld bytes too large, maximum size is %lld bytes\n"),
954 (long long)(logblocks
<< blocklog
), XFS_MAX_LOG_BYTES
);
960 calc_default_imaxpct(
965 * This returns the % of the disk space that is used for
966 * inodes, it changes relatively to the FS size:
967 * - over 50 TB, use 1%,
968 * - 1TB - 50 TB, use 5%,
969 * - under 1 TB, use XFS_DFL_IMAXIMUM_PCT (25%).
972 if (dblocks
< TERABYTES(1, blocklog
)) {
973 return XFS_DFL_IMAXIMUM_PCT
;
974 } else if (dblocks
< TERABYTES(50, blocklog
)) {
982 validate_ag_geometry(
988 if (agsize
< XFS_AG_MIN_BLOCKS(blocklog
)) {
990 _("agsize (%lld blocks) too small, need at least %lld blocks\n"),
992 (long long)XFS_AG_MIN_BLOCKS(blocklog
));
996 if (agsize
> XFS_AG_MAX_BLOCKS(blocklog
)) {
998 _("agsize (%lld blocks) too big, maximum is %lld blocks\n"),
1000 (long long)XFS_AG_MAX_BLOCKS(blocklog
));
1004 if (agsize
> dblocks
) {
1006 _("agsize (%lld blocks) too big, data area is %lld blocks\n"),
1007 (long long)agsize
, (long long)dblocks
);
1011 if (agsize
< XFS_AG_MIN_BLOCKS(blocklog
)) {
1013 _("too many allocation groups for size = %lld\n"),
1015 fprintf(stderr
, _("need at most %lld allocation groups\n"),
1016 (long long)(dblocks
/ XFS_AG_MIN_BLOCKS(blocklog
) +
1017 (dblocks
% XFS_AG_MIN_BLOCKS(blocklog
) != 0)));
1021 if (agsize
> XFS_AG_MAX_BLOCKS(blocklog
)) {
1023 _("too few allocation groups for size = %lld\n"), (long long)agsize
);
1025 _("need at least %lld allocation groups\n"),
1026 (long long)(dblocks
/ XFS_AG_MAX_BLOCKS(blocklog
) +
1027 (dblocks
% XFS_AG_MAX_BLOCKS(blocklog
) != 0)));
1032 * If the last AG is too small, reduce the filesystem size
1033 * and drop the blocks.
1035 if ( dblocks
% agsize
!= 0 &&
1036 (dblocks
% agsize
< XFS_AG_MIN_BLOCKS(blocklog
))) {
1038 _("last AG size %lld blocks too small, minimum size is %lld blocks\n"),
1039 (long long)(dblocks
% agsize
),
1040 (long long)XFS_AG_MIN_BLOCKS(blocklog
));
1045 * If agcount is too large, make it smaller.
1047 if (agcount
> XFS_MAX_AGNUMBER
+ 1) {
1049 _("%lld allocation groups is too many, maximum is %lld\n"),
1050 (long long)agcount
, (long long)XFS_MAX_AGNUMBER
+ 1);
1056 zero_old_xfs_structures(
1067 * We open regular files with O_TRUNC|O_CREAT. Nothing to do here...
1069 if (xi
->disfile
&& xi
->dcreat
)
1073 * read in existing filesystem superblock, use its geometry
1074 * settings and zero the existing secondary superblocks.
1076 buf
= memalign(libxfs_device_alignment(), new_sb
->sb_sectsize
);
1079 _("error reading existing superblock -- failed to memalign buffer\n"));
1082 memset(buf
, 0, new_sb
->sb_sectsize
);
1085 * If we are creating an image file, it might be of zero length at this
1086 * point in time. Hence reading the existing superblock is going to
1087 * return zero bytes. It's not a failure we need to warn about in this
1090 off
= pread(xi
->dfd
, buf
, new_sb
->sb_sectsize
, 0);
1091 if (off
!= new_sb
->sb_sectsize
) {
1094 _("error reading existing superblock: %s\n"),
1098 libxfs_sb_from_disk(&sb
, buf
);
1101 * perform same basic superblock validation to make sure we
1102 * actually zero secondary blocks
1104 if (sb
.sb_magicnum
!= XFS_SB_MAGIC
|| sb
.sb_blocksize
== 0)
1107 for (bsize
= 1, i
= 0; bsize
< sb
.sb_blocksize
&&
1108 i
< sizeof(sb
.sb_blocksize
) * NBBY
; i
++)
1111 if (i
< XFS_MIN_BLOCKSIZE_LOG
|| i
> XFS_MAX_BLOCKSIZE_LOG
||
1112 i
!= sb
.sb_blocklog
)
1115 if (sb
.sb_dblocks
> ((uint64_t)sb
.sb_agcount
* sb
.sb_agblocks
) ||
1116 sb
.sb_dblocks
< ((uint64_t)(sb
.sb_agcount
- 1) *
1117 sb
.sb_agblocks
+ XFS_MIN_AG_BLOCKS
))
1121 * block size and basic geometry seems alright, zero the secondaries.
1123 memset(buf
, 0, new_sb
->sb_sectsize
);
1125 for (i
= 1; i
< sb
.sb_agcount
; i
++) {
1126 off
+= sb
.sb_agblocks
;
1127 if (pwrite(xi
->dfd
, buf
, new_sb
->sb_sectsize
,
1128 off
<< sb
.sb_blocklog
) == -1)
1136 discard_blocks(dev_t dev
, uint64_t nsectors
)
1141 * We intentionally ignore errors from the discard ioctl. It is
1142 * not necessary for the mkfs functionality but just an optimization.
1144 fd
= libxfs_device_to_fd(dev
);
1146 platform_discard_blocks(fd
, 0, nsectors
<< 9);
1149 struct sb_feat_args
{
1157 bool lazy_sb_counters
;
1161 bool parent_pointers
;
1169 struct sb_feat_args
*fp
,
1175 sbp
->sb_versionnum
= XFS_DFL_SB_VERSION_BITS
;
1176 if (fp
->crcs_enabled
)
1177 sbp
->sb_versionnum
|= XFS_SB_VERSION_5
;
1179 sbp
->sb_versionnum
|= XFS_SB_VERSION_4
;
1181 if (fp
->inode_align
)
1182 sbp
->sb_versionnum
|= XFS_SB_VERSION_ALIGNBIT
;
1184 sbp
->sb_versionnum
|= XFS_SB_VERSION_DALIGNBIT
;
1185 if (fp
->log_version
== 2)
1186 sbp
->sb_versionnum
|= XFS_SB_VERSION_LOGV2BIT
;
1187 if (fp
->attr_version
== 1)
1188 sbp
->sb_versionnum
|= XFS_SB_VERSION_ATTRBIT
;
1189 if (sectsize
> BBSIZE
|| lsectsize
> BBSIZE
)
1190 sbp
->sb_versionnum
|= XFS_SB_VERSION_SECTORBIT
;
1192 sbp
->sb_versionnum
|= XFS_SB_VERSION_BORGBIT
;
1195 sbp
->sb_features2
= 0;
1196 if (fp
->lazy_sb_counters
)
1197 sbp
->sb_features2
|= XFS_SB_VERSION2_LAZYSBCOUNTBIT
;
1198 if (!fp
->projid16bit
)
1199 sbp
->sb_features2
|= XFS_SB_VERSION2_PROJID32BIT
;
1200 if (fp
->parent_pointers
)
1201 sbp
->sb_features2
|= XFS_SB_VERSION2_PARENTBIT
;
1202 if (fp
->crcs_enabled
)
1203 sbp
->sb_features2
|= XFS_SB_VERSION2_CRCBIT
;
1204 if (fp
->attr_version
== 2)
1205 sbp
->sb_features2
|= XFS_SB_VERSION2_ATTR2BIT
;
1207 /* v5 superblocks have their own feature bit for dirftype */
1208 if (fp
->dirftype
&& !fp
->crcs_enabled
)
1209 sbp
->sb_features2
|= XFS_SB_VERSION2_FTYPE
;
1211 /* update whether extended features are in use */
1212 if (sbp
->sb_features2
!= 0)
1213 sbp
->sb_versionnum
|= XFS_SB_VERSION_MOREBITSBIT
;
1216 * Due to a structure alignment issue, sb_features2 ended up in one
1217 * of two locations, the second "incorrect" location represented by
1218 * the sb_bad_features2 field. To avoid older kernels mounting
1219 * filesystems they shouldn't, set both field to the same value.
1221 sbp
->sb_bad_features2
= sbp
->sb_features2
;
1223 if (!fp
->crcs_enabled
)
1226 /* default features for v5 filesystems */
1227 sbp
->sb_features_compat
= 0;
1228 sbp
->sb_features_ro_compat
= 0;
1229 sbp
->sb_features_incompat
= XFS_SB_FEAT_INCOMPAT_FTYPE
;
1230 sbp
->sb_features_log_incompat
= 0;
1233 sbp
->sb_features_ro_compat
= XFS_SB_FEAT_RO_COMPAT_FINOBT
;
1235 sbp
->sb_features_ro_compat
|= XFS_SB_FEAT_RO_COMPAT_RMAPBT
;
1237 sbp
->sb_features_ro_compat
|= XFS_SB_FEAT_RO_COMPAT_REFLINK
;
1240 * Sparse inode chunk support has two main inode alignment requirements.
1241 * First, sparse chunk alignment must match the cluster size. Second,
1242 * full chunk alignment must match the inode chunk size.
1244 * Copy the already calculated/scaled inoalignmt to spino_align and
1245 * update the former to the full inode chunk size.
1248 sbp
->sb_spino_align
= sbp
->sb_inoalignmt
;
1249 sbp
->sb_inoalignmt
= XFS_INODES_PER_CHUNK
*
1250 sbp
->sb_inodesize
>> sbp
->sb_blocklog
;
1251 sbp
->sb_features_incompat
|= XFS_SB_FEAT_INCOMPAT_SPINODES
;
1256 static __attribute__((noreturn
)) void
1259 struct opt_params
*opts
,
1264 _("Illegal value %s for -%c %s option. %s\n"),
1265 value
, opts
->name
, opts
->subopts
[index
],
1266 reason
? reason
: "");
1271 * Check for conflicts and option respecification.
1275 struct opt_params
*opts
,
1279 struct subopt_param
*sp
= &opts
->subopt_params
[index
];
1282 if (sp
->index
!= index
) {
1284 ("Developer screwed up option parsing (%d/%d)! Please report!\n"),
1286 reqval(opts
->name
, (char **)opts
->subopts
, index
);
1290 * Check for respecification of the option. This is more complex than it
1291 * seems because some options are parsed twice - once as a string during
1292 * input parsing, then later the string is passed to getnum for
1293 * conversion into a number and bounds checking. Hence the two variables
1294 * used to track the different uses based on the @str parameter passed
1299 respec(opts
->name
, (char **)opts
->subopts
, index
);
1303 respec(opts
->name
, (char **)opts
->subopts
, index
);
1304 sp
->str_seen
= true;
1307 /* check for conflicts with the option */
1308 for (i
= 0; i
< MAX_CONFLICTS
; i
++) {
1309 int conflict_opt
= sp
->conflicts
[i
];
1311 if (conflict_opt
== LAST_CONFLICT
)
1313 if (opts
->subopt_params
[conflict_opt
].seen
||
1314 opts
->subopt_params
[conflict_opt
].str_seen
)
1315 conflict(opts
->name
, (char **)opts
->subopts
,
1316 conflict_opt
, index
);
1323 struct opt_params
*opts
,
1326 struct subopt_param
*sp
= &opts
->subopt_params
[index
];
1329 check_opt(opts
, index
, false);
1330 /* empty strings might just return a default value */
1331 if (!str
|| *str
== '\0') {
1332 if (sp
->defaultval
== SUBOPT_NEEDS_VAL
)
1333 reqval(opts
->name
, (char **)opts
->subopts
, index
);
1334 return sp
->defaultval
;
1337 if (sp
->minval
== 0 && sp
->maxval
== 0) {
1339 _("Option -%c %s has undefined minval/maxval."
1340 "Can't verify value range. This is a bug.\n"),
1341 opts
->name
, opts
->subopts
[index
]);
1346 * Some values are pure numbers, others can have suffixes that define
1347 * the units of the number. Those get passed to cvtnum(), otherwise we
1348 * convert it ourselves to guarantee there is no trailing garbage in the
1352 c
= cvtnum(blocksize
, sectorsize
, str
);
1356 c
= strtoll(str
, &str_end
, 0);
1357 if (c
== 0 && str_end
== str
)
1358 illegal_option(str
, opts
, index
, NULL
);
1359 if (*str_end
!= '\0')
1360 illegal_option(str
, opts
, index
, NULL
);
1363 /* Validity check the result. */
1365 illegal_option(str
, opts
, index
, _("value is too small"));
1366 else if (c
> sp
->maxval
)
1367 illegal_option(str
, opts
, index
, _("value is too large"));
1368 if (sp
->is_power_2
&& !ispow2(c
))
1369 illegal_option(str
, opts
, index
, _("value must be a power of 2"));
1374 * Option is a string - do all the option table work, and check there
1375 * is actually an option string. Otherwise we don't do anything with the string
1376 * here - validation will be done later when the string is converted to a value
1377 * or used as a file/device path.
1382 struct opt_params
*opts
,
1385 check_opt(opts
, index
, true);
1387 /* empty strings for string options are not valid */
1388 if (!str
|| *str
== '\0')
1389 reqval(opts
->name
, (char **)opts
->subopts
, index
);
1401 xfs_agnumber_t agno
;
1403 xfs_alloc_rec_t
*arec
;
1404 struct xfs_btree_block
*block
;
1413 xfs_rfsblock_t dblocks
;
1423 int force_overwrite
;
1438 xfs_agnumber_t logagno
;
1439 xfs_rfsblock_t logblocks
;
1443 xfs_fsblock_t logstart
;
1457 xfs_extlen_t nbmblocks
;
1461 xfs_alloc_rec_t
*nrec
;
1470 xfs_rfsblock_t rtblocks
;
1471 xfs_extlen_t rtextblocks
;
1472 xfs_rtblock_t rtextents
;
1478 uint64_t sector_mask
;
1481 uint64_t tmp_agsize
;
1485 struct fs_topology ft
;
1486 struct sb_feat_args sb_feat
= {
1491 .dir_version
= XFS_DFL_DIR_VERSION
,
1492 .inode_align
= XFS_IFLAG_ALIGN
,
1494 .lazy_sb_counters
= true,
1495 .projid16bit
= false,
1496 .crcs_enabled
= true,
1498 .parent_pointers
= false,
1503 platform_uuid_generate(&uuid
);
1504 progname
= basename(argv
[0]);
1505 setlocale(LC_ALL
, "");
1506 bindtextdomain(PACKAGE
, LOCALEDIR
);
1507 textdomain(PACKAGE
);
1509 blflag
= bsflag
= slflag
= ssflag
= lslflag
= lssflag
= 0;
1510 blocklog
= blocksize
= 0;
1511 sectorlog
= lsectorlog
= 0;
1512 sectorsize
= lsectorsize
= 0;
1513 agsize
= daflag
= dasize
= dblocks
= 0;
1514 ilflag
= imflag
= ipflag
= isflag
= 0;
1515 liflag
= laflag
= lsflag
= lsuflag
= lsunitflag
= ldflag
= lvflag
= 0;
1517 logagno
= logblocks
= rtblocks
= rtextblocks
= 0;
1518 Nflag
= nlflag
= nsflag
= nvflag
= 0;
1519 dirblocklog
= dirblocksize
= 0;
1521 imaxpct
= inodelog
= inopblock
= isize
= 0;
1522 dfile
= logfile
= rtfile
= NULL
;
1523 dsize
= logsize
= rtsize
= rtextsize
= protofile
= NULL
;
1524 dsu
= dsw
= dsunit
= dswidth
= lalign
= lsu
= lsunit
= 0;
1525 dsflag
= nodsflag
= norsflag
= 0;
1526 force_overwrite
= 0;
1528 memset(&fsx
, 0, sizeof(fsx
));
1530 memset(&xi
, 0, sizeof(xi
));
1531 xi
.isdirect
= LIBXFS_DIRECT
;
1532 xi
.isreadonly
= LIBXFS_EXCLUSIVELY
;
1534 while ((c
= getopt(argc
, argv
, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF
) {
1538 force_overwrite
= 1;
1542 while (*p
!= '\0') {
1543 char **subopts
= (char **)bopts
.subopts
;
1546 switch (getsubopt(&p
, subopts
, &value
)) {
1548 blocklog
= getnum(value
, &bopts
, B_LOG
);
1549 blocksize
= 1 << blocklog
;
1553 blocksize
= getnum(value
, &bopts
,
1555 blocklog
= libxfs_highbit32(blocksize
);
1559 unknown('b', value
);
1565 while (*p
!= '\0') {
1566 char **subopts
= (char **)dopts
.subopts
;
1569 switch (getsubopt(&p
, subopts
, &value
)) {
1571 agcount
= getnum(value
, &dopts
,
1576 agsize
= getnum(value
, &dopts
, D_AGSIZE
);
1580 xi
.disfile
= getnum(value
, &dopts
,
1584 xi
.dname
= getstr(value
, &dopts
, D_NAME
);
1587 dsize
= getstr(value
, &dopts
, D_SIZE
);
1590 dsunit
= getnum(value
, &dopts
, D_SUNIT
);
1594 dswidth
= getnum(value
, &dopts
,
1599 dsu
= getnum(value
, &dopts
, D_SU
);
1603 dsw
= getnum(value
, &dopts
, D_SW
);
1607 nodsflag
= getnum(value
, &dopts
,
1611 sectorlog
= getnum(value
, &dopts
,
1613 sectorsize
= 1 << sectorlog
;
1617 sectorsize
= getnum(value
, &dopts
,
1620 libxfs_highbit32(sectorsize
);
1624 c
= getnum(value
, &dopts
, D_RTINHERIT
);
1627 XFS_DIFLAG_RTINHERIT
;
1630 fsx
.fsx_projid
= getnum(value
, &dopts
,
1633 XFS_DIFLAG_PROJINHERIT
;
1635 case D_EXTSZINHERIT
:
1636 fsx
.fsx_extsize
= getnum(value
, &dopts
,
1639 XFS_DIFLAG_EXTSZINHERIT
;
1642 unknown('d', value
);
1648 while (*p
!= '\0') {
1649 char **subopts
= (char **)iopts
.subopts
;
1652 switch (getsubopt(&p
, subopts
, &value
)) {
1654 sb_feat
.inode_align
= getnum(value
,
1658 inodelog
= getnum(value
, &iopts
, I_LOG
);
1659 isize
= 1 << inodelog
;
1663 imaxpct
= getnum(value
, &iopts
,
1668 inopblock
= getnum(value
, &iopts
,
1673 isize
= getnum(value
, &iopts
, I_SIZE
);
1674 inodelog
= libxfs_highbit32(isize
);
1678 sb_feat
.attr_version
=
1679 getnum(value
, &iopts
, I_ATTR
);
1682 sb_feat
.projid16bit
=
1683 !getnum(value
, &iopts
,
1687 sb_feat
.spinodes
= getnum(value
,
1688 &iopts
, I_SPINODES
);
1691 unknown('i', value
);
1697 while (*p
!= '\0') {
1698 char **subopts
= (char **)lopts
.subopts
;
1701 switch (getsubopt(&p
, subopts
, &value
)) {
1703 logagno
= getnum(value
, &lopts
, L_AGNUM
);
1707 xi
.lisfile
= getnum(value
, &lopts
,
1711 loginternal
= getnum(value
, &lopts
,
1716 lsu
= getnum(value
, &lopts
, L_SU
);
1720 lsunit
= getnum(value
, &lopts
, L_SUNIT
);
1725 logfile
= getstr(value
, &lopts
, L_NAME
);
1726 xi
.logname
= logfile
;
1731 sb_feat
.log_version
=
1732 getnum(value
, &lopts
, L_VERSION
);
1736 logsize
= getstr(value
, &lopts
, L_SIZE
);
1739 lsectorlog
= getnum(value
, &lopts
,
1741 lsectorsize
= 1 << lsectorlog
;
1745 lsectorsize
= getnum(value
, &lopts
,
1748 libxfs_highbit32(lsectorsize
);
1752 sb_feat
.lazy_sb_counters
=
1753 getnum(value
, &lopts
,
1757 unknown('l', value
);
1762 if (strlen(optarg
) > sizeof(sbp
->sb_fname
))
1763 illegal(optarg
, "L");
1768 while (*p
!= '\0') {
1769 char **subopts
= (char **)mopts
.subopts
;
1772 switch (getsubopt(&p
, subopts
, &value
)) {
1774 sb_feat
.crcs_enabled
=
1775 getnum(value
, &mopts
, M_CRC
);
1776 if (sb_feat
.crcs_enabled
)
1777 sb_feat
.dirftype
= true;
1780 sb_feat
.finobt
= getnum(
1781 value
, &mopts
, M_FINOBT
);
1784 if (!value
|| *value
== '\0')
1785 reqval('m', subopts
, M_UUID
);
1786 if (platform_uuid_parse(value
, &uuid
))
1787 illegal(optarg
, "m uuid");
1790 sb_feat
.rmapbt
= getnum(
1791 value
, &mopts
, M_RMAPBT
);
1794 sb_feat
.reflink
= getnum(
1795 value
, &mopts
, M_REFLINK
);
1798 unknown('m', value
);
1804 while (*p
!= '\0') {
1805 char **subopts
= (char **)nopts
.subopts
;
1808 switch (getsubopt(&p
, subopts
, &value
)) {
1810 dirblocklog
= getnum(value
, &nopts
,
1812 dirblocksize
= 1 << dirblocklog
;
1816 dirblocksize
= getnum(value
, &nopts
,
1819 libxfs_highbit32(dirblocksize
);
1823 value
= getstr(value
, &nopts
, N_VERSION
);
1824 if (!strcasecmp(value
, "ci")) {
1828 sb_feat
.dir_version
=
1829 getnum(value
, &nopts
,
1835 sb_feat
.dirftype
= getnum(value
, &nopts
,
1839 unknown('n', value
);
1851 respec('p', NULL
, 0);
1859 while (*p
!= '\0') {
1860 char **subopts
= (char **)ropts
.subopts
;
1863 switch (getsubopt(&p
, subopts
, &value
)) {
1865 rtextsize
= getstr(value
, &ropts
,
1869 xi
.risfile
= getnum(value
, &ropts
,
1874 xi
.rtname
= getstr(value
, &ropts
,
1878 rtsize
= getstr(value
, &ropts
, R_SIZE
);
1881 norsflag
= getnum(value
, &ropts
,
1885 unknown('r', value
);
1891 while (*p
!= '\0') {
1892 char **subopts
= (char **)sopts
.subopts
;
1895 switch (getsubopt(&p
, subopts
, &value
)) {
1899 conflict('s', subopts
,
1900 S_SECTSIZE
, S_SECTLOG
);
1901 sectorlog
= getnum(value
, &sopts
,
1903 lsectorlog
= sectorlog
;
1904 sectorsize
= 1 << sectorlog
;
1905 lsectorsize
= sectorsize
;
1906 lslflag
= slflag
= 1;
1911 conflict('s', subopts
, S_SECTLOG
,
1913 sectorsize
= getnum(value
, &sopts
,
1915 lsectorsize
= sectorsize
;
1917 libxfs_highbit32(sectorsize
);
1918 lsectorlog
= sectorlog
;
1919 lssflag
= ssflag
= 1;
1922 unknown('s', value
);
1927 printf(_("%s version %s\n"), progname
, VERSION
);
1930 unknown(optopt
, "");
1933 if (argc
- optind
> 1) {
1934 fprintf(stderr
, _("extra arguments\n"));
1936 } else if (argc
- optind
== 1) {
1937 dfile
= xi
.volname
= getstr(argv
[optind
], &dopts
, D_NAME
);
1942 * Blocksize and sectorsize first, other things depend on them
1943 * For RAID4/5/6 we want to align sector size and block size,
1944 * so we need to start with the device geometry extraction too.
1946 if (!blflag
&& !bsflag
) {
1947 blocklog
= XFS_DFL_BLOCKSIZE_LOG
;
1948 blocksize
= 1 << XFS_DFL_BLOCKSIZE_LOG
;
1950 if (blocksize
< XFS_MIN_BLOCKSIZE
|| blocksize
> XFS_MAX_BLOCKSIZE
) {
1951 fprintf(stderr
, _("illegal block size %d\n"), blocksize
);
1954 if (sb_feat
.crcs_enabled
&& blocksize
< XFS_MIN_CRC_BLOCKSIZE
) {
1956 _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
1957 XFS_MIN_CRC_BLOCKSIZE
);
1960 if (sb_feat
.crcs_enabled
&& !sb_feat
.dirftype
) {
1961 fprintf(stderr
, _("cannot disable ftype with crcs enabled\n"));
1965 if (!slflag
&& !ssflag
) {
1966 sectorlog
= XFS_MIN_SECTORSIZE_LOG
;
1967 sectorsize
= XFS_MIN_SECTORSIZE
;
1969 if (!lslflag
&& !lssflag
) {
1970 lsectorlog
= sectorlog
;
1971 lsectorsize
= sectorsize
;
1975 * Before anything else, verify that we are correctly operating on
1976 * files or block devices and set the control parameters correctly.
1977 * Explicitly disable direct IO for image files so we don't error out on
1978 * sector size mismatches between the new filesystem and the underlying
1981 check_device_type(dfile
, &xi
.disfile
, !dsize
, !dfile
,
1982 Nflag
? NULL
: &xi
.dcreat
, force_overwrite
, "d");
1984 check_device_type(xi
.logname
, &xi
.lisfile
, !logsize
, !xi
.logname
,
1985 Nflag
? NULL
: &xi
.lcreat
,
1986 force_overwrite
, "l");
1988 check_device_type(xi
.rtname
, &xi
.risfile
, !rtsize
, !xi
.rtname
,
1989 Nflag
? NULL
: &xi
.rcreat
,
1990 force_overwrite
, "r");
1991 if (xi
.disfile
|| xi
.lisfile
|| xi
.risfile
)
1994 memset(&ft
, 0, sizeof(ft
));
1995 get_topology(&xi
, &ft
, force_overwrite
);
1999 * Unless specified manually on the command line use the
2000 * advertised sector size of the device. We use the physical
2001 * sector size unless the requested block size is smaller
2002 * than that, then we can use logical, but warn about the
2006 /* Older kernels may not have physical/logical distinction */
2007 if (!ft
.psectorsize
)
2008 ft
.psectorsize
= ft
.lsectorsize
;
2010 sectorsize
= ft
.psectorsize
? ft
.psectorsize
:
2013 if ((blocksize
< sectorsize
) && (blocksize
>= ft
.lsectorsize
)) {
2015 _("specified blocksize %d is less than device physical sector size %d\n"),
2016 blocksize
, ft
.psectorsize
);
2018 _("switching to logical sector size %d\n"),
2020 sectorsize
= ft
.lsectorsize
? ft
.lsectorsize
:
2026 sectorlog
= libxfs_highbit32(sectorsize
);
2028 lsectorsize
= sectorsize
;
2029 lsectorlog
= sectorlog
;
2033 if (sectorsize
< XFS_MIN_SECTORSIZE
||
2034 sectorsize
> XFS_MAX_SECTORSIZE
|| sectorsize
> blocksize
) {
2036 fprintf(stderr
, _("illegal sector size %d\n"), sectorsize
);
2039 _("block size %d cannot be smaller than logical sector size %d\n"),
2040 blocksize
, ft
.lsectorsize
);
2043 if (sectorsize
< ft
.lsectorsize
) {
2044 fprintf(stderr
, _("illegal sector size %d; hw sector is %d\n"),
2045 sectorsize
, ft
.lsectorsize
);
2048 if (lsectorsize
< XFS_MIN_SECTORSIZE
||
2049 lsectorsize
> XFS_MAX_SECTORSIZE
|| lsectorsize
> blocksize
) {
2050 fprintf(stderr
, _("illegal log sector size %d\n"), lsectorsize
);
2052 } else if (lsectorsize
> XFS_MIN_SECTORSIZE
&& !lsu
&& !lsunit
) {
2054 sb_feat
.log_version
= 2;
2058 * Now we have blocks and sector sizes set up, check parameters that are
2059 * no longer optional for CRC enabled filesystems. Catch them up front
2060 * here before doing anything else.
2062 if (sb_feat
.crcs_enabled
) {
2063 /* minimum inode size is 512 bytes, ipflag checked later */
2064 if ((isflag
|| ilflag
) && inodelog
< XFS_DINODE_DFL_CRC_LOG
) {
2066 _("Minimum inode size for CRCs is %d bytes\n"),
2067 1 << XFS_DINODE_DFL_CRC_LOG
);
2071 /* inodes always aligned */
2072 if (!sb_feat
.inode_align
) {
2074 _("Inodes always aligned for CRC enabled filesytems\n"));
2078 /* lazy sb counters always on */
2079 if (!sb_feat
.lazy_sb_counters
) {
2081 _("Lazy superblock counted always enabled for CRC enabled filesytems\n"));
2085 /* version 2 logs always on */
2086 if (sb_feat
.log_version
!= 2) {
2088 _("V2 logs always enabled for CRC enabled filesytems\n"));
2092 /* attr2 always on */
2093 if (sb_feat
.attr_version
!= 2) {
2095 _("V2 attribute format always enabled on CRC enabled filesytems\n"));
2099 /* 32 bit project quota always on */
2100 /* attr2 always on */
2101 if (sb_feat
.projid16bit
) {
2103 _("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
2108 * The kernel doesn't currently support crc=0,finobt=1
2109 * filesystems. If crcs are not enabled and the user has not
2110 * explicitly turned finobt on, then silently turn it off to
2111 * avoid an unnecessary warning.
2112 * If the user explicitly tried to use crc=0,finobt=1,
2113 * then issue an error.
2114 * The same is also for sparse inodes.
2116 if (sb_feat
.finobt
&& mopts
.subopt_params
[M_FINOBT
].seen
) {
2118 _("finobt not supported without CRC support\n"));
2123 if (sb_feat
.spinodes
) {
2125 _("sparse inodes not supported without CRC support\n"));
2128 sb_feat
.spinodes
= 0;
2130 if (sb_feat
.rmapbt
) {
2132 _("rmapbt not supported without CRC support\n"));
2135 sb_feat
.rmapbt
= false;
2137 if (sb_feat
.reflink
) {
2139 _("reflink not supported without CRC support\n"));
2142 sb_feat
.reflink
= false;
2146 if (sb_feat
.rmapbt
&& xi
.rtname
) {
2148 _("rmapbt not supported with realtime devices\n"));
2150 sb_feat
.rmapbt
= false;
2153 if (nsflag
|| nlflag
) {
2154 if (dirblocksize
< blocksize
||
2155 dirblocksize
> XFS_MAX_BLOCKSIZE
) {
2156 fprintf(stderr
, _("illegal directory block size %d\n"),
2161 if (blocksize
< (1 << XFS_MIN_REC_DIRSIZE
))
2162 dirblocklog
= XFS_MIN_REC_DIRSIZE
;
2164 dirblocklog
= blocklog
;
2165 dirblocksize
= 1 << dirblocklog
;
2172 dbytes
= getnum(dsize
, &dopts
, D_SIZE
);
2173 if (dbytes
% XFS_MIN_BLOCKSIZE
) {
2175 _("illegal data length %lld, not a multiple of %d\n"),
2176 (long long)dbytes
, XFS_MIN_BLOCKSIZE
);
2179 dblocks
= (xfs_rfsblock_t
)(dbytes
>> blocklog
);
2180 if (dbytes
% blocksize
)
2181 fprintf(stderr
, _("warning: "
2182 "data length %lld not a multiple of %d, truncated to %lld\n"),
2183 (long long)dbytes
, blocksize
,
2184 (long long)(dblocks
<< blocklog
));
2187 inodelog
= blocklog
- libxfs_highbit32(inopblock
);
2188 isize
= 1 << inodelog
;
2189 } else if (!ilflag
&& !isflag
) {
2190 inodelog
= sb_feat
.crcs_enabled
? XFS_DINODE_DFL_CRC_LOG
2191 : XFS_DINODE_DFL_LOG
;
2192 isize
= 1 << inodelog
;
2194 if (sb_feat
.crcs_enabled
&& inodelog
< XFS_DINODE_DFL_CRC_LOG
) {
2196 _("Minimum inode size for CRCs is %d bytes\n"),
2197 1 << XFS_DINODE_DFL_CRC_LOG
);
2204 logbytes
= getnum(logsize
, &lopts
, L_SIZE
);
2205 if (logbytes
% XFS_MIN_BLOCKSIZE
) {
2207 _("illegal log length %lld, not a multiple of %d\n"),
2208 (long long)logbytes
, XFS_MIN_BLOCKSIZE
);
2211 logblocks
= (xfs_rfsblock_t
)(logbytes
>> blocklog
);
2212 if (logbytes
% blocksize
)
2214 _("warning: log length %lld not a multiple of %d, truncated to %lld\n"),
2215 (long long)logbytes
, blocksize
,
2216 (long long)(logblocks
<< blocklog
));
2221 rtbytes
= getnum(rtsize
, &ropts
, R_SIZE
);
2222 if (rtbytes
% XFS_MIN_BLOCKSIZE
) {
2224 _("illegal rt length %lld, not a multiple of %d\n"),
2225 (long long)rtbytes
, XFS_MIN_BLOCKSIZE
);
2228 rtblocks
= (xfs_rfsblock_t
)(rtbytes
>> blocklog
);
2229 if (rtbytes
% blocksize
)
2231 _("warning: rt length %lld not a multiple of %d, truncated to %lld\n"),
2232 (long long)rtbytes
, blocksize
,
2233 (long long)(rtblocks
<< blocklog
));
2236 * If specified, check rt extent size against its constraints.
2239 uint64_t rtextbytes
;
2241 rtextbytes
= getnum(rtextsize
, &ropts
, R_EXTSIZE
);
2242 if (rtextbytes
% blocksize
) {
2244 _("illegal rt extent size %lld, not a multiple of %d\n"),
2245 (long long)rtextbytes
, blocksize
);
2248 rtextblocks
= (xfs_extlen_t
)(rtextbytes
>> blocklog
);
2251 * If realtime extsize has not been specified by the user,
2252 * and the underlying volume is striped, then set rtextblocks
2253 * to the stripe width.
2256 uint64_t rtextbytes
;
2258 if (!norsflag
&& !xi
.risfile
&& !(!rtsize
&& xi
.disfile
))
2259 rswidth
= ft
.rtswidth
;
2263 /* check that rswidth is a multiple of fs blocksize */
2264 if (!norsflag
&& rswidth
&& !(BBTOB(rswidth
) % blocksize
)) {
2265 rswidth
= DTOBT(rswidth
);
2266 rtextbytes
= rswidth
<< blocklog
;
2267 if (XFS_MIN_RTEXTSIZE
<= rtextbytes
&&
2268 (rtextbytes
<= XFS_MAX_RTEXTSIZE
)) {
2269 rtextblocks
= rswidth
;
2273 rtextblocks
= (blocksize
< XFS_MIN_RTEXTSIZE
) ?
2274 XFS_MIN_RTEXTSIZE
>> blocklog
: 1;
2277 ASSERT(rtextblocks
);
2280 * Check some argument sizes against mins, maxes.
2282 if (isize
> blocksize
/ XFS_MIN_INODE_PERBLOCK
||
2283 isize
< XFS_DINODE_MIN_SIZE
||
2284 isize
> XFS_DINODE_MAX_SIZE
) {
2287 fprintf(stderr
, _("illegal inode size %d\n"), isize
);
2288 maxsz
= MIN(blocksize
/ XFS_MIN_INODE_PERBLOCK
,
2289 XFS_DINODE_MAX_SIZE
);
2290 if (XFS_DINODE_MIN_SIZE
== maxsz
)
2292 _("allowable inode size with %d byte blocks is %d\n"),
2293 blocksize
, XFS_DINODE_MIN_SIZE
);
2296 _("allowable inode size with %d byte blocks is between %d and %d\n"),
2297 blocksize
, XFS_DINODE_MIN_SIZE
, maxsz
);
2301 /* if lsu or lsunit was specified, automatically use v2 logs */
2302 if ((lsu
|| lsunit
) && sb_feat
.log_version
== 1) {
2304 _("log stripe unit specified, using v2 logs\n"));
2305 sb_feat
.log_version
= 2;
2308 calc_stripe_factors(dsu
, dsw
, sectorsize
, lsu
, lsectorsize
,
2309 &dsunit
, &dswidth
, &lsunit
);
2311 /* If sunit & swidth were manually specified as 0, same as noalign */
2312 if (dsflag
&& !dsunit
&& !dswidth
)
2315 xi
.setblksize
= sectorsize
;
2318 * Initialize. This will open the log and rt devices as well.
2320 if (!libxfs_init(&xi
))
2323 fprintf(stderr
, _("no device name given in argument list\n"));
2328 * Ok, Linux only has a 1024-byte resolution on device _size_,
2329 * and the sizes below are in basic 512-byte blocks,
2330 * so if we have (size % 2), on any partition, we can't get
2331 * to the last 512 bytes. The same issue exists for larger
2332 * sector sizes - we cannot write past the last sector.
2334 * So, we reduce the size (in basic blocks) to a perfect
2335 * multiple of the sector size, or 1024, whichever is larger.
2338 sector_mask
= (uint64_t)-1 << (MAX(sectorlog
, 10) - BBSHIFT
);
2339 xi
.dsize
&= sector_mask
;
2340 xi
.rtsize
&= sector_mask
;
2341 xi
.logBBsize
&= (uint64_t)-1 << (MAX(lsectorlog
, 10) - BBSHIFT
);
2344 /* don't do discards on print-only runs or on files */
2345 if (discard
&& !Nflag
) {
2347 discard_blocks(xi
.ddev
, xi
.dsize
);
2348 if (xi
.rtdev
&& !xi
.risfile
)
2349 discard_blocks(xi
.rtdev
, xi
.rtsize
);
2350 if (xi
.logdev
&& xi
.logdev
!= xi
.ddev
&& !xi
.lisfile
)
2351 discard_blocks(xi
.logdev
, xi
.logBBsize
);
2354 if (!liflag
&& !ldflag
)
2355 loginternal
= xi
.logdev
== 0;
2357 logfile
= xi
.logname
;
2358 else if (loginternal
)
2359 logfile
= _("internal log");
2360 else if (xi
.volname
&& xi
.logdev
)
2361 logfile
= _("volume log");
2363 fprintf(stderr
, _("no log subvolume or internal log\n"));
2369 if (xi
.volname
&& xi
.rtdev
)
2370 rtfile
= _("volume rt");
2373 if (dsize
&& xi
.dsize
> 0 && dblocks
> DTOBT(xi
.dsize
)) {
2375 _("size %s specified for data subvolume is too large, "
2376 "maximum is %lld blocks\n"),
2377 dsize
, (long long)DTOBT(xi
.dsize
));
2379 } else if (!dsize
&& xi
.dsize
> 0)
2380 dblocks
= DTOBT(xi
.dsize
);
2382 fprintf(stderr
, _("can't get size of data subvolume\n"));
2385 if (dblocks
< XFS_MIN_DATA_BLOCKS
) {
2387 _("size %lld of data subvolume is too small, minimum %d blocks\n"),
2388 (long long)dblocks
, XFS_MIN_DATA_BLOCKS
);
2392 if (loginternal
&& xi
.logdev
) {
2394 _("can't have both external and internal logs\n"));
2396 } else if (loginternal
&& sectorsize
!= lsectorsize
) {
2398 _("data and log sector sizes must be equal for internal logs\n"));
2402 if (xi
.dbsize
> sectorsize
) {
2404 "Warning: the data subvolume sector size %u is less than the sector size \n\
2405 reported by the device (%u).\n"),
2406 sectorsize
, xi
.dbsize
);
2408 if (!loginternal
&& xi
.lbsize
> lsectorsize
) {
2410 "Warning: the log subvolume sector size %u is less than the sector size\n\
2411 reported by the device (%u).\n"),
2412 lsectorsize
, xi
.lbsize
);
2414 if (rtsize
&& xi
.rtsize
> 0 && xi
.rtbsize
> sectorsize
) {
2416 "Warning: the realtime subvolume sector size %u is less than the sector size\n\
2417 reported by the device (%u).\n"),
2418 sectorsize
, xi
.rtbsize
);
2421 if (rtsize
&& xi
.rtsize
> 0 && rtblocks
> DTOBT(xi
.rtsize
)) {
2423 _("size %s specified for rt subvolume is too large, "
2424 "maximum is %lld blocks\n"),
2425 rtsize
, (long long)DTOBT(xi
.rtsize
));
2427 } else if (!rtsize
&& xi
.rtsize
> 0)
2428 rtblocks
= DTOBT(xi
.rtsize
);
2429 else if (rtsize
&& !xi
.rtdev
) {
2431 _("size specified for non-existent rt subvolume\n"));
2435 rtextents
= rtblocks
/ rtextblocks
;
2436 nbmblocks
= (xfs_extlen_t
)howmany(rtextents
, NBBY
* blocksize
);
2438 rtextents
= rtblocks
= 0;
2444 if (ft
.dsunit
&& ft
.dsunit
!= dsunit
) {
2446 _("%s: Specified data stripe unit %d "
2447 "is not the same as the volume stripe "
2449 progname
, dsunit
, ft
.dsunit
);
2451 if (ft
.dswidth
&& ft
.dswidth
!= dswidth
) {
2453 _("%s: Specified data stripe width %d "
2454 "is not the same as the volume stripe "
2456 progname
, dswidth
, ft
.dswidth
);
2460 dswidth
= ft
.dswidth
;
2463 } /* else dsunit & dswidth can't be set if nodsflag is set */
2465 if (dasize
) { /* User-specified AG size */
2467 * Check specified agsize is a multiple of blocksize.
2469 if (agsize
% blocksize
) {
2471 _("agsize (%lld) not a multiple of fs blk size (%d)\n"),
2472 (long long)agsize
, blocksize
);
2475 agsize
/= blocksize
;
2476 agcount
= dblocks
/ agsize
+ (dblocks
% agsize
!= 0);
2478 } else if (daflag
) { /* User-specified AG count */
2479 agsize
= dblocks
/ agcount
+ (dblocks
% agcount
!= 0);
2481 calc_default_ag_geometry(blocklog
, dblocks
,
2482 dsunit
| dswidth
, &agsize
, &agcount
);
2486 * If dsunit is a multiple of fs blocksize, then check that is a
2487 * multiple of the agsize too
2489 if (dsunit
&& !(BBTOB(dsunit
) % blocksize
) &&
2490 dswidth
&& !(BBTOB(dswidth
) % blocksize
)) {
2492 /* convert from 512 byte blocks to fs blocksize */
2493 dsunit
= DTOBT(dsunit
);
2494 dswidth
= DTOBT(dswidth
);
2497 * agsize is not a multiple of dsunit
2499 if ((agsize
% dsunit
) != 0) {
2501 * Round up to stripe unit boundary. Also make sure
2502 * that agsize is still larger than
2503 * XFS_AG_MIN_BLOCKS(blocklog)
2505 tmp_agsize
= ((agsize
+ (dsunit
- 1))/ dsunit
) * dsunit
;
2507 * Round down to stripe unit boundary if rounding up
2508 * created an AG size that is larger than the AG max.
2510 if (tmp_agsize
> XFS_AG_MAX_BLOCKS(blocklog
))
2511 tmp_agsize
= ((agsize
) / dsunit
) * dsunit
;
2513 if ((tmp_agsize
>= XFS_AG_MIN_BLOCKS(blocklog
)) &&
2514 (tmp_agsize
<= XFS_AG_MAX_BLOCKS(blocklog
))) {
2515 agsize
= tmp_agsize
;
2517 agcount
= dblocks
/agsize
+
2518 (dblocks
% agsize
!= 0);
2521 _("agsize rounded to %lld, swidth = %d\n"),
2522 (long long)agsize
, dswidth
);
2525 dsunit
= dswidth
= 0;
2528 * agsize is out of bounds, this will
2529 * print nice details & exit.
2531 validate_ag_geometry(blocklog
, dblocks
,
2537 if (dswidth
&& ((agsize
% dswidth
) == 0) && (agcount
> 1)) {
2538 /* This is a non-optimal configuration because all AGs
2539 * start on the same disk in the stripe. Changing
2540 * the AG size by one sunit will guarantee that this
2543 tmp_agsize
= agsize
- dsunit
;
2544 if (tmp_agsize
< XFS_AG_MIN_BLOCKS(blocklog
)) {
2545 tmp_agsize
= agsize
+ dsunit
;
2546 if (dblocks
< agsize
) {
2547 /* oh well, nothing to do */
2548 tmp_agsize
= agsize
;
2551 if (daflag
|| dasize
) {
2553 "Warning: AG size is a multiple of stripe width. This can cause performance\n\
2554 problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\
2555 an AG size that is one stripe unit smaller, for example %llu.\n"),
2556 (unsigned long long)tmp_agsize
);
2558 agsize
= tmp_agsize
;
2559 agcount
= dblocks
/agsize
+ (dblocks
% agsize
!= 0);
2561 * If the last AG is too small, reduce the
2562 * filesystem size and drop the blocks.
2564 if ( dblocks
% agsize
!= 0 &&
2566 XFS_AG_MIN_BLOCKS(blocklog
))) {
2567 dblocks
= (xfs_rfsblock_t
)((agcount
- 1) * agsize
);
2569 ASSERT(agcount
!= 0);
2575 dsunit
= dswidth
= 0;
2578 _("%s: Stripe unit(%d) or stripe width(%d) is "
2579 "not a multiple of the block size(%d)\n"),
2580 progname
, BBTOB(dsunit
), BBTOB(dswidth
),
2587 * If the last AG is too small, reduce the filesystem size
2588 * and drop the blocks.
2590 if ( dblocks
% agsize
!= 0 &&
2591 (dblocks
% agsize
< XFS_AG_MIN_BLOCKS(blocklog
))) {
2593 dblocks
= (xfs_rfsblock_t
)((agcount
- 1) * agsize
);
2595 ASSERT(agcount
!= 0);
2598 validate_ag_geometry(blocklog
, dblocks
, agsize
, agcount
);
2601 imaxpct
= calc_default_imaxpct(blocklog
, dblocks
);
2604 * check that log sunit is modulo fsblksize or default it to dsunit.
2608 /* convert from 512 byte blocks to fs blocks */
2609 lsunit
= DTOBT(lsunit
);
2610 } else if (sb_feat
.log_version
== 2 && loginternal
&& dsunit
) {
2611 /* lsunit and dsunit now in fs blocks */
2615 if (sb_feat
.log_version
== 2 && (lsunit
* blocksize
) > 256 * 1024) {
2616 /* Warn only if specified on commandline */
2617 if (lsuflag
|| lsunitflag
) {
2619 _("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"),
2620 (lsunit
* blocksize
));
2622 _("log stripe unit adjusted to 32KiB\n"));
2624 lsunit
= (32 * 1024) >> blocklog
;
2627 min_logblocks
= max_trans_res(agsize
,
2628 sb_feat
.crcs_enabled
, sb_feat
.dir_version
,
2629 sectorlog
, blocklog
, inodelog
, dirblocklog
,
2630 sb_feat
.log_version
, lsunit
, sb_feat
.finobt
,
2631 sb_feat
.rmapbt
, sb_feat
.reflink
,
2632 sb_feat
.inode_align
);
2633 ASSERT(min_logblocks
);
2634 min_logblocks
= MAX(XFS_MIN_LOG_BLOCKS
, min_logblocks
);
2635 if (!logsize
&& dblocks
>= (1024*1024*1024) >> blocklog
)
2636 min_logblocks
= MAX(min_logblocks
, XFS_MIN_LOG_BYTES
>>blocklog
);
2637 if (logsize
&& xi
.logBBsize
> 0 && logblocks
> DTOBT(xi
.logBBsize
)) {
2639 _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
2640 logsize
, (long long)DTOBT(xi
.logBBsize
));
2642 } else if (!logsize
&& xi
.logBBsize
> 0) {
2643 logblocks
= DTOBT(xi
.logBBsize
);
2644 } else if (logsize
&& !xi
.logdev
&& !loginternal
) {
2646 _("size specified for non-existent log subvolume\n"));
2648 } else if (loginternal
&& logsize
&& logblocks
>= dblocks
) {
2649 fprintf(stderr
, _("size %lld too large for internal log\n"),
2650 (long long)logblocks
);
2652 } else if (!loginternal
&& !xi
.logdev
) {
2654 } else if (loginternal
&& !logsize
) {
2656 if (dblocks
< GIGABYTES(1, blocklog
)) {
2657 /* tiny filesystems get minimum sized logs. */
2658 logblocks
= min_logblocks
;
2659 } else if (dblocks
< GIGABYTES(16, blocklog
)) {
2662 * For small filesystems, we want to use the
2663 * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
2664 * at all possible, ramping up to 128MB at 256GB.
2666 logblocks
= MIN(XFS_MIN_LOG_BYTES
>> blocklog
,
2667 min_logblocks
* XFS_DFL_LOG_FACTOR
);
2670 * With a 2GB max log size, default to maximum size
2671 * at 4TB. This keeps the same ratio from the older
2672 * max log size of 128M at 256GB fs size. IOWs,
2673 * the ratio of fs size to log size is 2048:1.
2675 logblocks
= (dblocks
<< blocklog
) / 2048;
2676 logblocks
= logblocks
>> blocklog
;
2679 /* Ensure the chosen size meets minimum log size requirements */
2680 logblocks
= MAX(min_logblocks
, logblocks
);
2682 /* make sure the log fits wholly within an AG */
2683 if (logblocks
>= agsize
)
2684 logblocks
= min_logblocks
;
2686 /* and now clamp the size to the maximum supported size */
2687 logblocks
= MIN(logblocks
, XFS_MAX_LOG_BLOCKS
);
2688 if ((logblocks
<< blocklog
) > XFS_MAX_LOG_BYTES
)
2689 logblocks
= XFS_MAX_LOG_BYTES
>> blocklog
;
2692 validate_log_size(logblocks
, blocklog
, min_logblocks
);
2694 protostring
= setup_proto(protofile
);
2695 bsize
= 1 << (blocklog
- BBSHIFT
);
2698 memset(mp
, 0, sizeof(xfs_mount_t
));
2699 sbp
->sb_blocklog
= (uint8_t)blocklog
;
2700 sbp
->sb_sectlog
= (uint8_t)sectorlog
;
2701 sbp
->sb_agblklog
= (uint8_t)libxfs_log2_roundup((unsigned int)agsize
);
2702 sbp
->sb_agblocks
= (xfs_agblock_t
)agsize
;
2703 mp
->m_blkbb_log
= sbp
->sb_blocklog
- BBSHIFT
;
2704 mp
->m_sectbb_log
= sbp
->sb_sectlog
- BBSHIFT
;
2707 * sb_versionnum, finobt and rmapbt flags must be set before we use
2708 * libxfs_prealloc_blocks().
2710 sb_set_features(&mp
->m_sb
, &sb_feat
, sectorsize
, lsectorsize
, dsunit
);
2715 * Readjust the log size to fit within an AG if it was sized
2719 logblocks
= MIN(logblocks
,
2720 libxfs_alloc_ag_max_usable(mp
));
2722 /* revalidate the log size is valid if we changed it */
2723 validate_log_size(logblocks
, blocklog
, min_logblocks
);
2725 if (logblocks
> agsize
- libxfs_prealloc_blocks(mp
)) {
2727 _("internal log size %lld too large, must fit in allocation group\n"),
2728 (long long)logblocks
);
2733 if (logagno
>= agcount
) {
2735 _("log ag number %d too large, must be less than %lld\n"),
2736 logagno
, (long long)agcount
);
2740 logagno
= (xfs_agnumber_t
)(agcount
/ 2);
2742 logstart
= XFS_AGB_TO_FSB(mp
, logagno
, libxfs_prealloc_blocks(mp
));
2744 * Align the logstart at stripe unit boundary.
2747 logstart
= fixup_internal_log_stripe(mp
,
2748 lsflag
, logstart
, agsize
, lsunit
,
2749 &logblocks
, blocklog
, &lalign
);
2750 } else if (dsunit
) {
2751 logstart
= fixup_internal_log_stripe(mp
,
2752 lsflag
, logstart
, agsize
, dsunit
,
2753 &logblocks
, blocklog
, &lalign
);
2758 fixup_log_stripe_unit(lsflag
, lsunit
,
2759 &logblocks
, blocklog
);
2761 validate_log_size(logblocks
, blocklog
, min_logblocks
);
2763 if (!qflag
|| Nflag
) {
2765 "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
2766 " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
2767 " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u, reflink=%u\n"
2768 "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
2769 " =%-22s sunit=%-6u swidth=%u blks\n"
2770 "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n"
2771 "log =%-22s bsize=%-6d blocks=%lld, version=%d\n"
2772 " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
2773 "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
2774 dfile
, isize
, (long long)agcount
, (long long)agsize
,
2775 "", sectorsize
, sb_feat
.attr_version
,
2776 !sb_feat
.projid16bit
,
2777 "", sb_feat
.crcs_enabled
, sb_feat
.finobt
, sb_feat
.spinodes
,
2778 sb_feat
.rmapbt
, sb_feat
.reflink
,
2779 "", blocksize
, (long long)dblocks
, imaxpct
,
2780 "", dsunit
, dswidth
,
2781 sb_feat
.dir_version
, dirblocksize
, sb_feat
.nci
,
2783 logfile
, 1 << blocklog
, (long long)logblocks
,
2784 sb_feat
.log_version
, "", lsectorsize
, lsunit
,
2785 sb_feat
.lazy_sb_counters
,
2786 rtfile
, rtextblocks
<< blocklog
,
2787 (long long)rtblocks
, (long long)rtextents
);
2793 strncpy(sbp
->sb_fname
, label
, sizeof(sbp
->sb_fname
));
2794 sbp
->sb_magicnum
= XFS_SB_MAGIC
;
2795 sbp
->sb_blocksize
= blocksize
;
2796 sbp
->sb_dblocks
= dblocks
;
2797 sbp
->sb_rblocks
= rtblocks
;
2798 sbp
->sb_rextents
= rtextents
;
2799 platform_uuid_copy(&sbp
->sb_uuid
, &uuid
);
2800 /* Only in memory; libxfs expects this as if read from disk */
2801 platform_uuid_copy(&sbp
->sb_meta_uuid
, &uuid
);
2802 sbp
->sb_logstart
= logstart
;
2803 sbp
->sb_rootino
= sbp
->sb_rbmino
= sbp
->sb_rsumino
= NULLFSINO
;
2804 sbp
->sb_rextsize
= rtextblocks
;
2805 sbp
->sb_agcount
= (xfs_agnumber_t
)agcount
;
2806 sbp
->sb_rbmblocks
= nbmblocks
;
2807 sbp
->sb_logblocks
= (xfs_extlen_t
)logblocks
;
2808 sbp
->sb_sectsize
= (uint16_t)sectorsize
;
2809 sbp
->sb_inodesize
= (uint16_t)isize
;
2810 sbp
->sb_inopblock
= (uint16_t)(blocksize
/ isize
);
2811 sbp
->sb_sectlog
= (uint8_t)sectorlog
;
2812 sbp
->sb_inodelog
= (uint8_t)inodelog
;
2813 sbp
->sb_inopblog
= (uint8_t)(blocklog
- inodelog
);
2815 (uint8_t)(rtextents
?
2816 libxfs_highbit32((unsigned int)rtextents
) : 0);
2817 sbp
->sb_inprogress
= 1; /* mkfs is in progress */
2818 sbp
->sb_imax_pct
= imaxpct
;
2821 sbp
->sb_fdblocks
= dblocks
- agcount
* libxfs_prealloc_blocks(mp
) -
2822 (loginternal
? logblocks
: 0);
2823 sbp
->sb_frextents
= 0; /* will do a free later */
2824 sbp
->sb_uquotino
= sbp
->sb_gquotino
= sbp
->sb_pquotino
= 0;
2826 sbp
->sb_unit
= dsunit
;
2827 sbp
->sb_width
= dswidth
;
2828 sbp
->sb_dirblklog
= dirblocklog
- blocklog
;
2829 if (sb_feat
.log_version
== 2) { /* This is stored in bytes */
2830 lsunit
= (lsunit
== 0) ? 1 : XFS_FSB_TO_B(mp
, lsunit
);
2831 sbp
->sb_logsunit
= lsunit
;
2833 sbp
->sb_logsunit
= 0;
2834 if (sb_feat
.inode_align
) {
2835 int cluster_size
= XFS_INODE_BIG_CLUSTER_SIZE
;
2836 if (sb_feat
.crcs_enabled
)
2837 cluster_size
*= isize
/ XFS_DINODE_MIN_SIZE
;
2838 sbp
->sb_inoalignmt
= cluster_size
>> blocklog
;
2839 sb_feat
.inode_align
= sbp
->sb_inoalignmt
!= 0;
2841 sbp
->sb_inoalignmt
= 0;
2842 if (lsectorsize
!= BBSIZE
|| sectorsize
!= BBSIZE
) {
2843 sbp
->sb_logsectlog
= (uint8_t)lsectorlog
;
2844 sbp
->sb_logsectsize
= (uint16_t)lsectorsize
;
2846 sbp
->sb_logsectlog
= 0;
2847 sbp
->sb_logsectsize
= 0;
2850 sb_set_features(&mp
->m_sb
, &sb_feat
, sectorsize
, lsectorsize
, dsunit
);
2852 if (force_overwrite
)
2853 zero_old_xfs_structures(&xi
, sbp
);
2856 * Zero out the beginning of the device, to obliterate any old
2857 * filesystem signatures out there. This should take care of
2858 * swap (somewhere around the page size), jfs (32k),
2859 * ext[2,3] and reiserfs (64k) - and hopefully all else.
2861 libxfs_buftarg_init(mp
, xi
.ddev
, xi
.logdev
, xi
.rtdev
);
2862 buf
= libxfs_getbuf(mp
->m_ddev_targp
, 0, BTOBB(WHACK_SIZE
));
2863 memset(XFS_BUF_PTR(buf
), 0, WHACK_SIZE
);
2864 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
2865 libxfs_purgebuf(buf
);
2867 /* OK, now write the superblock */
2868 buf
= libxfs_getbuf(mp
->m_ddev_targp
, XFS_SB_DADDR
, XFS_FSS_TO_BB(mp
, 1));
2869 buf
->b_ops
= &xfs_sb_buf_ops
;
2870 memset(XFS_BUF_PTR(buf
), 0, sectorsize
);
2871 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf
), sbp
);
2872 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
2873 libxfs_purgebuf(buf
);
2876 * If the data area is a file, then grow it out to its final size
2877 * if needed so that the reads for the end of the device in the mount
2878 * code will succeed.
2880 if (xi
.disfile
&& xi
.dsize
* xi
.dbsize
< dblocks
* blocksize
) {
2881 if (ftruncate(xi
.dfd
, dblocks
* blocksize
) < 0) {
2883 _("%s: Growing the data section failed\n"),
2890 * Zero out the end of the device, to obliterate any
2891 * old MD RAID (or other) metadata at the end of the device.
2892 * (MD sb is ~64k from the end, take out a wider swath to be sure)
2895 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
2896 (xi
.dsize
- BTOBB(WHACK_SIZE
)),
2898 memset(XFS_BUF_PTR(buf
), 0, WHACK_SIZE
);
2899 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
2900 libxfs_purgebuf(buf
);
2906 libxfs_log_clear(mp
->m_logdev_targp
, NULL
,
2907 XFS_FSB_TO_DADDR(mp
, logstart
),
2908 (xfs_extlen_t
)XFS_FSB_TO_BB(mp
, logblocks
),
2909 &sbp
->sb_uuid
, sb_feat
.log_version
, lsunit
, XLOG_FMT
, XLOG_INIT_CYCLE
, false);
2911 mp
= libxfs_mount(mp
, sbp
, xi
.ddev
, xi
.logdev
, xi
.rtdev
, 0);
2913 fprintf(stderr
, _("%s: filesystem failed to initialize\n"),
2919 * XXX: this code is effectively shared with the kernel growfs code.
2920 * These initialisations should be pulled into libxfs to keep the
2921 * kernel/userspace header initialisation code the same.
2923 for (agno
= 0; agno
< agcount
; agno
++) {
2924 struct xfs_agfl
*agfl
;
2926 struct xfs_perag
*pag
= libxfs_perag_get(mp
, agno
);
2931 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
2932 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
2933 XFS_FSS_TO_BB(mp
, 1));
2934 buf
->b_ops
= &xfs_sb_buf_ops
;
2935 memset(XFS_BUF_PTR(buf
), 0, sectorsize
);
2936 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf
), sbp
);
2937 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
2940 * AG header block: freespace
2942 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
2943 XFS_AG_DADDR(mp
, agno
, XFS_AGF_DADDR(mp
)),
2944 XFS_FSS_TO_BB(mp
, 1));
2945 buf
->b_ops
= &xfs_agf_buf_ops
;
2946 agf
= XFS_BUF_TO_AGF(buf
);
2947 memset(agf
, 0, sectorsize
);
2948 if (agno
== agcount
- 1)
2949 agsize
= dblocks
- (xfs_rfsblock_t
)(agno
* agsize
);
2950 agf
->agf_magicnum
= cpu_to_be32(XFS_AGF_MAGIC
);
2951 agf
->agf_versionnum
= cpu_to_be32(XFS_AGF_VERSION
);
2952 agf
->agf_seqno
= cpu_to_be32(agno
);
2953 agf
->agf_length
= cpu_to_be32(agsize
);
2954 agf
->agf_roots
[XFS_BTNUM_BNOi
] = cpu_to_be32(XFS_BNO_BLOCK(mp
));
2955 agf
->agf_roots
[XFS_BTNUM_CNTi
] = cpu_to_be32(XFS_CNT_BLOCK(mp
));
2956 agf
->agf_levels
[XFS_BTNUM_BNOi
] = cpu_to_be32(1);
2957 agf
->agf_levels
[XFS_BTNUM_CNTi
] = cpu_to_be32(1);
2958 pag
->pagf_levels
[XFS_BTNUM_BNOi
] = 1;
2959 pag
->pagf_levels
[XFS_BTNUM_CNTi
] = 1;
2960 if (xfs_sb_version_hasrmapbt(&mp
->m_sb
)) {
2961 agf
->agf_roots
[XFS_BTNUM_RMAPi
] =
2962 cpu_to_be32(XFS_RMAP_BLOCK(mp
));
2963 agf
->agf_levels
[XFS_BTNUM_RMAPi
] = cpu_to_be32(1);
2964 agf
->agf_rmap_blocks
= cpu_to_be32(1);
2966 if (xfs_sb_version_hasreflink(&mp
->m_sb
)) {
2967 agf
->agf_refcount_root
= cpu_to_be32(
2968 libxfs_refc_block(mp
));
2969 agf
->agf_refcount_level
= cpu_to_be32(1);
2970 agf
->agf_refcount_blocks
= cpu_to_be32(1);
2972 agf
->agf_flfirst
= 0;
2973 agf
->agf_fllast
= cpu_to_be32(XFS_AGFL_SIZE(mp
) - 1);
2974 agf
->agf_flcount
= 0;
2975 nbmblocks
= (xfs_extlen_t
)(agsize
- libxfs_prealloc_blocks(mp
));
2976 agf
->agf_freeblks
= cpu_to_be32(nbmblocks
);
2977 agf
->agf_longest
= cpu_to_be32(nbmblocks
);
2978 if (xfs_sb_version_hascrc(&mp
->m_sb
))
2979 platform_uuid_copy(&agf
->agf_uuid
, &mp
->m_sb
.sb_uuid
);
2981 if (loginternal
&& agno
== logagno
) {
2982 be32_add_cpu(&agf
->agf_freeblks
, -logblocks
);
2983 agf
->agf_longest
= cpu_to_be32(agsize
-
2984 XFS_FSB_TO_AGBNO(mp
, logstart
) - logblocks
);
2986 if (libxfs_alloc_min_freelist(mp
, pag
) > worst_freelist
)
2987 worst_freelist
= libxfs_alloc_min_freelist(mp
, pag
);
2988 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
2991 * AG freelist header block
2993 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
2994 XFS_AG_DADDR(mp
, agno
, XFS_AGFL_DADDR(mp
)),
2995 XFS_FSS_TO_BB(mp
, 1));
2996 buf
->b_ops
= &xfs_agfl_buf_ops
;
2997 agfl
= XFS_BUF_TO_AGFL(buf
);
2998 /* setting to 0xff results in initialisation to NULLAGBLOCK */
2999 memset(agfl
, 0xff, sectorsize
);
3000 if (xfs_sb_version_hascrc(&mp
->m_sb
)) {
3001 agfl
->agfl_magicnum
= cpu_to_be32(XFS_AGFL_MAGIC
);
3002 agfl
->agfl_seqno
= cpu_to_be32(agno
);
3003 platform_uuid_copy(&agfl
->agfl_uuid
, &mp
->m_sb
.sb_uuid
);
3004 for (bucket
= 0; bucket
< XFS_AGFL_SIZE(mp
); bucket
++)
3005 agfl
->agfl_bno
[bucket
] = cpu_to_be32(NULLAGBLOCK
);
3008 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3011 * AG header block: inodes
3013 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3014 XFS_AG_DADDR(mp
, agno
, XFS_AGI_DADDR(mp
)),
3015 XFS_FSS_TO_BB(mp
, 1));
3016 agi
= XFS_BUF_TO_AGI(buf
);
3017 buf
->b_ops
= &xfs_agi_buf_ops
;
3018 memset(agi
, 0, sectorsize
);
3019 agi
->agi_magicnum
= cpu_to_be32(XFS_AGI_MAGIC
);
3020 agi
->agi_versionnum
= cpu_to_be32(XFS_AGI_VERSION
);
3021 agi
->agi_seqno
= cpu_to_be32(agno
);
3022 agi
->agi_length
= cpu_to_be32((xfs_agblock_t
)agsize
);
3024 agi
->agi_root
= cpu_to_be32(XFS_IBT_BLOCK(mp
));
3025 agi
->agi_level
= cpu_to_be32(1);
3026 if (sb_feat
.finobt
) {
3027 agi
->agi_free_root
= cpu_to_be32(XFS_FIBT_BLOCK(mp
));
3028 agi
->agi_free_level
= cpu_to_be32(1);
3030 agi
->agi_freecount
= 0;
3031 agi
->agi_newino
= cpu_to_be32(NULLAGINO
);
3032 agi
->agi_dirino
= cpu_to_be32(NULLAGINO
);
3033 if (xfs_sb_version_hascrc(&mp
->m_sb
))
3034 platform_uuid_copy(&agi
->agi_uuid
, &mp
->m_sb
.sb_uuid
);
3035 for (c
= 0; c
< XFS_AGI_UNLINKED_BUCKETS
; c
++)
3036 agi
->agi_unlinked
[c
] = cpu_to_be32(NULLAGINO
);
3037 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3040 * BNO btree root block
3042 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3043 XFS_AGB_TO_DADDR(mp
, agno
, XFS_BNO_BLOCK(mp
)),
3045 buf
->b_ops
= &xfs_allocbt_buf_ops
;
3046 block
= XFS_BUF_TO_BLOCK(buf
);
3047 memset(block
, 0, blocksize
);
3048 libxfs_btree_init_block(mp
, buf
, XFS_BTNUM_BNO
, 0, 1, agno
, 0);
3050 arec
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
3051 arec
->ar_startblock
= cpu_to_be32(libxfs_prealloc_blocks(mp
));
3052 if (loginternal
&& agno
== logagno
) {
3055 * Have to insert two records
3056 * Insert pad record for stripe align of log
3058 arec
->ar_blockcount
= cpu_to_be32(
3059 XFS_FSB_TO_AGBNO(mp
, logstart
) -
3060 be32_to_cpu(arec
->ar_startblock
));
3063 * Insert record at start of internal log
3065 nrec
->ar_startblock
= cpu_to_be32(
3066 be32_to_cpu(arec
->ar_startblock
) +
3067 be32_to_cpu(arec
->ar_blockcount
));
3069 be16_add_cpu(&block
->bb_numrecs
, 1);
3072 * Change record start to after the internal log
3074 be32_add_cpu(&arec
->ar_startblock
, logblocks
);
3077 * Calculate the record block count and check for the case where
3078 * the log might have consumed all available space in the AG. If
3079 * so, reset the record count to 0 to avoid exposure of an invalid
3080 * record start block.
3082 arec
->ar_blockcount
= cpu_to_be32(agsize
-
3083 be32_to_cpu(arec
->ar_startblock
));
3084 if (!arec
->ar_blockcount
)
3085 block
->bb_numrecs
= 0;
3087 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3090 * CNT btree root block
3092 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3093 XFS_AGB_TO_DADDR(mp
, agno
, XFS_CNT_BLOCK(mp
)),
3095 buf
->b_ops
= &xfs_allocbt_buf_ops
;
3096 block
= XFS_BUF_TO_BLOCK(buf
);
3097 memset(block
, 0, blocksize
);
3098 libxfs_btree_init_block(mp
, buf
, XFS_BTNUM_CNT
, 0, 1, agno
, 0);
3100 arec
= XFS_ALLOC_REC_ADDR(mp
, block
, 1);
3101 arec
->ar_startblock
= cpu_to_be32(libxfs_prealloc_blocks(mp
));
3102 if (loginternal
&& agno
== logagno
) {
3104 arec
->ar_blockcount
= cpu_to_be32(
3105 XFS_FSB_TO_AGBNO(mp
, logstart
) -
3106 be32_to_cpu(arec
->ar_startblock
));
3108 nrec
->ar_startblock
= cpu_to_be32(
3109 be32_to_cpu(arec
->ar_startblock
) +
3110 be32_to_cpu(arec
->ar_blockcount
));
3112 be16_add_cpu(&block
->bb_numrecs
, 1);
3114 be32_add_cpu(&arec
->ar_startblock
, logblocks
);
3117 * Calculate the record block count and check for the case where
3118 * the log might have consumed all available space in the AG. If
3119 * so, reset the record count to 0 to avoid exposure of an invalid
3120 * record start block.
3122 arec
->ar_blockcount
= cpu_to_be32(agsize
-
3123 be32_to_cpu(arec
->ar_startblock
));
3124 if (!arec
->ar_blockcount
)
3125 block
->bb_numrecs
= 0;
3127 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3130 * refcount btree root block
3132 if (xfs_sb_version_hasreflink(&mp
->m_sb
)) {
3133 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3134 XFS_AGB_TO_DADDR(mp
, agno
,
3135 libxfs_refc_block(mp
)),
3137 buf
->b_ops
= &xfs_refcountbt_buf_ops
;
3139 block
= XFS_BUF_TO_BLOCK(buf
);
3140 memset(block
, 0, blocksize
);
3141 libxfs_btree_init_block(mp
, buf
, XFS_BTNUM_REFC
, 0,
3144 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3148 * INO btree root block
3150 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3151 XFS_AGB_TO_DADDR(mp
, agno
, XFS_IBT_BLOCK(mp
)),
3153 buf
->b_ops
= &xfs_inobt_buf_ops
;
3154 block
= XFS_BUF_TO_BLOCK(buf
);
3155 memset(block
, 0, blocksize
);
3156 libxfs_btree_init_block(mp
, buf
, XFS_BTNUM_INO
, 0, 0, agno
, 0);
3157 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3160 * Free INO btree root block
3162 if (sb_feat
.finobt
) {
3163 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3164 XFS_AGB_TO_DADDR(mp
, agno
, XFS_FIBT_BLOCK(mp
)),
3166 buf
->b_ops
= &xfs_inobt_buf_ops
;
3167 block
= XFS_BUF_TO_BLOCK(buf
);
3168 memset(block
, 0, blocksize
);
3169 libxfs_btree_init_block(mp
, buf
, XFS_BTNUM_FINO
, 0, 0, agno
, 0);
3170 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3173 /* RMAP btree root block */
3174 if (xfs_sb_version_hasrmapbt(&mp
->m_sb
)) {
3175 struct xfs_rmap_rec
*rrec
;
3177 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3178 XFS_AGB_TO_DADDR(mp
, agno
, XFS_RMAP_BLOCK(mp
)),
3180 buf
->b_ops
= &xfs_rmapbt_buf_ops
;
3181 block
= XFS_BUF_TO_BLOCK(buf
);
3182 memset(block
, 0, blocksize
);
3184 libxfs_btree_init_block(mp
, buf
, XFS_BTNUM_RMAP
, 0, 0, agno
, 0);
3187 * mark the AG header regions as static metadata
3188 * The BNO btree block is the first block after the
3189 * headers, so it's location defines the size of region
3190 * the static metadata consumes.
3192 rrec
= XFS_RMAP_REC_ADDR(block
, 1);
3193 rrec
->rm_startblock
= 0;
3194 rrec
->rm_blockcount
= cpu_to_be32(XFS_BNO_BLOCK(mp
));
3195 rrec
->rm_owner
= cpu_to_be64(XFS_RMAP_OWN_FS
);
3196 rrec
->rm_offset
= 0;
3197 be16_add_cpu(&block
->bb_numrecs
, 1);
3199 /* account freespace btree root blocks */
3200 rrec
= XFS_RMAP_REC_ADDR(block
, 2);
3201 rrec
->rm_startblock
= cpu_to_be32(XFS_BNO_BLOCK(mp
));
3202 rrec
->rm_blockcount
= cpu_to_be32(2);
3203 rrec
->rm_owner
= cpu_to_be64(XFS_RMAP_OWN_AG
);
3204 rrec
->rm_offset
= 0;
3205 be16_add_cpu(&block
->bb_numrecs
, 1);
3207 /* account inode btree root blocks */
3208 rrec
= XFS_RMAP_REC_ADDR(block
, 3);
3209 rrec
->rm_startblock
= cpu_to_be32(XFS_IBT_BLOCK(mp
));
3210 rrec
->rm_blockcount
= cpu_to_be32(XFS_RMAP_BLOCK(mp
) -
3212 rrec
->rm_owner
= cpu_to_be64(XFS_RMAP_OWN_INOBT
);
3213 rrec
->rm_offset
= 0;
3214 be16_add_cpu(&block
->bb_numrecs
, 1);
3216 /* account for rmap btree root */
3217 rrec
= XFS_RMAP_REC_ADDR(block
, 4);
3218 rrec
->rm_startblock
= cpu_to_be32(XFS_RMAP_BLOCK(mp
));
3219 rrec
->rm_blockcount
= cpu_to_be32(1);
3220 rrec
->rm_owner
= cpu_to_be64(XFS_RMAP_OWN_AG
);
3221 rrec
->rm_offset
= 0;
3222 be16_add_cpu(&block
->bb_numrecs
, 1);
3224 /* account for refcount btree root */
3225 if (xfs_sb_version_hasreflink(&mp
->m_sb
)) {
3226 rrec
= XFS_RMAP_REC_ADDR(block
, 5);
3227 rrec
->rm_startblock
= cpu_to_be32(
3228 libxfs_refc_block(mp
));
3229 rrec
->rm_blockcount
= cpu_to_be32(1);
3230 rrec
->rm_owner
= cpu_to_be64(XFS_RMAP_OWN_REFC
);
3231 rrec
->rm_offset
= 0;
3232 be16_add_cpu(&block
->bb_numrecs
, 1);
3235 /* account for the log space */
3236 if (loginternal
&& agno
== logagno
) {
3237 rrec
= XFS_RMAP_REC_ADDR(block
,
3238 be16_to_cpu(block
->bb_numrecs
) + 1);
3239 rrec
->rm_startblock
= cpu_to_be32(
3240 XFS_FSB_TO_AGBNO(mp
, logstart
));
3241 rrec
->rm_blockcount
= cpu_to_be32(logblocks
);
3242 rrec
->rm_owner
= cpu_to_be64(XFS_RMAP_OWN_LOG
);
3243 rrec
->rm_offset
= 0;
3244 be16_add_cpu(&block
->bb_numrecs
, 1);
3247 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3250 libxfs_perag_put(pag
);
3254 * Touch last block, make fs the right size if it's a file.
3256 buf
= libxfs_getbuf(mp
->m_ddev_targp
,
3257 (xfs_daddr_t
)XFS_FSB_TO_BB(mp
, dblocks
- 1LL), bsize
);
3258 memset(XFS_BUF_PTR(buf
), 0, blocksize
);
3259 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3262 * Make sure we can write the last block in the realtime area.
3264 if (mp
->m_rtdev_targp
->dev
&& rtblocks
> 0) {
3265 buf
= libxfs_getbuf(mp
->m_rtdev_targp
,
3266 XFS_FSB_TO_BB(mp
, rtblocks
- 1LL), bsize
);
3267 memset(XFS_BUF_PTR(buf
), 0, blocksize
);
3268 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3272 * BNO, CNT free block list
3274 for (agno
= 0; agno
< agcount
; agno
++) {
3275 xfs_alloc_arg_t args
;
3277 struct xfs_trans_res tres
= {0};
3279 c
= libxfs_trans_alloc(mp
, &tres
, worst_freelist
, 0, 0, &tp
);
3283 memset(&args
, 0, sizeof(args
));
3288 args
.pag
= libxfs_perag_get(mp
,agno
);
3290 libxfs_alloc_fix_freelist(&args
, 0);
3291 libxfs_perag_put(args
.pag
);
3292 libxfs_trans_commit(tp
);
3296 * Allocate the root inode and anything else in the proto file.
3298 parse_proto(mp
, &fsx
, &protostring
);
3301 * Protect ourselves against possible stupidity
3303 if (XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
) != 0) {
3305 _("%s: root inode created in AG %u, not AG 0\n"),
3306 progname
, XFS_INO_TO_AGNO(mp
, mp
->m_sb
.sb_rootino
));
3311 * Write out multiple secondary superblocks with rootinode field set
3313 if (mp
->m_sb
.sb_agcount
> 1) {
3315 * the last superblock
3317 buf
= libxfs_readbuf(mp
->m_dev
,
3318 XFS_AGB_TO_DADDR(mp
, mp
->m_sb
.sb_agcount
-1,
3320 XFS_FSS_TO_BB(mp
, 1),
3321 LIBXFS_EXIT_ON_FAILURE
, &xfs_sb_buf_ops
);
3322 XFS_BUF_TO_SBP(buf
)->sb_rootino
= cpu_to_be64(
3323 mp
->m_sb
.sb_rootino
);
3324 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3326 * and one in the middle for luck
3328 if (mp
->m_sb
.sb_agcount
> 2) {
3329 buf
= libxfs_readbuf(mp
->m_dev
,
3330 XFS_AGB_TO_DADDR(mp
, (mp
->m_sb
.sb_agcount
-1)/2,
3332 XFS_FSS_TO_BB(mp
, 1),
3333 LIBXFS_EXIT_ON_FAILURE
, &xfs_sb_buf_ops
);
3334 XFS_BUF_TO_SBP(buf
)->sb_rootino
= cpu_to_be64(
3335 mp
->m_sb
.sb_rootino
);
3336 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3341 * Dump all inodes and buffers before marking us all done.
3342 * Need to drop references to inodes we still hold, first.
3344 libxfs_rtmount_destroy(mp
);
3345 libxfs_bcache_purge();
3348 * Mark the filesystem ok.
3350 buf
= libxfs_getsb(mp
, LIBXFS_EXIT_ON_FAILURE
);
3351 (XFS_BUF_TO_SBP(buf
))->sb_inprogress
= 0;
3352 libxfs_writebuf(buf
, LIBXFS_EXIT_ON_FAILURE
);
3356 libxfs_device_close(xi
.rtdev
);
3357 if (xi
.logdev
&& xi
.logdev
!= xi
.ddev
)
3358 libxfs_device_close(xi
.logdev
);
3359 libxfs_device_close(xi
.ddev
);
3371 fprintf(stderr
, _("Cannot specify both -%c %s and -%c %s\n"),
3372 opt
, tab
[oldidx
], opt
, tab
[newidx
]);
3382 fprintf(stderr
, _("Illegal value %s for -%s option\n"), value
, opt
);
3390 return (i
& (i
- 1)) == 0;
3393 static void __attribute__((noreturn
))
3399 fprintf(stderr
, _("-%c %s option requires a value\n"), opt
, tab
[idx
]);
3409 fprintf(stderr
, "-%c ", opt
);
3411 fprintf(stderr
, "%s ", tab
[idx
]);
3412 fprintf(stderr
, _("option respecified\n"));
3421 fprintf(stderr
, _("unknown option -%c %s\n"), opt
, s
);
3427 unsigned int blksize
,
3428 unsigned int sectsize
,
3435 i
= strtoll(s
, &sp
, 0);
3436 if (i
== 0 && sp
== s
)
3447 _("Blocksize must be provided prior to using 'b' suffix.\n"));
3456 _("Sectorsize must be specified prior to using 's' suffix.\n"));
3459 return i
* sectsize
;
3488 static void __attribute__((noreturn
))
3491 fprintf(stderr
, _("Usage: %s\n\
3492 /* blocksize */ [-b log=n|size=num]\n\
3493 /* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]\n\
3494 /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
3495 (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
3496 sectlog=n|sectsize=num\n\
3497 /* force overwrite */ [-f]\n\
3498 /* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
3499 projid32bit=0|1,sparse=0|1]\n\
3500 /* no discard */ [-K]\n\
3501 /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
3502 sunit=value|su=num,sectlog=n|sectsize=num,\n\
3504 /* label */ [-L label (maximum 12 characters)]\n\
3505 /* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\
3506 /* no-op info only */ [-N]\n\
3507 /* prototype file */ [-p fname]\n\
3509 /* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\
3510 /* sectorsize */ [-s log=n|size=num]\n\
3511 /* version */ [-V]\n\
3513 <devicename> is required unless -d name=xxx is given.\n\
3514 <num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n\
3515 xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n\
3516 <value> is xxx (512 byte blocks).\n"),