2 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
37 #include "err_protos.h"
39 #define BSIZE (1024 * 1024)
41 #define XFS_AG_BYTES(bblog) ((long long)BBSIZE << (bblog))
42 #define XFS_AG_MIN_BYTES ((XFS_AG_BYTES(15))) /* 16 MB */
45 * copy the fields of a superblock that are present in primary and
46 * secondaries -- preserve fields that are different in the primary.
49 copy_sb(xfs_sb_t
*source
, xfs_sb_t
*dest
)
56 __uint16_t versionnum
;
58 rootino
= dest
->sb_rootino
;
59 rbmino
= dest
->sb_rbmino
;
60 rsumino
= dest
->sb_rsumino
;
61 uquotino
= dest
->sb_uquotino
;
62 gquotino
= dest
->sb_gquotino
;
64 versionnum
= dest
->sb_versionnum
;
68 dest
->sb_rootino
= rootino
;
69 dest
->sb_rbmino
= rbmino
;
70 dest
->sb_rsumino
= rsumino
;
71 dest
->sb_uquotino
= uquotino
;
72 dest
->sb_gquotino
= gquotino
;
74 dest
->sb_versionnum
= versionnum
;
77 * copy over version bits that are stamped into all
78 * secondaries and cannot be changed at run time in
79 * the primary superblock
81 if (XFS_SB_VERSION_HASDALIGN(source
))
82 XFS_SB_VERSION_ADDDALIGN(dest
);
83 if (XFS_SB_VERSION_HASEXTFLGBIT(source
))
84 XFS_SB_VERSION_ADDEXTFLGBIT(dest
);
87 * these are all supposed to be zero or will get reset anyway
91 dest
->sb_fdblocks
= 0;
92 dest
->sb_frextents
= 0;
94 bzero(source
->sb_fname
, 12);
98 * find a secondary superblock, copy it into the sb buffer
101 find_secondary_sb(xfs_sb_t
*rsb
)
113 do_warn(_("\nattempting to find secondary superblock...\n"));
115 sb
= (xfs_sb_t
*) memalign(MEM_ALIGN
, BSIZE
);
118 _("error finding secondary superblock -- failed to memalign buffer\n"));
122 bzero(&bufsb
, sizeof(xfs_sb_t
));
128 * skip first sector since we know that's bad
130 for (done
= 0, off
= XFS_AG_MIN_BYTES
; !done
; off
+= bsize
) {
132 * read disk 1 MByte at a time.
134 if (lseek64(fs_fd
, off
, SEEK_SET
) != off
) {
138 if (!done
&& (bsize
= read(fs_fd
, sb
, BSIZE
)) == 0) {
145 * check the buffer 512 bytes at a time since
146 * we don't know how big the sectors really are.
148 for (i
= 0; !done
&& i
< bsize
; i
+= BBSIZE
) {
149 c_bufsb
= (char *) sb
+ i
;
150 libxfs_xlate_sb(c_bufsb
, &bufsb
, 1, XFS_SB_ALL_BITS
);
152 if (verify_sb(&bufsb
, 0) != XR_OK
)
155 do_warn(_("found candidate secondary superblock...\n"));
158 * found one. now verify it by looking
159 * for other secondaries.
161 bcopy(&bufsb
, rsb
, sizeof(xfs_sb_t
));
162 rsb
->sb_inprogress
= 0;
165 if (verify_set_primary_sb(rsb
, 0, &dirty
) == XR_OK
) {
167 _("verified secondary superblock...\n"));
172 _("unable to verify superblock, continuing...\n"));
182 * calculate what inode alignment field ought to be
183 * based on internal superblock info
186 calc_ino_align(xfs_sb_t
*sb
)
190 align
= XFS_INODE_BIG_CLUSTER_SIZE
>> sb
->sb_blocklog
;
196 * verify a superblock -- does not verify root inode #
197 * can only check that geometry info is internally
198 * consistent. because of growfs, that's no guarantee
199 * of correctness (e.g. geometry may have changed)
201 * fields verified or consistency checked:
209 * sb_blocksize (as a group)
212 * geometry info - sb_dblocks (as a group)
217 * inode info - sb_inodesize (x-checked with geo info)
233 * ALL real-time fields
234 * final 4 summary counters
238 verify_sb(xfs_sb_t
*sb
, int is_primary_sb
)
244 /* check magic number and version number */
246 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
)
247 return(XR_BAD_MAGIC
);
249 if (!XFS_SB_GOOD_VERSION(sb
))
250 return(XR_BAD_VERSION
);
252 /* does sb think mkfs really finished ? */
254 if (is_primary_sb
&& sb
->sb_inprogress
== 1)
255 return(XR_BAD_INPROGRESS
);
257 /* check to make sure blocksize is legal 2^N, 9 <= N <= 16 */
259 if (sb
->sb_blocksize
== 0)
260 return(XR_BAD_BLOCKSIZE
);
264 for (i
= 0; bsize
< sb
->sb_blocksize
&&
265 i
< sizeof(sb
->sb_blocksize
) * NBBY
; i
++)
268 if (i
< XFS_MIN_BLOCKSIZE_LOG
|| i
> XFS_MAX_BLOCKSIZE_LOG
)
269 return(XR_BAD_BLOCKSIZE
);
271 /* check sb blocksize field against sb blocklog field */
273 if (i
!= sb
->sb_blocklog
)
274 return(XR_BAD_BLOCKLOG
);
276 /* sanity check ag count, size fields against data size field */
278 if (sb
->sb_dblocks
== 0 ||
280 ((__uint64_t
)sb
->sb_agcount
* sb
->sb_agblocks
) ||
282 ((__uint64_t
)(sb
->sb_agcount
- 1) * sb
->sb_agblocks
283 + XFS_MIN_AG_BLOCKS
))
284 return(XR_BAD_FS_SIZE_DATA
);
286 if (sb
->sb_agblklog
!= (__uint8_t
)libxfs_log2_roundup(sb
->sb_agblocks
))
287 return(XR_BAD_FS_SIZE_DATA
);
289 if (sb
->sb_inodesize
< XFS_DINODE_MIN_SIZE
||
290 sb
->sb_inodesize
> XFS_DINODE_MAX_SIZE
||
291 sb
->sb_inopblock
!= howmany(sb
->sb_blocksize
,sb
->sb_inodesize
))
292 return(XR_BAD_INO_SIZE_DATA
);
294 /* check to make sure sectorsize is legal 2^N, 9 <= N <= 15 */
296 if (sb
->sb_sectsize
== 0)
297 return(XR_BAD_SECT_SIZE_DATA
);
301 for (i
= 0; bsize
< sb
->sb_sectsize
&&
302 i
< sizeof(sb
->sb_sectsize
) * NBBY
; i
++) {
306 if (i
< XFS_MIN_SECTORSIZE_LOG
|| i
> XFS_MAX_SECTORSIZE_LOG
)
307 return(XR_BAD_SECT_SIZE_DATA
);
309 /* check sb sectorsize field against sb sectlog field */
311 if (i
!= sb
->sb_sectlog
)
312 return(XR_BAD_SECT_SIZE_DATA
);
314 if (XFS_SB_VERSION_HASSECTOR(sb
)) {
316 /* check to make sure log sector is legal 2^N, 9 <= N <= 15 */
318 if (sb
->sb_logsectsize
== 0)
319 return(XR_BAD_SECT_SIZE_DATA
);
323 for (i
= 0; bsize
< sb
->sb_logsectsize
&&
324 i
< sizeof(sb
->sb_logsectsize
) * NBBY
; i
++) {
328 if (i
< XFS_MIN_SECTORSIZE_LOG
|| i
> XFS_MAX_SECTORSIZE_LOG
)
329 return(XR_BAD_SECT_SIZE_DATA
);
331 /* check sb log sectorsize field against sb log sectlog field */
333 if (i
!= sb
->sb_logsectlog
)
334 return(XR_BAD_SECT_SIZE_DATA
);
338 * real-time extent size is always set
340 if (sb
->sb_rextsize
* sb
->sb_blocksize
> XFS_MAX_RTEXTSIZE
)
341 return(XR_BAD_RT_GEO_DATA
);
343 if (sb
->sb_rextsize
* sb
->sb_blocksize
< XFS_MIN_RTEXTSIZE
)
344 return(XR_BAD_RT_GEO_DATA
);
346 if (sb
->sb_rblocks
== 0) {
347 if (sb
->sb_rextents
!= 0)
348 return(XR_BAD_RT_GEO_DATA
);
350 if (sb
->sb_rbmblocks
!= 0)
351 return(XR_BAD_RT_GEO_DATA
);
353 if (sb
->sb_rextslog
!= 0)
354 return(XR_BAD_RT_GEO_DATA
);
356 if (sb
->sb_frextents
!= 0)
357 return(XR_BAD_RT_GEO_DATA
);
360 * if we have a real-time partition, sanity-check geometry
362 if (sb
->sb_rblocks
/ sb
->sb_rextsize
!= sb
->sb_rextents
)
363 return(XR_BAD_RT_GEO_DATA
);
365 if (sb
->sb_rextslog
!=
366 libxfs_highbit32((unsigned int)sb
->sb_rextents
))
367 return(XR_BAD_RT_GEO_DATA
);
369 if (sb
->sb_rbmblocks
!= (xfs_extlen_t
) howmany(sb
->sb_rextents
,
370 NBBY
* sb
->sb_blocksize
))
371 return(XR_BAD_RT_GEO_DATA
);
375 * verify correctness of inode alignment if it's there
377 if (XFS_SB_VERSION_HASALIGN(sb
)) {
378 align
= calc_ino_align(sb
);
380 if (align
!= sb
->sb_inoalignmt
)
381 return(XR_BAD_INO_ALIGN
);
385 * verify max. % of inodes (sb_imax_pct)
387 if (sb
->sb_imax_pct
> 100)
388 return(XR_BAD_INO_MAX_PCT
);
391 * verify stripe alignment fields if present
393 if (XFS_SB_VERSION_HASDALIGN(sb
)) {
394 if ((!sb
->sb_unit
&& sb
->sb_width
) ||
395 (sb
->sb_unit
&& sb
->sb_agblocks
% sb
->sb_unit
))
396 return(XR_BAD_SB_UNIT
);
397 if ((sb
->sb_unit
&& !sb
->sb_width
) ||
398 (sb
->sb_width
&& sb
->sb_unit
&& sb
->sb_width
% sb
->sb_unit
))
399 return(XR_BAD_SB_WIDTH
);
403 * if shared bit is set, verify that the version number is sane
405 if (XFS_SB_VERSION_HASSHARED(sb
)) {
406 if (sb
->sb_shared_vn
> XFS_SB_MAX_SHARED_VN
)
411 * mkfs's that stamped a feature bit besides the ones in the
412 * mask below could leave garbage in the secondary superblock
413 * sectors. Anything stamping the shared fs bit or better into
414 * the secondaries is ok and should generate clean secondary
415 * superblock sectors.
417 * check primary and clean secondary superblocks more strictly
419 if (is_primary_sb
|| sb
->sb_versionnum
& XR_PART_SECSB_VNMASK
) {
421 * return errors if shared vn or alignment fields
422 * are set without their feature bits being set
424 if ((!pre_65_beta
&& (sb
->sb_versionnum
& XR_PART_SECSB_VNMASK
)) ||
425 (pre_65_beta
&& (sb
->sb_versionnum
& XR_ALPHA_SECSB_VNMASK
))) {
427 * shared version # and inode alignment fields
430 if (sb
->sb_shared_vn
&& !XFS_SB_VERSION_HASSHARED(sb
))
432 if (sb
->sb_inoalignmt
&& !XFS_SB_VERSION_HASALIGN(sb
))
433 return(XR_BAD_INO_ALIGN
);
436 (sb
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
)) ||
438 (sb
->sb_versionnum
& XFS_SB_VERSION_DALIGNBIT
))) {
440 * stripe alignment values should be valid
442 if (sb
->sb_unit
&& !XFS_SB_VERSION_HASDALIGN(sb
))
443 return(XR_BAD_SB_UNIT
);
444 if (sb
->sb_width
&& !XFS_SB_VERSION_HASDALIGN(sb
))
445 return(XR_BAD_SB_WIDTH
);
450 * checks involving later superblock fields get added here...
452 if (sb
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
) {
461 write_primary_sb(xfs_sb_t
*sbp
, int size
)
468 if ((buf
= calloc(size
, 1)) == NULL
) {
469 do_error(_("failed to malloc superblock buffer\n"));
473 if (lseek64(fs_fd
, 0LL, SEEK_SET
) != 0LL) {
475 do_error(_("couldn't seek to offset 0 in filesystem\n"));
478 libxfs_xlate_sb(buf
, sbp
, -1, XFS_SB_ALL_BITS
);
480 if (write(fs_fd
, buf
, size
) != size
) {
482 do_error(_("primary superblock write failed!\n"));
489 * get a possible superblock -- don't check for internal consistency
492 get_sb(xfs_sb_t
*sbp
, xfs_off_t off
, int size
, xfs_agnumber_t agno
)
497 if ((buf
= calloc(size
, 1)) == NULL
) {
499 _("error reading superblock %u -- failed to malloc buffer\n"),
504 /* try and read it first */
506 if (lseek64(fs_fd
, off
, SEEK_SET
) != off
) {
508 _("error reading superblock %u -- seek to offset %lld failed\n"),
513 if ((rval
= read(fs_fd
, buf
, size
)) != size
) {
516 _("superblock read failed, offset %lld, size %d, ag %u, rval %d\n"),
517 off
, size
, rval
, agno
);
518 do_error("%s\n", strerror(error
));
520 libxfs_xlate_sb(buf
, sbp
, 1, XFS_SB_ALL_BITS
);
523 return (verify_sb(sbp
, 0));
526 /* returns element on list with highest reference count */
529 get_best_geo(fs_geo_list_t
*list
)
532 fs_geo_list_t
*current
, *rval
= NULL
;
536 while (current
!= NULL
) {
537 if (current
->refs
> cnt
) {
541 current
= current
->next
;
547 /* adds geometry info to linked list. returns (sometimes new) head of list */
550 add_geo(fs_geo_list_t
*list
, fs_geometry_t
*geo_p
, int index
)
552 fs_geo_list_t
*current
= list
;
554 while (current
!= NULL
) {
555 if (memcmp(geo_p
, ¤t
->geo
, sizeof(fs_geometry_t
)) == 0) {
560 current
= current
->next
;
563 if ((current
= malloc(sizeof(fs_geo_list_t
))) == NULL
) {
564 do_error(_("couldn't malloc geometry structure\n"));
568 current
->geo
= *geo_p
;
570 current
->next
= list
;
571 current
->index
= index
;
577 free_geo(fs_geo_list_t
*list
)
580 fs_geo_list_t
*current
;
584 for (current
= list
; current
!= NULL
; current
= next
) {
585 next
= current
->next
;
591 get_sb_geometry(fs_geometry_t
*geo
, xfs_sb_t
*sbp
)
593 bzero(geo
, sizeof(fs_geometry_t
));
596 * blindly set fields that we know are always good
598 geo
->sb_blocksize
= sbp
->sb_blocksize
;
599 geo
->sb_dblocks
= sbp
->sb_dblocks
;
600 geo
->sb_rblocks
= sbp
->sb_rblocks
;
601 geo
->sb_rextents
= sbp
->sb_rextents
;
602 geo
->sb_logstart
= sbp
->sb_logstart
;
603 geo
->sb_rextsize
= sbp
->sb_rextsize
;
604 geo
->sb_agblocks
= sbp
->sb_agblocks
;
605 geo
->sb_agcount
= sbp
->sb_agcount
;
606 geo
->sb_rbmblocks
= sbp
->sb_rbmblocks
;
607 geo
->sb_logblocks
= sbp
->sb_logblocks
;
608 geo
->sb_sectsize
= sbp
->sb_sectsize
;
609 geo
->sb_inodesize
= sbp
->sb_inodesize
;
611 if (XFS_SB_VERSION_HASALIGN(sbp
))
612 geo
->sb_ialignbit
= 1;
614 if (XFS_SB_VERSION_HASSHARED(sbp
) ||
615 sbp
->sb_versionnum
& XR_PART_SECSB_VNMASK
)
616 geo
->sb_sharedbit
= 1;
618 if (XFS_SB_VERSION_HASDALIGN(sbp
))
619 geo
->sb_salignbit
= 1;
621 if (XFS_SB_VERSION_HASEXTFLGBIT(sbp
))
622 geo
->sb_extflgbit
= 1;
625 * protect against pre-6.5 mkfs-generated garbaged
626 * fields in the secondary superblocks. pay attention
627 * to those fields if and only if their corresponding
628 * feature bits are set in the feature bits of the
629 * version number or we can deduce from the version bits
630 * that are set that our field was properly initialized
631 * because a field after the field we care about was
632 * properly initialized as well.
636 * inode alignment field lives before the data alignment field
638 if ((!pre_65_beta
&& (sbp
->sb_versionnum
& XR_PART_SECSB_VNMASK
)) ||
639 (pre_65_beta
&& (sbp
->sb_versionnum
& XR_ALPHA_SECSB_VNMASK
)))
640 geo
->sb_inoalignmt
= sbp
->sb_inoalignmt
;
642 if ((!pre_65_beta
&& (sbp
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
)) ||
643 (pre_65_beta
&& XFS_SB_VERSION_HASDALIGN(sbp
))) {
644 geo
->sb_unit
= sbp
->sb_unit
;
645 geo
->sb_width
= sbp
->sb_width
;
649 * shared vn always set if either ino or data alignment is on
650 * since that field lives between the quota and inode alignment
653 if (sbp
->sb_versionnum
& XR_PART_SECSB_VNMASK
)
654 geo
->sb_shared_vn
= sbp
->sb_shared_vn
;
657 * superblock fields located after sb_widthfields get set
658 * into the geometry structure only if we can determine
659 * from the features enabled in this superblock whether
660 * or not the sector was bzero'd at mkfs time.
662 if ((!pre_65_beta
&& (sbp
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
)) ||
663 (pre_65_beta
&& (sbp
->sb_versionnum
& XR_ALPHA_SECSB_VNMASK
))) {
664 geo
->sb_fully_zeroed
= 1;
669 * the way to verify that a primary sb is consistent with the
670 * filesystem is find the secondaries given the info in the
671 * primary and compare the geometries in the secondaries against
672 * the geometry indicated by the primary.
674 * returns 1 if bad, 0 if ok
677 verify_set_primary_sb(xfs_sb_t
*rsb
,
685 fs_geo_list_t
*current
;
696 * select the number of secondaries to try for
698 num_sbs
= MIN(NUM_SBS
, rsb
->sb_agcount
);
699 skip
= howmany(num_sbs
, rsb
->sb_agcount
);
700 size
= NUM_AGH_SECTS
* rsb
->sb_sectsize
;
706 sb
= (xfs_sb_t
*) alloc_ag_buf(size
);
707 checked
= calloc(rsb
->sb_agcount
, sizeof(char));
709 do_error(_("calloc failed in verify_set_primary_sb\n"));
714 * put the primary sb geometry info onto the geometry list
716 checked
[sb_index
] = 1;
717 get_sb_geometry(&geo
, rsb
);
718 list
= add_geo(list
, &geo
, sb_index
);
721 * grab N secondaries. check them off as we get them
722 * so we only process each one once
724 for (round
= 0; round
< skip
; round
++) {
725 for (agno
= round
; agno
< rsb
->sb_agcount
; agno
+= skip
) {
729 off
= (xfs_off_t
)agno
* rsb
->sb_agblocks
<< rsb
->sb_blocklog
;
733 if (get_sb(sb
, off
, size
, agno
) == XR_EOF
) {
738 if (verify_sb(sb
, 0) == XR_OK
) {
740 * save away geometry info.
741 * don't bother checking the sb
742 * against the agi/agf as the odds
743 * of the sb being corrupted in a way
744 * that it is internally consistent
745 * but not consistent with the rest
746 * of the filesystem is really really low.
748 get_sb_geometry(&geo
, sb
);
749 list
= add_geo(list
, &geo
, agno
);
756 * see if we have enough superblocks to bother with
758 if (num_ok
< num_sbs
/ 2)
759 return(XR_INSUFF_SEC_SB
);
761 current
= get_best_geo(list
);
764 * check that enough sbs agree that we're willing to
765 * go with this geometry. if not, print out the
766 * geometry and a message about the force option.
771 * all them have to be right. if not, report geometry
772 * and get out unless force option is in effect (-F)
774 if (current
->refs
!= 2) {
777 _("Only two AGs detected and they do not match - cannot proceed.\n"));
784 * just report the geometry info and get out.
785 * refuse to run further unless the force (-F)
786 * option is in effect.
789 do_warn(_("Only one AG detected - cannot proceed.\n"));
794 * at least half of the probed superblocks have
795 * to agree. if they don't, this fs is probably
796 * too far gone anyway considering the fact that
797 * XFS normally doesn't alter the secondary superblocks.
799 if (current
->refs
< num_sbs
/ 2) {
801 _("Not enough matching superblocks - cannot proceed.\n"));
807 * set the geometry into primary superblock if necessary.
810 if (current
->index
!= sb_index
) {
812 off
= current
->index
* current
->geo
.sb_agblocks
813 * current
->geo
.sb_blocksize
;
814 if (get_sb(sb
, off
, current
->geo
.sb_sectsize
,
815 current
->index
) != XR_OK
)
816 do_error(_("could not read superblock\n"));
821 * turn off inprogress bit since this is the primary.
822 * also save away values that we need to ensure are
823 * consistent in the other secondaries.
825 rsb
->sb_inprogress
= 0;
826 sb_inoalignmt
= sb
->sb_inoalignmt
;
827 sb_unit
= sb
->sb_unit
;
828 sb_width
= sb
->sb_width
;