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
)), C1
, 0, TYP_NONE
},
115 const field_t sb_hfld
[] = {
116 { "", FLDT_SB
, OI(0), C1
, 0, TYP_NONE
},
125 " set allocation group superblock\n"
129 " 'sb 7' - set location to 7th allocation group superblock, set type to 'sb'\n"
131 " Located in the first sector of each allocation group, the superblock\n"
132 " contains the base information for the filesystem.\n"
133 " The superblock in allocation group 0 is the primary. The copies in the\n"
134 " remaining allocation groups only serve as backup for filesystem recovery.\n"
135 " The icount/ifree/fdblocks/frextents are only updated in superblock 0.\n"
149 agno
= (xfs_agnumber_t
)strtoul(argv
[1], &p
, 0);
150 if (*p
!= '\0' || agno
>= mp
->m_sb
.sb_agcount
) {
151 dbprintf(_("bad allocation group number %s\n"), argv
[1]);
155 } else if (cur_agno
== NULLAGNUMBER
)
157 ASSERT(typtab
[TYP_SB
].typnm
== TYP_SB
);
158 set_cur(&typtab
[TYP_SB
],
159 XFS_AG_DADDR(mp
, cur_agno
, XFS_SB_DADDR
),
160 XFS_FSS_TO_BB(mp
, 1), DB_RING_ADD
, NULL
);
171 return bitize(mp
->m_sb
.sb_sectsize
);
175 get_sb(xfs_agnumber_t agno
, xfs_sb_t
*sb
)
178 set_cur(&typtab
[TYP_SB
],
179 XFS_AG_DADDR(mp
, agno
, XFS_SB_DADDR
),
180 XFS_FSS_TO_BB(mp
, 1), DB_RING_IGN
, NULL
);
182 if (!iocur_top
->data
) {
183 dbprintf(_("can't read superblock for AG %u\n"), agno
);
188 libxfs_sb_from_disk(sb
, iocur_top
->data
);
190 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
) {
191 dbprintf(_("bad sb magic # %#x in AG %u\n"),
192 sb
->sb_magicnum
, agno
);
195 if (!xfs_sb_good_version(sb
)) {
196 dbprintf(_("bad sb version # %#x in AG %u\n"),
197 sb
->sb_versionnum
, agno
);
200 if (agno
== 0 && sb
->sb_inprogress
!= 0) {
201 dbprintf(_("mkfs not completed successfully\n"));
207 /* workaround craziness in the xlog routines */
208 int xlog_recover_do_trans(struct xlog
*log
, xlog_recover_t
*t
, int p
)
217 xfs_daddr_t head_blk
, tail_blk
;
219 if (mp
->m_sb
.sb_logstart
) {
220 if (x
.logdev
&& x
.logdev
!= x
.ddev
) {
221 dbprintf(_("aborting - external log specified for FS "
222 "with an internal log\n"));
226 if (!x
.logdev
|| (x
.logdev
== x
.ddev
)) {
227 dbprintf(_("aborting - no external log specified for FS "
228 "with an external log\n"));
233 memset(&log
, 0, sizeof(log
));
234 libxfs_buftarg_init(mp
, x
.ddev
, x
.logdev
, x
.rtdev
);
235 x
.logBBsize
= XFS_FSB_TO_BB(mp
, mp
->m_sb
.sb_logblocks
);
236 x
.logBBstart
= XFS_FSB_TO_DADDR(mp
, mp
->m_sb
.sb_logstart
);
238 if (xfs_sb_version_hassector(&mp
->m_sb
))
239 x
.lbsize
<<= (mp
->m_sb
.sb_logsectlog
- BBSHIFT
);
241 log
.l_dev
= mp
->m_logdev_targp
;
242 log
.l_logsize
= BBTOB(log
.l_logBBsize
);
243 log
.l_logBBsize
= x
.logBBsize
;
244 log
.l_logBBstart
= x
.logBBstart
;
245 log
.l_sectBBsize
= BTOBB(x
.lbsize
);
248 if (xlog_find_tail(&log
, &head_blk
, &tail_blk
)) {
249 dbprintf(_("ERROR: cannot find log head/tail, run xfs_repair\n"));
252 if (head_blk
!= tail_blk
) {
254 "ERROR: The filesystem has valuable metadata changes in a log which needs to\n"
255 "be replayed. Mount the filesystem to replay the log, and unmount it before\n"
256 "re-running %s. If you are unable to mount the filesystem, then use\n"
257 "the xfs_repair -L option to destroy the log and attempt a repair.\n"
258 "Note that destroying the log may cause corruption -- please attempt a mount\n"
259 "of the filesystem before doing this.\n"), progname
);
266 sb_logzero(uuid_t
*uuidp
)
271 dbprintf(_("Clearing log and setting UUID\n"));
273 if (libxfs_log_clear(mp
->m_logdev_targp
,
274 XFS_FSB_TO_DADDR(mp
, mp
->m_sb
.sb_logstart
),
275 (xfs_extlen_t
)XFS_FSB_TO_BB(mp
, mp
->m_sb
.sb_logblocks
),
277 xfs_sb_version_haslogv2(&mp
->m_sb
) ? 2 : 1,
278 mp
->m_sb
.sb_logsunit
, XLOG_FMT
)) {
279 dbprintf(_("ERROR: cannot clear the log\n"));
291 " write/print FS uuid\n"
295 " 'uuid' - print UUID\n"
296 " 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n"
297 " 'uuid generate' - generate and write\n"
298 " 'uuid rewrite' - copy UUID from SB 0\n"
300 "The print function checks the UUID in each SB and will warn if the UUIDs\n"
301 "differ between AGs (the log is not checked). The write commands will\n"
302 "set the uuid in all AGs to either a specified value, a newly generated\n"
303 "value or the value found in the first superblock (SB 0) respectively.\n"
304 "As a side effect of writing the UUID, the log is cleared (which is fine\n"
305 "on a CLEANLY unmounted FS).\n"
311 do_uuid(xfs_agnumber_t agno
, uuid_t
*uuid
)
316 if (!get_sb(agno
, &tsb
))
319 if (!uuid
) { /* get uuid */
320 memcpy(&uu
, &tsb
.sb_uuid
, sizeof(uuid_t
));
325 memcpy(&tsb
.sb_uuid
, uuid
, sizeof(uuid_t
));
326 libxfs_sb_to_disk(iocur_top
->data
, &tsb
, XFS_SB_UUID
);
341 if (argc
!= 1 && argc
!= 2) {
342 dbprintf(_("invalid parameters\n"));
346 if (argc
== 2) { /* WRITE UUID */
348 if ((x
.isreadonly
& LIBXFS_ISREADONLY
) || !expert_mode
) {
349 dbprintf(_("%s: not in expert mode, writing disabled\n"),
354 if (!strcasecmp(argv
[1], "generate")) {
355 platform_uuid_generate(&uu
);
356 } else if (!strcasecmp(argv
[1], "nil")) {
357 platform_uuid_clear(&uu
);
358 } else if (!strcasecmp(argv
[1], "rewrite")) {
359 uup
= do_uuid(0, NULL
);
361 dbprintf(_("failed to read UUID from AG 0\n"));
364 memcpy(&uu
, uup
, sizeof(uuid_t
));
365 platform_uuid_unparse(&uu
, bp
);
366 dbprintf(_("old UUID = %s\n"), bp
);
368 if (platform_uuid_parse(argv
[1], &uu
)) {
369 dbprintf(_("invalid UUID\n"));
374 /* clear the log (setting uuid) if it's not dirty */
375 if (!sb_logzero(&uu
))
378 dbprintf(_("writing all SBs\n"));
379 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++)
380 if (!do_uuid(agno
, &uu
)) {
381 dbprintf(_("failed to set UUID in AG %d\n"), agno
);
385 platform_uuid_unparse(&uu
, bp
);
386 dbprintf(_("new UUID = %s\n"), bp
);
389 } else { /* READ+CHECK UUID */
391 for (agno
= 0; agno
< mp
->m_sb
.sb_agcount
; agno
++) {
392 uup
= do_uuid(agno
, NULL
);
394 dbprintf(_("failed to read UUID from AG %d\n"),
399 if (memcmp(&uu
, uup
, sizeof(uuid_t
))) {
400 dbprintf(_("warning: UUID in AG %d "
401 "differs to the primary SB\n"),
406 memcpy(&uu
, uup
, sizeof(uuid_t
));
409 if (mp
->m_sb
.sb_logstart
) {
410 if (x
.logdev
&& x
.logdev
!= x
.ddev
)
411 dbprintf(_("warning - external log specified "
412 "for FS with an internal log\n"));
413 } else if (!x
.logdev
|| (x
.logdev
== x
.ddev
)) {
414 dbprintf(_("warning - no external log specified "
415 "for FS with an external log\n"));
418 platform_uuid_unparse(&uu
, bp
);
419 dbprintf(_("UUID = %s\n"), bp
);
431 " write/print FS label\n"
435 " 'label' - print label\n"
436 " 'label 123456789012' - write label\n"
437 " 'label --' - write an empty label\n"
439 "The print function checks the label in each SB and will warn if the labels\n"
440 "differ between AGs. The write commands will set the label in all AGs to the\n"
441 "specified value. The maximum length of a label is 12 characters - use of a\n"
442 "longer label will result in truncation and a warning will be issued.\n"
448 do_label(xfs_agnumber_t agno
, char *label
)
452 static char lbl
[sizeof(tsb
.sb_fname
) + 1];
454 if (!get_sb(agno
, &tsb
))
457 memset(&lbl
[0], 0, sizeof(lbl
));
459 if (!label
) { /* get label */
461 memcpy(&lbl
[0], &tsb
.sb_fname
, sizeof(tsb
.sb_fname
));
465 if ((len
= strlen(label
)) > sizeof(tsb
.sb_fname
)) {
467 dbprintf(_("%s: truncating label length from %d to %d\n"),
468 progname
, (int)len
, (int)sizeof(tsb
.sb_fname
));
469 len
= sizeof(tsb
.sb_fname
);
472 (strcmp(label
, "\"\"") == 0 ||
473 strcmp(label
, "''") == 0 ||
474 strcmp(label
, "--") == 0) )
475 label
[0] = label
[1] = '\0';
476 memset(&tsb
.sb_fname
, 0, sizeof(tsb
.sb_fname
));
477 memcpy(&tsb
.sb_fname
, label
, len
);
478 memcpy(&lbl
[0], &tsb
.sb_fname
, sizeof(tsb
.sb_fname
));
479 libxfs_sb_to_disk(iocur_top
->data
, &tsb
, XFS_SB_FNAME
);
493 if (argc
!= 1 && argc
!= 2) {
494 dbprintf(_("invalid parameters\n"));
498 if (argc
== 2) { /* WRITE LABEL */
500 if ((x
.isreadonly
& LIBXFS_ISREADONLY
) || !expert_mode
) {
501 dbprintf(_("%s: not in expert mode, writing disabled\n"),
506 dbprintf(_("writing all SBs\n"));
507 for (ag
= 0; ag
< mp
->m_sb
.sb_agcount
; ag
++)
508 if ((p
= do_label(ag
, argv
[1])) == NULL
) {
509 dbprintf(_("failed to set label in AG %d\n"), ag
);
512 dbprintf(_("new label = \"%s\"\n"), p
);
514 } else { /* READ LABEL */
516 for (ag
= 0; ag
< mp
->m_sb
.sb_agcount
; ag
++) {
517 p
= do_label(ag
, NULL
);
519 dbprintf(_("failed to read label in AG %d\n"), ag
);
523 memcpy(&sb
.sb_fname
, p
, sizeof(sb
.sb_fname
));
524 else if (memcmp(&sb
.sb_fname
, p
, sizeof(sb
.sb_fname
)))
525 dbprintf(_("warning: AG %d label differs\n"), ag
);
527 dbprintf(_("label = \"%s\"\n"), p
);
538 " set/print feature bits in sb version\n"
542 " 'version' - print current feature bits\n"
543 " 'version extflg' - enable unwritten extents\n"
544 " 'version attr1' - enable v1 inline extended attributes\n"
545 " 'version attr2' - enable v2 inline extended attributes\n"
546 " 'version log2' - enable v2 log format\n"
548 "The version function prints currently enabled features for a filesystem\n"
549 "according to the version field of its primary superblock.\n"
550 "It can also be used to enable selected features, such as support for\n"
551 "unwritten extents. The updated version is written into all AGs.\n"
557 do_version(xfs_agnumber_t agno
, __uint16_t version
, __uint32_t features
)
560 __int64_t fields
= 0;
562 if (!get_sb(agno
, &tsb
))
565 if (xfs_sb_has_mismatched_features2(&tsb
)) {
566 dbprintf(_("Superblock has mismatched features2 fields, "
567 "skipping modification\n"));
571 if ((version
& XFS_SB_VERSION_LOGV2BIT
) &&
572 !xfs_sb_version_haslogv2(&tsb
)) {
574 fields
|= (1LL << XFS_SBS_LOGSUNIT
);
577 tsb
.sb_versionnum
= version
;
578 tsb
.sb_features2
= features
;
579 tsb
.sb_bad_features2
= features
;
580 fields
|= XFS_SB_VERSIONNUM
| XFS_SB_FEATURES2
| XFS_SB_BAD_FEATURES2
;
581 libxfs_sb_to_disk(iocur_top
->data
, &tsb
, fields
);
592 if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_1
)
594 else if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_2
)
596 else if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_3
)
598 else if (XFS_SB_VERSION_NUM(sbp
) == XFS_SB_VERSION_4
)
601 if (xfs_sb_version_hasattr(sbp
))
603 if (xfs_sb_version_hasnlink(sbp
))
605 if (xfs_sb_version_hasquota(sbp
))
607 if (xfs_sb_version_hasalign(sbp
))
609 if (xfs_sb_version_hasdalign(sbp
))
610 strcat(s
, ",DALIGN");
611 if (xfs_sb_version_hasshared(sbp
))
612 strcat(s
, ",SHARED");
613 if (xfs_sb_version_hasdirv2(sbp
))
615 if (xfs_sb_version_haslogv2(sbp
))
617 if (xfs_sb_version_hasextflgbit(sbp
))
618 strcat(s
, ",EXTFLG");
619 if (xfs_sb_version_hassector(sbp
))
620 strcat(s
, ",SECTOR");
621 if (xfs_sb_version_hasasciici(sbp
))
622 strcat(s
, ",ASCII_CI");
623 if (xfs_sb_version_hasmorebits(sbp
))
624 strcat(s
, ",MOREBITS");
625 if (xfs_sb_version_hasattr2(sbp
))
627 if (xfs_sb_version_haslazysbcount(sbp
))
628 strcat(s
, ",LAZYSBCOUNT");
629 if (xfs_sb_version_hasprojid32bit(sbp
))
630 strcat(s
, ",PROJID32BIT");
639 __uint16_t version
= 0;
640 __uint32_t features
= 0;
643 if (argc
== 2) { /* WRITE VERSION */
645 if ((x
.isreadonly
& LIBXFS_ISREADONLY
) || !expert_mode
) {
646 dbprintf(_("%s: not in expert mode, writing disabled\n"),
651 /* Logic here derived from the IRIX xfs_chver(1M) script. */
652 if (!strcasecmp(argv
[1], "extflg")) {
653 switch (XFS_SB_VERSION_NUM(&mp
->m_sb
)) {
654 case XFS_SB_VERSION_1
:
655 version
= 0x0004 | XFS_SB_VERSION_EXTFLGBIT
;
657 case XFS_SB_VERSION_2
:
658 version
= 0x0014 | XFS_SB_VERSION_EXTFLGBIT
;
660 case XFS_SB_VERSION_3
:
661 version
= 0x0034 | XFS_SB_VERSION_EXTFLGBIT
;
663 case XFS_SB_VERSION_4
:
664 if (xfs_sb_version_hasextflgbit(&mp
->m_sb
))
665 dbprintf(_("unwritten extents flag"
666 " is already enabled\n"));
668 version
= mp
->m_sb
.sb_versionnum
|
669 XFS_SB_VERSION_EXTFLGBIT
;
672 } else if (!strcasecmp(argv
[1], "log2")) {
673 switch (XFS_SB_VERSION_NUM(&mp
->m_sb
)) {
674 case XFS_SB_VERSION_1
:
675 version
= 0x0004 | XFS_SB_VERSION_LOGV2BIT
;
677 case XFS_SB_VERSION_2
:
678 version
= 0x0014 | XFS_SB_VERSION_LOGV2BIT
;
680 case XFS_SB_VERSION_3
:
681 version
= 0x0034 | XFS_SB_VERSION_LOGV2BIT
;
683 case XFS_SB_VERSION_4
:
684 if (xfs_sb_version_haslogv2(&mp
->m_sb
))
685 dbprintf(_("version 2 log format"
686 " is already in use\n"));
688 version
= mp
->m_sb
.sb_versionnum
|
689 XFS_SB_VERSION_LOGV2BIT
;
692 } else if (!strcasecmp(argv
[1], "attr1")) {
693 if (xfs_sb_version_hasattr2(&mp
->m_sb
)) {
694 if (!(mp
->m_sb
.sb_features2
&=
695 ~XFS_SB_VERSION2_ATTR2BIT
))
696 mp
->m_sb
.sb_versionnum
&=
697 ~XFS_SB_VERSION_MOREBITSBIT
;
699 xfs_sb_version_addattr(&mp
->m_sb
);
700 version
= mp
->m_sb
.sb_versionnum
;
701 features
= mp
->m_sb
.sb_features2
;
702 } else if (!strcasecmp(argv
[1], "attr2")) {
703 xfs_sb_version_addattr(&mp
->m_sb
);
704 xfs_sb_version_addattr2(&mp
->m_sb
);
705 version
= mp
->m_sb
.sb_versionnum
;
706 features
= mp
->m_sb
.sb_features2
;
707 } else if (!strcasecmp(argv
[1], "projid32bit")) {
708 xfs_sb_version_addprojid32bit(&mp
->m_sb
);
709 version
= mp
->m_sb
.sb_versionnum
;
710 features
= mp
->m_sb
.sb_features2
;
712 dbprintf(_("%s: invalid version change command \"%s\"\n"),
718 dbprintf(_("writing all SBs\n"));
719 for (ag
= 0; ag
< mp
->m_sb
.sb_agcount
; ag
++)
720 if (!do_version(ag
, version
, features
)) {
721 dbprintf(_("failed to set versionnum "
725 mp
->m_sb
.sb_versionnum
= version
;
726 mp
->m_sb
.sb_features2
= features
;
730 if (argc
== 3) { /* VERSIONNUM + FEATURES2 */
733 version
= mp
->m_sb
.sb_versionnum
;
734 features
= mp
->m_sb
.sb_features2
;
735 mp
->m_sb
.sb_versionnum
= strtoul(argv
[1], &sp
, 0);
736 mp
->m_sb
.sb_features2
= strtoul(argv
[2], &sp
, 0);
739 dbprintf(_("versionnum [0x%x+0x%x] = %s\n"), mp
->m_sb
.sb_versionnum
,
740 mp
->m_sb
.sb_features2
, version_string(&mp
->m_sb
));
742 if (argc
== 3) { /* now reset... */
743 mp
->m_sb
.sb_versionnum
= version
;
744 mp
->m_sb
.sb_features2
= features
;