@@ -59,6 +59,32 @@ xchk_superblock_xref(
5959 /* scrub teardown will take care of sc->sa for us */
6060}
6161
62+ /*
63+ * Calculate the ondisk superblock size in bytes given the feature set of the
64+ * mounted filesystem (aka the primary sb). This is subtlely different from
65+ * the logic in xfs_repair, which computes the size of a secondary sb given the
66+ * featureset listed in the secondary sb.
67+ */
68+ STATIC size_t
69+ xchk_superblock_ondisk_size (
70+ struct xfs_mount * mp )
71+ {
72+ if (xfs_has_metadir (mp ))
73+ return offsetofend (struct xfs_dsb , sb_pad );
74+ if (xfs_has_metauuid (mp ))
75+ return offsetofend (struct xfs_dsb , sb_meta_uuid );
76+ if (xfs_has_crc (mp ))
77+ return offsetofend (struct xfs_dsb , sb_lsn );
78+ if (xfs_sb_version_hasmorebits (& mp -> m_sb ))
79+ return offsetofend (struct xfs_dsb , sb_bad_features2 );
80+ if (xfs_has_logv2 (mp ))
81+ return offsetofend (struct xfs_dsb , sb_logsunit );
82+ if (xfs_has_sector (mp ))
83+ return offsetofend (struct xfs_dsb , sb_logsectsize );
84+ /* only support dirv2 or more recent */
85+ return offsetofend (struct xfs_dsb , sb_dirblklog );
86+ }
87+
6288/*
6389 * Scrub the filesystem superblock.
6490 *
@@ -75,6 +101,7 @@ xchk_superblock(
75101 struct xfs_buf * bp ;
76102 struct xfs_dsb * sb ;
77103 struct xfs_perag * pag ;
104+ size_t sblen ;
78105 xfs_agnumber_t agno ;
79106 uint32_t v2_ok ;
80107 __be32 features_mask ;
@@ -145,8 +172,11 @@ xchk_superblock(
145172 xchk_block_set_preen (sc , bp );
146173
147174 if (xfs_has_metadir (sc -> mp )) {
148- if (sb -> sb_metadirino != cpu_to_be64 (mp -> m_sb .sb_metadirino ))
149- xchk_block_set_preen (sc , bp );
175+ if (sb -> sb_rbmino != cpu_to_be64 (0 ))
176+ xchk_block_set_corrupt (sc , bp );
177+
178+ if (sb -> sb_rsumino != cpu_to_be64 (0 ))
179+ xchk_block_set_corrupt (sc , bp );
150180 } else {
151181 if (sb -> sb_rbmino != cpu_to_be64 (mp -> m_sb .sb_rbmino ))
152182 xchk_block_set_preen (sc , bp );
@@ -229,7 +259,13 @@ xchk_superblock(
229259 * sb_icount, sb_ifree, sb_fdblocks, sb_frexents
230260 */
231261
232- if (!xfs_has_metadir (mp )) {
262+ if (xfs_has_metadir (mp )) {
263+ if (sb -> sb_uquotino != cpu_to_be64 (0 ))
264+ xchk_block_set_corrupt (sc , bp );
265+
266+ if (sb -> sb_gquotino != cpu_to_be64 (0 ))
267+ xchk_block_set_preen (sc , bp );
268+ } else {
233269 if (sb -> sb_uquotino != cpu_to_be64 (mp -> m_sb .sb_uquotino ))
234270 xchk_block_set_preen (sc , bp );
235271
@@ -281,15 +317,8 @@ xchk_superblock(
281317 if (!!(sb -> sb_features2 & cpu_to_be32 (~v2_ok )))
282318 xchk_block_set_corrupt (sc , bp );
283319
284- if (xfs_has_metadir (mp )) {
285- if (sb -> sb_rgblklog != mp -> m_sb .sb_rgblklog )
286- xchk_block_set_corrupt (sc , bp );
287- if (memchr_inv (sb -> sb_pad , 0 , sizeof (sb -> sb_pad )))
288- xchk_block_set_preen (sc , bp );
289- } else {
290- if (sb -> sb_features2 != sb -> sb_bad_features2 )
291- xchk_block_set_preen (sc , bp );
292- }
320+ if (sb -> sb_features2 != sb -> sb_bad_features2 )
321+ xchk_block_set_preen (sc , bp );
293322 }
294323
295324 /* Check sb_features2 flags that are set at mkfs time. */
@@ -351,7 +380,10 @@ xchk_superblock(
351380 if (sb -> sb_spino_align != cpu_to_be32 (mp -> m_sb .sb_spino_align ))
352381 xchk_block_set_corrupt (sc , bp );
353382
354- if (!xfs_has_metadir (mp )) {
383+ if (xfs_has_metadir (mp )) {
384+ if (sb -> sb_pquotino != cpu_to_be64 (0 ))
385+ xchk_block_set_corrupt (sc , bp );
386+ } else {
355387 if (sb -> sb_pquotino != cpu_to_be64 (mp -> m_sb .sb_pquotino ))
356388 xchk_block_set_preen (sc , bp );
357389 }
@@ -366,16 +398,25 @@ xchk_superblock(
366398 }
367399
368400 if (xfs_has_metadir (mp )) {
401+ if (sb -> sb_metadirino != cpu_to_be64 (mp -> m_sb .sb_metadirino ))
402+ xchk_block_set_preen (sc , bp );
403+
369404 if (sb -> sb_rgcount != cpu_to_be32 (mp -> m_sb .sb_rgcount ))
370405 xchk_block_set_corrupt (sc , bp );
371406
372407 if (sb -> sb_rgextents != cpu_to_be32 (mp -> m_sb .sb_rgextents ))
373408 xchk_block_set_corrupt (sc , bp );
409+
410+ if (sb -> sb_rgblklog != mp -> m_sb .sb_rgblklog )
411+ xchk_block_set_corrupt (sc , bp );
412+
413+ if (memchr_inv (sb -> sb_pad , 0 , sizeof (sb -> sb_pad )))
414+ xchk_block_set_corrupt (sc , bp );
374415 }
375416
376417 /* Everything else must be zero. */
377- if ( memchr_inv ( sb + 1 , 0 ,
378- BBTOB (bp -> b_length ) - sizeof ( struct xfs_dsb ) ))
418+ sblen = xchk_superblock_ondisk_size ( mp );
419+ if ( memchr_inv (( char * ) sb + sblen , 0 , BBTOB (bp -> b_length ) - sblen ))
379420 xchk_block_set_corrupt (sc , bp );
380421
381422 xchk_superblock_xref (sc , bp );
@@ -458,7 +499,7 @@ xchk_agf_xref_btreeblks(
458499{
459500 struct xfs_agf * agf = sc -> sa .agf_bp -> b_addr ;
460501 struct xfs_mount * mp = sc -> mp ;
461- xfs_agblock_t blocks ;
502+ xfs_filblks_t blocks ;
462503 xfs_agblock_t btreeblks ;
463504 int error ;
464505
@@ -507,7 +548,7 @@ xchk_agf_xref_refcblks(
507548 struct xfs_scrub * sc )
508549{
509550 struct xfs_agf * agf = sc -> sa .agf_bp -> b_addr ;
510- xfs_agblock_t blocks ;
551+ xfs_filblks_t blocks ;
511552 int error ;
512553
513554 if (!sc -> sa .refc_cur )
@@ -840,7 +881,7 @@ xchk_agi_xref_fiblocks(
840881 struct xfs_scrub * sc )
841882{
842883 struct xfs_agi * agi = sc -> sa .agi_bp -> b_addr ;
843- xfs_agblock_t blocks ;
884+ xfs_filblks_t blocks ;
844885 int error = 0 ;
845886
846887 if (!xfs_has_inobtcounts (sc -> mp ))
0 commit comments