2 * Copyright (c) 2000-2001 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/
38 #include "err_protos.h"
42 * copy the fields of a superblock that are present in primary and
43 * secondaries -- preserve fields that are different in the primary.
46 copy_sb(xfs_sb_t
*source
, xfs_sb_t
*dest
)
53 __uint16_t versionnum
;
55 rootino
= dest
->sb_rootino
;
56 rbmino
= dest
->sb_rbmino
;
57 rsumino
= dest
->sb_rsumino
;
58 uquotino
= dest
->sb_uquotino
;
59 gquotino
= dest
->sb_gquotino
;
61 versionnum
= dest
->sb_versionnum
;
65 dest
->sb_rootino
= rootino
;
66 dest
->sb_rbmino
= rbmino
;
67 dest
->sb_rsumino
= rsumino
;
68 dest
->sb_uquotino
= uquotino
;
69 dest
->sb_gquotino
= gquotino
;
71 dest
->sb_versionnum
= versionnum
;
74 * copy over version bits that are stamped into all
75 * secondaries and cannot be changed at run time in
76 * the primary superblock
78 if (XFS_SB_VERSION_HASDALIGN(source
))
79 XFS_SB_VERSION_ADDDALIGN(dest
);
80 if (XFS_SB_VERSION_HASEXTFLGBIT(source
))
81 XFS_SB_VERSION_ADDEXTFLGBIT(dest
);
84 * these are all supposed to be zero or will get reset anyway
88 dest
->sb_fdblocks
= 0;
89 dest
->sb_frextents
= 0;
91 bzero(source
->sb_fname
, 12);
94 #define BSIZE (1024 * 1024)
97 * find a secondary superblock, copy it into the sb buffer
100 find_secondary_sb(xfs_sb_t
*rsb
)
112 do_warn("\nattempting to find secondary superblock...\n");
114 sb
= (xfs_sb_t
*) memalign(MEM_ALIGN
, BSIZE
);
117 "error finding secondary superblock -- failed to memalign buffer\n");
121 bzero(&bufsb
, sizeof(xfs_sb_t
));
127 * skip first sector since we know that's bad
129 for (done
= 0, off
= XFS_AG_MIN_BYTES
; !done
; off
+= bsize
) {
131 * read disk 1 MByte at a time.
133 if (lseek64(fs_fd
, off
, SEEK_SET
) != off
) {
137 if (!done
&& (bsize
= read(fs_fd
, sb
, BSIZE
)) == 0) {
144 * check the buffer 512 bytes at a time since
145 * we don't know how big the sectors really are.
147 for (i
= 0; !done
&& i
< bsize
; i
+= BBSIZE
) {
148 c_bufsb
= (char *) sb
+ i
;
149 libxfs_xlate_sb(c_bufsb
, &bufsb
, 1, ARCH_CONVERT
,
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
, bufsb
.sb_sectsize
);
162 rsb
->sb_inprogress
= 0;
165 if (verify_set_primary_sb(rsb
, 0, &dirty
) == XR_OK
) {
166 do_warn("verified secondary superblock...\n");
171 "unable to verify superblock, continuing...\n");
181 * calculate what inode alignment field ought to be
182 * based on internal superblock info
185 calc_ino_align(xfs_sb_t
*sb
)
189 align
= XFS_INODE_BIG_CLUSTER_SIZE
>> sb
->sb_blocklog
;
195 * verify a superblock -- does not verify root inode #
196 * can only check that geometry info is internally
197 * consistent. because of growfs, that's no guarantee
198 * of correctness (e.g. geometry may have changed)
200 * fields verified or consistency checked:
208 * sb_blocksize (as a group)
211 * geometry info - sb_dblocks (as a group)
216 * inode info - sb_inodesize (x-checked with geo info)
230 * ALL real-time fields
231 * final 4 summary counters
235 verify_sb(xfs_sb_t
*sb
, int is_primary_sb
)
241 /* check magic number and version number */
243 if (sb
->sb_magicnum
!= XFS_SB_MAGIC
)
244 return(XR_BAD_MAGIC
);
246 if (!XFS_SB_GOOD_VERSION(sb
))
247 return(XR_BAD_VERSION
);
249 /* does sb think mkfs really finished ? */
251 if (is_primary_sb
&& sb
->sb_inprogress
== 1)
252 return(XR_BAD_INPROGRESS
);
254 /* check to make sure blocksize is legal 2^N, 9 <= N <= 16 */
256 if (sb
->sb_blocksize
== 0)
257 return(XR_BAD_BLOCKSIZE
);
261 for (i
= 0; bsize
< sb
->sb_blocksize
&& i
< 32; i
++) {
265 if (i
< XR_LOG2BSIZE_MIN
|| i
> XR_LOG2BSIZE_MAX
)
266 return(XR_BAD_BLOCKSIZE
);
268 /* check sb blocksize field against sb blocklog field */
270 if (i
!= sb
->sb_blocklog
)
271 return(XR_BAD_BLOCKLOG
);
273 /* sanity check ag count, size fields against data size field */
275 if (sb
->sb_dblocks
== 0 ||
276 sb
->sb_dblocks
> sb
->sb_agcount
* sb
->sb_agblocks
||
277 sb
->sb_dblocks
< (sb
->sb_agcount
- 1)
278 * sb
->sb_agblocks
+ XFS_MIN_AG_BLOCKS
)
279 return(XR_BAD_FS_SIZE_DATA
);
281 if (sb
->sb_agblklog
!= (__uint8_t
)libxfs_log2_roundup(sb
->sb_agblocks
))
282 return(XR_BAD_FS_SIZE_DATA
);
284 if (sb
->sb_inodesize
< XFS_DINODE_MIN_SIZE
||
285 sb
->sb_inodesize
> XFS_DINODE_MAX_SIZE
||
286 sb
->sb_inopblock
!= howmany(sb
->sb_blocksize
,sb
->sb_inodesize
))
287 return(XR_BAD_INO_SIZE_DATA
);
289 /* check sector size against log(sector size) field */
293 for (i
= 0; bsize
< sb
->sb_sectsize
&& i
< 15; i
++) {
297 if (sb
->sb_sectsize
== 0 || i
== 16 ||
298 sb
->sb_sectsize
!= (1 << i
))
299 return(XR_BAD_SECT_SIZE_DATA
);
302 * real-time extent size is always set
304 if (sb
->sb_rextsize
* sb
->sb_blocksize
> XFS_MAX_RTEXTSIZE
)
305 return(XR_BAD_RT_GEO_DATA
);
307 if (sb
->sb_rextsize
* sb
->sb_blocksize
< XFS_MIN_RTEXTSIZE
)
308 return(XR_BAD_RT_GEO_DATA
);
310 if (sb
->sb_rblocks
== 0) {
311 if (sb
->sb_rextents
!= 0)
312 return(XR_BAD_RT_GEO_DATA
);
314 if (sb
->sb_rbmblocks
!= 0)
315 return(XR_BAD_RT_GEO_DATA
);
317 if (sb
->sb_rextslog
!= 0)
318 return(XR_BAD_RT_GEO_DATA
);
320 if (sb
->sb_frextents
!= 0)
321 return(XR_BAD_RT_GEO_DATA
);
324 * if we have a real-time partition, sanity-check geometry
326 if (sb
->sb_rblocks
/ sb
->sb_rextsize
!= sb
->sb_rextents
)
327 return(XR_BAD_RT_GEO_DATA
);
329 if (sb
->sb_rextslog
!=
330 libxfs_highbit32((unsigned int)sb
->sb_rextents
))
331 return(XR_BAD_RT_GEO_DATA
);
333 if (sb
->sb_rbmblocks
!= (xfs_extlen_t
) howmany(sb
->sb_rextents
,
334 NBBY
* sb
->sb_blocksize
))
335 return(XR_BAD_RT_GEO_DATA
);
339 * verify correctness of inode alignment if it's there
341 if (XFS_SB_VERSION_HASALIGN(sb
)) {
342 align
= calc_ino_align(sb
);
344 if (align
!= sb
->sb_inoalignmt
)
345 return(XR_BAD_INO_ALIGN
);
349 * verify max. % of inodes (sb_imax_pct)
351 if (sb
->sb_imax_pct
> 100)
352 return(XR_BAD_INO_MAX_PCT
);
355 * verify stripe alignment fields if present
357 if (XFS_SB_VERSION_HASDALIGN(sb
)) {
358 if ((!sb
->sb_unit
&& sb
->sb_width
) ||
359 (sb
->sb_unit
&& sb
->sb_agblocks
% sb
->sb_unit
))
360 return(XR_BAD_SB_UNIT
);
361 if ((sb
->sb_unit
&& !sb
->sb_width
) ||
362 (sb
->sb_width
&& sb
->sb_unit
&& sb
->sb_width
% sb
->sb_unit
))
363 return(XR_BAD_SB_WIDTH
);
367 * if shared bit is set, verify that the version number is sane
369 if (XFS_SB_VERSION_HASSHARED(sb
)) {
370 if (sb
->sb_shared_vn
> XFS_SB_MAX_SHARED_VN
)
375 * mkfs's that stamped a feature bit besides the ones in the
376 * mask below could leave garbage in the secondary superblock
377 * sectors. Anything stamping the shared fs bit or better into
378 * the secondaries is ok and should generate clean secondary
379 * superblock sectors.
381 * check primary and clean secondary superblocks more strictly
383 if (is_primary_sb
|| sb
->sb_versionnum
& XR_PART_SECSB_VNMASK
) {
385 * return errors if shared vn or alignment fields
386 * are set without their feature bits being set
388 if ((!pre_65_beta
&& (sb
->sb_versionnum
& XR_PART_SECSB_VNMASK
)) ||
389 (pre_65_beta
&& (sb
->sb_versionnum
& XR_ALPHA_SECSB_VNMASK
))) {
391 * shared version # and inode alignment fields
394 if (sb
->sb_shared_vn
&& !XFS_SB_VERSION_HASSHARED(sb
))
396 if (sb
->sb_inoalignmt
&& !XFS_SB_VERSION_HASALIGN(sb
))
397 return(XR_BAD_INO_ALIGN
);
400 (sb
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
)) ||
402 (sb
->sb_versionnum
& XFS_SB_VERSION_DALIGNBIT
))) {
404 * stripe alignment values should be valid
406 if (sb
->sb_unit
&& !XFS_SB_VERSION_HASDALIGN(sb
))
407 return(XR_BAD_SB_UNIT
);
408 if (sb
->sb_width
&& !XFS_SB_VERSION_HASDALIGN(sb
))
409 return(XR_BAD_SB_WIDTH
);
414 * checks involving later superblock fields get added here...
416 if (sb
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
) {
425 write_primary_sb(xfs_sb_t
*sbp
, int size
)
432 if ((buf
= calloc(size
, 1)) == NULL
) {
433 do_error("failed to malloc superblock buffer\n");
437 if (lseek64(fs_fd
, 0LL, SEEK_SET
) != 0LL) {
439 do_error("couldn't seek to offset 0 in filesystem\n");
442 libxfs_xlate_sb(buf
, sbp
, -1, ARCH_CONVERT
, XFS_SB_ALL_BITS
);
444 if (write(fs_fd
, buf
, size
) != size
) {
446 do_error("primary superblock write failed!\n");
453 * get a possible superblock -- don't check for internal consistency
456 get_sb(xfs_sb_t
*sbp
, xfs_off_t off
, int size
, xfs_agnumber_t agno
)
461 if ((buf
= calloc(size
, 1)) == NULL
) {
463 "error reading superblock %u -- failed to malloc buffer\n",
468 /* try and read it first */
470 if (lseek64(fs_fd
, off
, SEEK_SET
) != off
) {
472 "error reading superblock %u -- seek to offset %lld failed\n",
477 if ((rval
= read(fs_fd
, buf
, size
)) != size
) {
480 "superblock read failed, offset %lld, size %d, ag %u, rval %d\n",
481 off
, size
, rval
, agno
);
482 do_error("%s\n", strerror(error
));
484 libxfs_xlate_sb(buf
, sbp
, 1, ARCH_CONVERT
, XFS_SB_ALL_BITS
);
487 return (verify_sb(sbp
, 0));
492 check_growfs(xfs_off_t off
, int bufnum
, xfs_agnumber_t agnum
)
496 ASSERT(bufnum
< NUM_SBS
);
498 /* try and read it first */
500 if (lseek64(fs_fd
, off
, SEEK_SET
) != off
)
503 if ((rval
= read(fs_fd
, sb_bufs
[bufnum
], sbbuf_size
)) != sbbuf_size
) {
505 * we didn't get a full block so the filesystem
506 * could not have been grown. return a non-XR_OK
512 return(get_sb(off
, bufnum
, agnum
));
515 /* returns element on list with highest reference count */
518 get_best_geo(fs_geo_list_t
*list
)
521 fs_geo_list_t
*current
, *rval
= NULL
;
525 while (current
!= NULL
) {
526 if (current
->refs
> cnt
) {
530 current
= current
->next
;
536 /* adds geometry info to linked list. returns (sometimes new) head of list */
539 add_geo(fs_geo_list_t
*list
, fs_geometry_t
*geo_p
, int index
)
541 fs_geo_list_t
*current
= list
;
543 while (current
!= NULL
) {
544 if (memcmp(geo_p
, ¤t
->geo
, sizeof(fs_geometry_t
)) == 0) {
549 current
= current
->next
;
552 if ((current
= malloc(sizeof(fs_geo_list_t
))) == NULL
) {
553 do_error("couldn't malloc geometry structure\n");
557 current
->geo
= *geo_p
;
559 current
->next
= list
;
560 current
->index
= index
;
566 free_geo(fs_geo_list_t
*list
)
569 fs_geo_list_t
*current
;
573 for (current
= list
; current
!= NULL
; current
= next
) {
574 next
= current
->next
;
580 get_sb_geometry(fs_geometry_t
*geo
, xfs_sb_t
*sbp
)
582 bzero(geo
, sizeof(fs_geometry_t
));
585 * blindly set fields that we know are always good
587 geo
->sb_blocksize
= sbp
->sb_blocksize
;
588 geo
->sb_dblocks
= sbp
->sb_dblocks
;
589 geo
->sb_rblocks
= sbp
->sb_rblocks
;
590 geo
->sb_rextents
= sbp
->sb_rextents
;
591 geo
->sb_logstart
= sbp
->sb_logstart
;
592 geo
->sb_rextsize
= sbp
->sb_rextsize
;
593 geo
->sb_agblocks
= sbp
->sb_agblocks
;
594 geo
->sb_agcount
= sbp
->sb_agcount
;
595 geo
->sb_rbmblocks
= sbp
->sb_rbmblocks
;
596 geo
->sb_logblocks
= sbp
->sb_logblocks
;
597 geo
->sb_sectsize
= sbp
->sb_sectsize
;
598 geo
->sb_inodesize
= sbp
->sb_inodesize
;
600 if (XFS_SB_VERSION_HASALIGN(sbp
))
601 geo
->sb_ialignbit
= 1;
603 if (XFS_SB_VERSION_HASSHARED(sbp
) ||
604 sbp
->sb_versionnum
& XR_PART_SECSB_VNMASK
)
605 geo
->sb_sharedbit
= 1;
607 if (XFS_SB_VERSION_HASDALIGN(sbp
))
608 geo
->sb_salignbit
= 1;
610 if (XFS_SB_VERSION_HASEXTFLGBIT(sbp
))
611 geo
->sb_extflgbit
= 1;
614 * protect against pre-6.5 mkfs-generated garbaged
615 * fields in the secondary superblocks. pay attention
616 * to those fields if and only if their corresponding
617 * feature bits are set in the feature bits of the
618 * version number or we can deduce from the version bits
619 * that are set that our field was properly initialized
620 * because a field after the field we care about was
621 * properly initialized as well.
625 * inode alignment field lives before the data alignment field
627 if ((!pre_65_beta
&& (sbp
->sb_versionnum
& XR_PART_SECSB_VNMASK
)) ||
628 (pre_65_beta
&& (sbp
->sb_versionnum
& XR_ALPHA_SECSB_VNMASK
)))
629 geo
->sb_inoalignmt
= sbp
->sb_inoalignmt
;
631 if ((!pre_65_beta
&& (sbp
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
)) ||
632 (pre_65_beta
&& XFS_SB_VERSION_HASDALIGN(sbp
))) {
633 geo
->sb_unit
= sbp
->sb_unit
;
634 geo
->sb_width
= sbp
->sb_width
;
638 * shared vn always set if either ino or data alignment is on
639 * since that field lives between the quota and inode alignment
642 if (sbp
->sb_versionnum
& XR_PART_SECSB_VNMASK
)
643 geo
->sb_shared_vn
= sbp
->sb_shared_vn
;
646 * superblock fields located after sb_widthfields get set
647 * into the geometry structure only if we can determine
648 * from the features enabled in this superblock whether
649 * or not the sector was bzero'd at mkfs time.
651 if ((!pre_65_beta
&& (sbp
->sb_versionnum
& XR_GOOD_SECSB_VNMASK
)) ||
652 (pre_65_beta
&& (sbp
->sb_versionnum
& XR_ALPHA_SECSB_VNMASK
))) {
653 geo
->sb_fully_zeroed
= 1;
658 * the way to verify that a primary sb is consistent with the
659 * filesystem is find the secondaries given the info in the
660 * primary and compare the geometries in the secondaries against
661 * the geometry indicated by the primary.
663 * returns 1 if bad, 0 if ok
666 verify_set_primary_sb(xfs_sb_t
*rsb
,
674 fs_geo_list_t
*current
;
685 * select the number of secondaries to try for
687 num_sbs
= MIN(NUM_SBS
, rsb
->sb_agcount
);
688 skip
= howmany(num_sbs
, rsb
->sb_agcount
);
689 size
= NUM_AGH_SECTS
* rsb
->sb_sectsize
;
695 sb
= (xfs_sb_t
*) alloc_ag_buf(size
);
696 checked
= calloc(rsb
->sb_agcount
, sizeof(char));
698 do_error("calloc failed in verify_set_primary_sb\n");
703 * put the primary sb geometry info onto the geometry list
705 checked
[sb_index
] = 1;
706 get_sb_geometry(&geo
, rsb
);
707 list
= add_geo(list
, &geo
, sb_index
);
710 * grab N secondaries. check them off as we get them
711 * so we only process each one once
713 for (round
= 0; round
< skip
; round
++) {
714 for (agno
= round
; agno
< rsb
->sb_agcount
; agno
+= skip
) {
718 off
= (xfs_off_t
)agno
* rsb
->sb_agblocks
<< rsb
->sb_blocklog
;
722 if (get_sb(sb
, off
, size
, agno
) == XR_EOF
) {
727 if (verify_sb(sb
, 0) == XR_OK
) {
729 * save away geometry info.
730 * don't bother checking the sb
731 * against the agi/agf as the odds
732 * of the sb being corrupted in a way
733 * that it is internally consistent
734 * but not consistent with the rest
735 * of the filesystem is really really low.
737 get_sb_geometry(&geo
, sb
);
738 list
= add_geo(list
, &geo
, agno
);
745 * see if we have enough superblocks to bother with
747 if (num_ok
< num_sbs
/ 2)
748 return(XR_INSUFF_SEC_SB
);
750 current
= get_best_geo(list
);
753 * check that enough sbs agree that we're willing to
754 * go with this geometry. if not, print out the
755 * geometry and a message about the force option.
760 * all them have to be right. if not, report geometry
761 * and get out unless force option is in effect (-F)
763 if (current
->refs
!= 2) {
765 do_warn("Only two AGs detected and they do not match - cannot proceed.\n");
772 * just report the geometry info and get out.
773 * refuse to run further unless the force (-F)
774 * option is in effect.
777 do_warn("Only one AG detected - cannot proceed.\n");
782 * at least half of the probed superblocks have
783 * to agree. if they don't, this fs is probably
784 * too far gone anyway considering the fact that
785 * XFS normally doesn't alter the secondary superblocks.
787 if (current
->refs
< num_sbs
/ 2) {
788 do_warn("Not enough matching superblocks - cannot proceed.\n");
794 * set the geometry into primary superblock if necessary.
797 if (current
->index
!= sb_index
) {
799 off
= current
->index
* current
->geo
.sb_agblocks
800 * current
->geo
.sb_blocksize
;
801 if (get_sb(sb
, off
, current
->geo
.sb_sectsize
,
802 current
->index
) != XR_OK
)
803 do_error("could not read superblock\n");
808 * turn off inprogress bit since this is the primary.
809 * also save away values that we need to ensure are
810 * consistent in the other secondaries.
812 rsb
->sb_inprogress
= 0;
813 sb_inoalignmt
= sb
->sb_inoalignmt
;
814 sb_unit
= sb
->sb_unit
;
815 sb_width
= sb
->sb_width
;