2 * Copyright (c) 2000-2001,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
19 #include <xfs/libxfs.h>
20 #include <xfs/libxlog.h>
32 static int sb_f(int argc
, char **argv
);
33 static void sb_help(void);
34 static int uuid_f(int argc
, char **argv
);
35 static void uuid_help(void);
36 static int label_f(int argc
, char **argv
);
37 static void label_help(void);
38 static int version_f(int argc
, char **argv
);
39 static void version_help(void);
41 static const cmdinfo_t sb_cmd
=
42 { "sb", NULL
, sb_f
, 0, 1, 1, N_("[agno]"),
43 N_("set current address to sb header"), sb_help
};
44 static const cmdinfo_t uuid_cmd
=
45 { "uuid", NULL
, uuid_f
, 0, 1, 1, N_("[uuid]"),
46 N_("write/print FS uuid"), uuid_help
};
47 static const cmdinfo_t label_cmd
=
48 { "label", NULL
, label_f
, 0, 1, 1, N_("[label]"),
49 N_("write/print FS label"), label_help
};
50 static const cmdinfo_t version_cmd
=
51 { "version", NULL
, version_f
, 0, -1, 1, N_("[feature | [vnum fnum]]"),
52 N_("set feature bit(s) in the sb version field"), version_help
};
58 add_command(&uuid_cmd
);
59 add_command(&label_cmd
);
60 add_command(&version_cmd
);
63 #define OFF(f) bitize(offsetof(xfs_sb_t, sb_ ## f))
64 #define SZC(f) szcount(xfs_sb_t, sb_ ## f)
65 const field_t sb_flds
[] = {
66 { "magicnum", FLDT_UINT32X
, OI(OFF(magicnum
)), C1
, 0, TYP_NONE
},
67 { "blocksize", FLDT_UINT32D
, OI(OFF(blocksize
)), C1
, 0, TYP_NONE
},
68 { "dblocks", FLDT_DRFSBNO
, OI(OFF(dblocks
)), C1
, 0, TYP_NONE
},
69 { "rblocks", FLDT_DRFSBNO
, OI(OFF(rblocks
)), C1
, 0, TYP_NONE
},
70 { "rextents", FLDT_DRTBNO
, OI(OFF(rextents
)), C1
, 0, TYP_NONE
},
71 { "uuid", FLDT_UUID
, OI(OFF(uuid
)), C1
, 0, TYP_NONE
},
72 { "logstart", FLDT_DFSBNO
, OI(OFF(logstart
)), C1
, 0, TYP_LOG
},
73 { "rootino", FLDT_INO
, OI(OFF(rootino
)), C1
, 0, TYP_INODE
},
74 { "rbmino", FLDT_INO
, OI(OFF(rbmino
)), C1
, 0, TYP_INODE
},
75 { "rsumino", FLDT_INO
, OI(OFF(rsumino
)), C1
, 0, TYP_INODE
},
76 { "rextsize", FLDT_AGBLOCK
, OI(OFF(rextsize
)), C1
, 0, TYP_NONE
},
77 { "agblocks", FLDT_AGBLOCK
, OI(OFF(agblocks
)), C1
, 0, TYP_NONE
},
78 { "agcount", FLDT_AGNUMBER
, OI(OFF(agcount
)), C1
, 0, TYP_NONE
},
79 { "rbmblocks", FLDT_EXTLEN
, OI(OFF(rbmblocks
)), C1
, 0, TYP_NONE
},
80 { "logblocks", FLDT_EXTLEN
, OI(OFF(logblocks
)), C1
, 0, TYP_NONE
},
81 { "versionnum", FLDT_UINT16X
, OI(OFF(versionnum
)), C1
, 0, TYP_NONE
},
82 { "sectsize", FLDT_UINT16D
, OI(OFF(sectsize
)), C1
, 0, TYP_NONE
},
83 { "inodesize", FLDT_UINT16D
, OI(OFF(inodesize
)), C1
, 0, TYP_NONE
},
84 { "inopblock", FLDT_UINT16D
, OI(OFF(inopblock
)), C1
, 0, TYP_NONE
},
85 { "fname", FLDT_CHARNS
, OI(OFF(fname
)), CI(SZC(fname
)), 0, TYP_NONE
},
86 { "blocklog", FLDT_UINT8D
, OI(OFF(blocklog
)), C1
, 0, TYP_NONE
},
87 { "sectlog", FLDT_UINT8D
, OI(OFF(sectlog
)), C1
, 0, TYP_NONE
},
88 { "inodelog", FLDT_UINT8D
, OI(OFF(inodelog
)), C1
, 0, TYP_NONE
},
89 { "inopblog", FLDT_UINT8D
, OI(OFF(inopblog
)), C1
, 0, TYP_NONE
},
90 { "agblklog", FLDT_UINT8D
, OI(OFF(agblklog
)), C1
, 0, TYP_NONE
},
91 { "rextslog", FLDT_UINT8D
, OI(OFF(rextslog
)), C1
, 0, TYP_NONE
},
92 { "inprogress", FLDT_UINT8D
, OI(OFF(inprogress
)), C1
, 0, TYP_NONE
},
93 { "imax_pct", FLDT_UINT8D
, OI(OFF(imax_pct
)), C1
, 0, TYP_NONE
},
94 { "icount", FLDT_UINT64D
, OI(OFF(icount
)), C1
, 0, TYP_NONE
},
95 { "ifree", FLDT_UINT64D
, OI(OFF(ifree
)), C1
, 0, TYP_NONE
},
96 { "fdblocks", FLDT_UINT64D
, OI(OFF(fdblocks
)), C1
, 0, TYP_NONE
},
97 { "frextents", FLDT_UINT64D
, OI(OFF(frextents
)), C1
, 0, TYP_NONE
},
98 { "uquotino", FLDT_INO
, OI(OFF(uquotino
)), C1
, 0, TYP_INODE
},
99 { "gquotino", FLDT_INO
, OI(OFF(gquotino
)), C1
, 0, TYP_INODE
},
100 { "qflags", FLDT_UINT16X
, OI(OFF(qflags
)), C1
, 0, TYP_NONE
},
101 { "flags", FLDT_UINT8X
, OI(OFF(flags
)), C1
, 0, TYP_NONE
},
102 { "shared_vn", FLDT_UINT8D
, OI(OFF(shared_vn
)), C1
, 0, TYP_NONE
},
103 { "inoalignmt", FLDT_EXTLEN
, OI(OFF(inoalignmt
)), C1
, 0, TYP_NONE
},
104 { "unit", FLDT_UINT32D
, OI(OFF(unit
)), C1
, 0, TYP_NONE
},
105 { "width", FLDT_UINT32D
, OI(OFF(width
)), C1
, 0, TYP_NONE
},
106 { "dirblklog", FLDT_UINT8D
, OI(OFF(dirblklog
)), C1
, 0, TYP_NONE
},
107 { "logsectlog", FLDT_UINT8D
, OI(OFF(logsectlog
)), C1
, 0, TYP_NONE
},
108 { "logsectsize", FLDT_UINT16D
, OI(OFF(logsectsize
)), C1
, 0, TYP_NONE
},
109 { "logsunit", FLDT_UINT32D
, OI(OFF(logsunit
)), C1
, 0, TYP_NONE
},
110 { "features2", FLDT_UINT32X
, OI(OFF(features2
)), C1
, 0, TYP_NONE
},
111 { "bad_features2", FLDT_UINT32X
, OI(OFF(bad_features2
)),
113 { "features_compat", FLDT_UINT32X
, OI(OFF(features_compat
)),
115 { "features_ro_compat", FLDT_UINT32X
, OI(OFF(features_ro_compat
)),
117 { "features_incompat", FLDT_UINT32X
, OI(OFF(features_incompat
)),
119 { "features_log_incompat", FLDT_UINT32X
, OI(OFF(features_log_incompat
)),
121 { "crc", FLDT_CRC
, OI(OFF(crc
)), C1
, 0, TYP_NONE
},
122 { "pquotino", FLDT_INO
, OI(OFF(pquotino
)), C1
, 0, TYP_INODE
},
123 { "lsn", FLDT_UINT64X
, OI(OFF(lsn
)), C1
, 0, TYP_NONE
},
127 const field_t sb_hfld
[] = {
128 { "", FLDT_SB
, OI(0), C1
, 0, TYP_NONE
},
137 " set allocation group superblock\n"
141 " 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n"
143 " Located in the first sector of each allocation group, the superblock\n"
144 " contains the base information for the filesystem.\n"
145 " The superblock in allocation group 0 is the primary. The copies in the\n"
146 " remaining allocation groups only serve as backup for filesystem recovery.\n"
147 " The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n"
161 agno
= (xfs_agnumber_t
)strtoul(argv
[1], &p
, 0);
162 if (*p
!= '\0' || agno
>= mp
->m_sb
.sb_agcount
) {
163 dbprintf(_("bad allocation group number %s\n"), argv
[1]);
167 } else if (cur_agno
== NULLAGNUMBER
)
169 ASSERT(typtab
[TYP_SB
].typnm
== TYP_SB
);
170 set_cur(&typtab
[TYP_SB
],
171 XFS_AG_DADDR(mp
, cur_agno
, XFS_SB_DADDR
),
172 XFS_FSS_TO_BB(mp
, 1), DB_RING_ADD
, NULL
);
183 return bitize(mp
->m_sb
.sb_sectsize
);
187 get_sb(xfs_agnumber_t agno
, xfs_sb_t
*sb
)
190 set_cur(&typtab
[TYP_SB
],
191 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
192 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
194 if (!iocur_top
->data
) {
195 dbprintf(_("can't read superblock for AG %u\n"), agno
);
200 libxfs_sb_from_disk(sb
, iocur_top
->data
);
202 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
) {
203 dbprintf(_("bad sb magic # %#x in AG %u\n"),
204 sb
->sb_magicnum
, agno
);
207 if (!xfs_sb_good_version(sb
)) {
208 dbprintf(_("bad sb version # %#x in AG %u\n"),
209 sb
->sb_versionnum
, agno
);
212 if (agno
== 0 && sb
->sb_inprogress
!= 0) {
213 dbprintf(_("mkfs not completed successfully\n"));
219 /* workaround craziness in the xlog routines */
220 int xlog_recover_do_trans(struct xlog
*log
, xlog_recover_t
*t
, int p
)
230 if (mp
->m_sb
.sb_logstart
) {
231 if (x
.logdev
&& x
.logdev
!= x
.ddev
) {
232 dbprintf(_("aborting - external log specified for FS "
233 "with an internal log\n"));
237 if (!x
.logdev
|| (x
.logdev
== x
.ddev
)) {
238 dbprintf(_("aborting - no external log specified for FS "
239 "with an external log\n"));
244 libxfs_buftarg_init(mp
, x
.ddev
, x
.logdev
, x
.rtdev
);
246 dirty
= xlog_is_dirty(mp
, &x
, 0);
248 dbprintf(_("ERROR: cannot find log head/tail, run xfs_repair\n"));
250 } else if (dirty
== 1) {
252 "ERROR: The filesystem has valuable metadata changes in a log which needs to\n"
253 "be replayed. Mount the filesystem to replay the log, and unmount it before\n"
254 "re-running %s. If you are unable to mount the filesystem, then use\n"
255 "the xfs_repair -L option to destroy the log and attempt a repair.\n"
256 "Note that destroying the log may cause corruption -- please attempt a mount\n"
257 "of the filesystem before doing this.\n"), progname
);
265 sb_logzero(uuid_t
*uuidp
)
270 dbprintf(_("Clearing log and setting UUID\n"));
272 if (libxfs_log_clear(mp
->m_logdev_targp
,
273 XFS_FSB_TO_DADDR(mp
, mp
->m_sb
.sb_logstart
),
274 (xfs_extlen_t
)XFS_FSB_TO_BB(mp
, mp
->m_sb
.sb_logblocks
),
276 xfs_sb_version_haslogv2(&mp
->m_sb
) ? 2 : 1,
277 mp
->m_sb
.sb_logsunit
, XLOG_FMT
)) {
278 dbprintf(_("ERROR: cannot clear the log\n"));
290 " write/print FS uuid\n"
294 " 'uuid' - print UUID\n"
295 " 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n"
296 " 'uuid generate' - generate and write\n"
297 " 'uuid rewrite' - copy UUID from SB 0\n"
299 "The print function checks the UUID in each SB and will warn if the UUIDs\n"
300 "differ between AGs (the log is not checked). The write commands will\n"
301 "set the uuid in all AGs to either a specified value, a newly generated\n"
302 "value or the value found in the first superblock (SB 0) respectively.\n"
303 "As a side effect of writing the UUID, the log is cleared (which is fine\n"
304 "on a CLEANLY unmounted FS).\n"
310 do_uuid(xfs_agnumber_t agno
, uuid_t
*uuid
)
315 if (!get_sb(agno
, &tsb
))
318 if (!uuid
) { /* get uuid */
319 memcpy(&uu
, &tsb
.sb_uuid
, sizeof(uuid_t
));
324 memcpy(&tsb
.sb_uuid
, uuid
, sizeof(uuid_t
));
325 libxfs_sb_to_disk(iocur_top
->data
, &tsb
, XFS_SB_UUID
);
340 if (argc
!= 1 && argc
!= 2) {
341 dbprintf(_("invalid parameters\n"));
345 if (argc
== 2) { /* WRITE UUID */
347 if ((x
.isreadonly
& LIBXFS_ISREADONLY
) || !expert_mode
) {
348 dbprintf(_("%s: not in expert mode, writing disabled\n"),
354 * For now, changing the UUID of V5 superblock filesystems is
355 * not supported; we do not have the infrastructure to fix all
356 * other metadata when a new superblock UUID is generated.
358 if (xfs_sb_version_hascrc(&mp
->m_sb
) &&
359 strcasecmp(argv
[1], "rewrite")) {
360 dbprintf(_("%s: only 'rewrite' supported on V5 fs\n"),
365 if (!strcasecmp(argv
[1], "generate")) {
366 platform_uuid_generate(&uu
);
367 } else if (!strcasecmp(argv
[1], "nil")) {
368 platform_uuid_clear(&uu
);
369 } else if (!strcasecmp(argv
[1], "rewrite")) {
370 uup
= do_uuid(0, NULL
);
372 dbprintf(_("failed to read UUID from AG 0\n"));
375 memcpy(&uu
, uup
, sizeof(uuid_t
));
376 platform_uuid_unparse(&uu
, bp
);
377 dbprintf(_("old UUID = %s\n"), bp
);
379 if (platform_uuid_parse(argv
[1], &uu
)) {
380 dbprintf(_("invalid UUID\n"));
385 /* clear the log (setting uuid) if it's not dirty */
386 if (!sb_logzero(&uu
))
389 dbprintf(_("writing all SBs\n"));
390 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
391 if (!do_uuid(agno
, &uu
)) {
392 dbprintf(_("failed to set UUID in AG %d\n"), agno
);
396 platform_uuid_unparse(&uu
, bp
);
397 dbprintf(_("new UUID = %s\n"), bp
);
400 } else { /* READ+CHECK UUID */
402 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
403 uup
= do_uuid(agno
, NULL
);
405 dbprintf(_("failed to read UUID from AG %d\n"),
410 if (memcmp(&uu
, uup
, sizeof(uuid_t
))) {
411 dbprintf(_("warning: UUID in AG %d "
412 "differs to the primary SB\n"),
417 memcpy(&uu
, uup
, sizeof(uuid_t
));
420 if (mp
->m_sb
.sb_logstart
) {
421 if (x
.logdev
&& x
.logdev
!= x
.ddev
)
422 dbprintf(_("warning - external log specified "
423 "for FS with an internal log\n"));
424 } else if (!x
.logdev
|| (x
.logdev
== x
.ddev
)) {
425 dbprintf(_("warning - no external log specified "
426 "for FS with an external log\n"));
429 platform_uuid_unparse(&uu
, bp
);
430 dbprintf(_("UUID = %s\n"), bp
);
442 " write/print FS label\n"
446 " 'label' - print label\n"
447 " 'label 123456789012' - write label\n"
448 " 'label --' - write an empty label\n"
450 "The print function checks the label in each SB and will warn if the labels\n"
451 "differ between AGs. The write commands will set the label in all AGs to the\n"
452 "specified value. The maximum length of a label is 12 characters - use of a\n"
453 "longer label will result in truncation and a warning will be issued.\n"
459 do_label(xfs_agnumber_t agno
, char *label
)
463 static char lbl
[sizeof(tsb
.sb_fname
) + 1];
465 if (!get_sb(agno
, &tsb
))
468 memset(&lbl
[0], 0, sizeof(lbl
));
470 if (!label
) { /* get label */
472 memcpy(&lbl
[0], &tsb
.sb_fname
, sizeof(tsb
.sb_fname
));
476 if ((len
= strlen(label
)) > sizeof(tsb
.sb_fname
)) {
478 dbprintf(_("%s: truncating label length from %d to %d\n"),
479 progname
, (int)len
, (int)sizeof(tsb
.sb_fname
));
480 len
= sizeof(tsb
.sb_fname
);
483 (strcmp(label
, "\"\"") == 0 ||
484 strcmp(label
, "''") == 0 ||
485 strcmp(label
, "--") == 0) )
486 label
[0] = label
[1] = '\0';
487 memset(&tsb
.sb_fname
, 0, sizeof(tsb
.sb_fname
));
488 memcpy(&tsb
.sb_fname
, label
, len
);
489 memcpy(&lbl
[0], &tsb
.sb_fname
, sizeof(tsb
.sb_fname
));
490 libxfs_sb_to_disk(iocur_top
->data
, &tsb
, XFS_SB_FNAME
);
504 if (argc
!= 1 && argc
!= 2) {
505 dbprintf(_("invalid parameters\n"));
509 if (argc
== 2) { /* WRITE LABEL */
511 if ((x
.isreadonly
& LIBXFS_ISREADONLY
) || !expert_mode
) {
512 dbprintf(_("%s: not in expert mode, writing disabled\n"),
517 dbprintf(_("writing all SBs\n"));
518 for (ag
= 0; ag
< mp
->m_sb
.sb_agcount
; ag
++)
519 if ((p
= do_label(ag
, argv
[1])) == NULL
) {
520 dbprintf(_("failed to set label in AG %d\n"), ag
);
523 dbprintf(_("new label = \"%s\"\n"), p
);
525 } else { /* READ LABEL */
527 for (ag
= 0; ag
< mp
->m_sb
.sb_agcount
; ag
++) {
528 p
= do_label(ag
, NULL
);
530 dbprintf(_("failed to read label in AG %d\n"), ag
);
534 memcpy(&sb
.sb_fname
, p
, sizeof(sb
.sb_fname
));
535 else if (memcmp(&sb
.sb_fname
, p
, sizeof(sb
.sb_fname
)))
536 dbprintf(_("warning: AG %d label differs\n"), ag
);
538 dbprintf(_("label = \"%s\"\n"), p
);
549 " set/print feature bits in sb version\n"
553 " 'version' - print current feature bits\n"
554 " 'version extflg' - enable unwritten extents\n"
555 " 'version attr1' - enable v1 inline extended attributes\n"
556 " 'version attr2' - enable v2 inline extended attributes\n"
557 " 'version log2' - enable v2 log format\n"
559 "The version function prints currently enabled features for a filesystem\n"
560 "according to the version field of its primary superblock.\n"
561 "It can also be used to enable selected features, such as support for\n"
562 "unwritten extents. The updated version is written into all AGs.\n"
568 do_version(xfs_agnumber_t agno
, __uint16_t version
, __uint32_t features
)
571 __int64_t fields
= 0;
573 if (!get_sb(agno
, &tsb
))
576 if (xfs_sb_has_mismatched_features2(&tsb
)) {
577 dbprintf(_("Superblock has mismatched features2 fields, "
578 "skipping modification\n"));
582 if ((version
& XFS_SB_VERSION_LOGV2BIT
) &&
583 !xfs_sb_version_haslogv2(&tsb
)) {
585 fields
|= (1LL << XFS_SBS_LOGSUNIT
);
588 tsb
.sb_versionnum
= version
;
589 tsb
.sb_features2
= features
;
590 tsb
.sb_bad_features2
= features
;
591 fields
|= XFS_SB_VERSIONNUM
| XFS_SB_FEATURES2
| XFS_SB_BAD_FEATURES2
;
592 libxfs_sb_to_disk(iocur_top
->data
, &tsb
, fields
);
603 if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_1
)
605 else if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_2
)
607 else if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_3
)
609 else if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_4
)
611 else if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_5
)
614 if (xfs_sb_version_hasattr(sbp
))
616 if (xfs_sb_version_hasnlink(sbp
))
618 if (xfs_sb_version_hasquota(sbp
))
620 if (xfs_sb_version_hasalign(sbp
))
622 if (xfs_sb_version_hasdalign(sbp
))
623 strcat(s
, ",DALIGN");
624 if (xfs_sb_version_hasshared(sbp
))
625 strcat(s
, ",SHARED");
626 if (xfs_sb_version_hasdirv2(sbp
))
628 if (xfs_sb_version_haslogv2(sbp
))
630 if (xfs_sb_version_hasextflgbit(sbp
))
631 strcat(s
, ",EXTFLG");
632 if (xfs_sb_version_hassector(sbp
))
633 strcat(s
, ",SECTOR");
634 if (xfs_sb_version_hasasciici(sbp
))
635 strcat(s
, ",ASCII_CI");
636 if (xfs_sb_version_hasmorebits(sbp
))
637 strcat(s
, ",MOREBITS");
638 if (xfs_sb_version_hasattr2(sbp
))
640 if (xfs_sb_version_haslazysbcount(sbp
))
641 strcat(s
, ",LAZYSBCOUNT");
642 if (xfs_sb_version_hasprojid32bit(sbp
))
643 strcat(s
, ",PROJID32BIT");
644 if (xfs_sb_version_hascrc(sbp
))
646 if (xfs_sb_version_hasftype(sbp
))
648 if (xfs_sb_version_hasfinobt(sbp
))
649 strcat(s
, ",FINOBT");
654 * XXX: this only supports reading and writing to version 4 superblock fields.
655 * V5 superblocks always define certain V4 feature bits - they are blocked from
656 * being changed if a V5 sb is detected, but otherwise v5 superblock features
657 * are not handled here.
664 __uint16_t version
= 0;
665 __uint32_t features
= 0;
668 if (argc
== 2) { /* WRITE VERSION */
670 if ((x
.isreadonly
& LIBXFS_ISREADONLY
) || !expert_mode
) {
671 dbprintf(_("%s: not in expert mode, writing disabled\n"),
676 /* Logic here derived from the IRIX xfs_chver(1M) script. */
677 if (!strcasecmp(argv
[1], "extflg")) {
678 switch (XFS_SB_VERSION_NUM(&mp
->m_sb
)) {
679 case XFS_SB_VERSION_1
:
680 version
= 0x0004 | XFS_SB_VERSION_EXTFLGBIT
;
682 case XFS_SB_VERSION_2
:
683 version
= 0x0014 | XFS_SB_VERSION_EXTFLGBIT
;
685 case XFS_SB_VERSION_3
:
686 version
= 0x0034 | XFS_SB_VERSION_EXTFLGBIT
;
688 case XFS_SB_VERSION_4
:
689 if (xfs_sb_version_hasextflgbit(&mp
->m_sb
))
691 _("unwritten extents flag is already enabled\n"));
693 version
= mp
->m_sb
.sb_versionnum
|
694 XFS_SB_VERSION_EXTFLGBIT
;
696 case XFS_SB_VERSION_5
:
698 _("unwritten extents always enabled for v5 superblocks.\n"));
701 } else if (!strcasecmp(argv
[1], "log2")) {
702 switch (XFS_SB_VERSION_NUM(&mp
->m_sb
)) {
703 case XFS_SB_VERSION_1
:
704 version
= 0x0004 | XFS_SB_VERSION_LOGV2BIT
;
706 case XFS_SB_VERSION_2
:
707 version
= 0x0014 | XFS_SB_VERSION_LOGV2BIT
;
709 case XFS_SB_VERSION_3
:
710 version
= 0x0034 | XFS_SB_VERSION_LOGV2BIT
;
712 case XFS_SB_VERSION_4
:
713 if (xfs_sb_version_haslogv2(&mp
->m_sb
))
715 _("version 2 log format is already in use\n"));
717 version
= mp
->m_sb
.sb_versionnum
|
718 XFS_SB_VERSION_LOGV2BIT
;
720 case XFS_SB_VERSION_5
:
722 _("Version 2 logs always enabled for v5 superblocks.\n"));
725 } else if (XFS_SB_VERSION_NUM(&mp
->m_sb
) == XFS_SB_VERSION_5
) {
727 _("%s: Cannot change %s on v5 superblocks.\n"),
730 } else if (!strcasecmp(argv
[1], "attr1")) {
732 if (xfs_sb_version_hasattr2(&mp
->m_sb
)) {
733 if (!(mp
->m_sb
.sb_features2
&=
734 ~XFS_SB_VERSION2_ATTR2BIT
))
735 mp
->m_sb
.sb_versionnum
&=
736 ~XFS_SB_VERSION_MOREBITSBIT
;
738 xfs_sb_version_addattr(&mp
->m_sb
);
739 version
= mp
->m_sb
.sb_versionnum
;
740 features
= mp
->m_sb
.sb_features2
;
741 } else if (!strcasecmp(argv
[1], "attr2")) {
742 xfs_sb_version_addattr(&mp
->m_sb
);
743 xfs_sb_version_addattr2(&mp
->m_sb
);
744 version
= mp
->m_sb
.sb_versionnum
;
745 features
= mp
->m_sb
.sb_features2
;
746 } else if (!strcasecmp(argv
[1], "projid32bit")) {
747 xfs_sb_version_addprojid32bit(&mp
->m_sb
);
748 version
= mp
->m_sb
.sb_versionnum
;
749 features
= mp
->m_sb
.sb_features2
;
751 dbprintf(_("%s: invalid version change command \"%s\"\n"),
757 dbprintf(_("writing all SBs\n"));
758 for (ag
= 0; ag
< mp
->m_sb
.sb_agcount
; ag
++)
759 if (!do_version(ag
, version
, features
)) {
760 dbprintf(_("failed to set versionnum "
764 mp
->m_sb
.sb_versionnum
= version
;
765 mp
->m_sb
.sb_features2
= features
;
769 if (argc
== 3) { /* VERSIONNUM + FEATURES2 */
772 version
= mp
->m_sb
.sb_versionnum
;
773 features
= mp
->m_sb
.sb_features2
;
774 mp
->m_sb
.sb_versionnum
= strtoul(argv
[1], &sp
, 0);
775 mp
->m_sb
.sb_features2
= strtoul(argv
[2], &sp
, 0);
778 dbprintf(_("versionnum [0x%x+0x%x] = %s\n"), mp
->m_sb
.sb_versionnum
,
779 mp
->m_sb
.sb_features2
, version_string(&mp
->m_sb
));
781 if (argc
== 3) { /* now reset... */
782 mp
->m_sb
.sb_versionnum
= version
;
783 mp
->m_sb
.sb_features2
= features
;