@@ -360,66 +360,76 @@ xfs_readsb(
360
360
}
361
361
362
362
/*
363
- * Update alignment values based on mount options and sb values
363
+ * If we were provided with new sunit/swidth values as mount options, make sure
364
+ * that they pass basic alignment and superblock feature checks, and convert
365
+ * them into the same units (FSB) that everything else expects. This step
366
+ * /must/ be done before computing the inode geometry.
364
367
*/
365
368
STATIC int
366
- xfs_update_alignment (xfs_mount_t * mp )
369
+ xfs_validate_new_dalign (
370
+ struct xfs_mount * mp )
367
371
{
368
- xfs_sb_t * sbp = & (mp -> m_sb );
372
+ if (mp -> m_dalign == 0 )
373
+ return 0 ;
369
374
370
- if (mp -> m_dalign ) {
375
+ /*
376
+ * If stripe unit and stripe width are not multiples
377
+ * of the fs blocksize turn off alignment.
378
+ */
379
+ if ((BBTOB (mp -> m_dalign ) & mp -> m_blockmask ) ||
380
+ (BBTOB (mp -> m_swidth ) & mp -> m_blockmask )) {
381
+ xfs_warn (mp ,
382
+ "alignment check failed: sunit/swidth vs. blocksize(%d)" ,
383
+ mp -> m_sb .sb_blocksize );
384
+ return - EINVAL ;
385
+ } else {
371
386
/*
372
- * If stripe unit and stripe width are not multiples
373
- * of the fs blocksize turn off alignment.
387
+ * Convert the stripe unit and width to FSBs.
374
388
*/
375
- if (( BBTOB ( mp -> m_dalign ) & mp -> m_blockmask ) ||
376
- ( BBTOB ( mp -> m_swidth ) & mp -> m_blockmask )) {
389
+ mp -> m_dalign = XFS_BB_TO_FSBT ( mp , mp -> m_dalign );
390
+ if ( mp -> m_dalign && ( mp -> m_sb . sb_agblocks % mp -> m_dalign )) {
377
391
xfs_warn (mp ,
378
- "alignment check failed: sunit/swidth vs. blocksize (%d)" ,
379
- sbp -> sb_blocksize );
392
+ "alignment check failed: sunit/swidth vs. agsize (%d)" ,
393
+ mp -> m_sb . sb_agblocks );
380
394
return - EINVAL ;
381
- } else {
382
- /*
383
- * Convert the stripe unit and width to FSBs.
384
- */
385
- mp -> m_dalign = XFS_BB_TO_FSBT (mp , mp -> m_dalign );
386
- if (mp -> m_dalign && (sbp -> sb_agblocks % mp -> m_dalign )) {
387
- xfs_warn (mp ,
388
- "alignment check failed: sunit/swidth vs. agsize(%d)" ,
389
- sbp -> sb_agblocks );
390
- return - EINVAL ;
391
- } else if (mp -> m_dalign ) {
392
- mp -> m_swidth = XFS_BB_TO_FSBT (mp , mp -> m_swidth );
393
- } else {
394
- xfs_warn (mp ,
395
- "alignment check failed: sunit(%d) less than bsize(%d)" ,
396
- mp -> m_dalign , sbp -> sb_blocksize );
397
- return - EINVAL ;
398
- }
399
- }
400
-
401
- /*
402
- * Update superblock with new values
403
- * and log changes
404
- */
405
- if (xfs_sb_version_hasdalign (sbp )) {
406
- if (sbp -> sb_unit != mp -> m_dalign ) {
407
- sbp -> sb_unit = mp -> m_dalign ;
408
- mp -> m_update_sb = true;
409
- }
410
- if (sbp -> sb_width != mp -> m_swidth ) {
411
- sbp -> sb_width = mp -> m_swidth ;
412
- mp -> m_update_sb = true;
413
- }
395
+ } else if (mp -> m_dalign ) {
396
+ mp -> m_swidth = XFS_BB_TO_FSBT (mp , mp -> m_swidth );
414
397
} else {
415
398
xfs_warn (mp ,
416
- "cannot change alignment: superblock does not support data alignment" );
399
+ "alignment check failed: sunit(%d) less than bsize(%d)" ,
400
+ mp -> m_dalign , mp -> m_sb .sb_blocksize );
417
401
return - EINVAL ;
418
402
}
403
+ }
404
+
405
+ if (!xfs_sb_version_hasdalign (& mp -> m_sb )) {
406
+ xfs_warn (mp ,
407
+ "cannot change alignment: superblock does not support data alignment" );
408
+ return - EINVAL ;
409
+ }
410
+
411
+ return 0 ;
412
+ }
413
+
414
+ /* Update alignment values based on mount options and sb values. */
415
+ STATIC int
416
+ xfs_update_alignment (
417
+ struct xfs_mount * mp )
418
+ {
419
+ struct xfs_sb * sbp = & mp -> m_sb ;
420
+
421
+ if (mp -> m_dalign ) {
422
+ if (sbp -> sb_unit == mp -> m_dalign &&
423
+ sbp -> sb_width == mp -> m_swidth )
424
+ return 0 ;
425
+
426
+ sbp -> sb_unit = mp -> m_dalign ;
427
+ sbp -> sb_width = mp -> m_swidth ;
428
+ mp -> m_update_sb = true;
419
429
} else if ((mp -> m_flags & XFS_MOUNT_NOALIGN ) != XFS_MOUNT_NOALIGN &&
420
430
xfs_sb_version_hasdalign (& mp -> m_sb )) {
421
- mp -> m_dalign = sbp -> sb_unit ;
422
- mp -> m_swidth = sbp -> sb_width ;
431
+ mp -> m_dalign = sbp -> sb_unit ;
432
+ mp -> m_swidth = sbp -> sb_width ;
423
433
}
424
434
425
435
return 0 ;
@@ -648,12 +658,12 @@ xfs_mountfs(
648
658
}
649
659
650
660
/*
651
- * Check if sb_agblocks is aligned at stripe boundary
652
- * If sb_agblocks is NOT aligned turn off m_dalign since
653
- * allocator alignment is within an ag, therefore ag has
654
- * to be aligned at stripe boundary .
661
+ * If we were given new sunit/swidth options, do some basic validation
662
+ * checks and convert the incore dalign and swidth values to the
663
+ * same units (FSB) that everything else uses. This /must/ happen
664
+ * before computing the inode geometry .
655
665
*/
656
- error = xfs_update_alignment (mp );
666
+ error = xfs_validate_new_dalign (mp );
657
667
if (error )
658
668
goto out ;
659
669
@@ -664,6 +674,17 @@ xfs_mountfs(
664
674
xfs_rmapbt_compute_maxlevels (mp );
665
675
xfs_refcountbt_compute_maxlevels (mp );
666
676
677
+ /*
678
+ * Check if sb_agblocks is aligned at stripe boundary. If sb_agblocks
679
+ * is NOT aligned turn off m_dalign since allocator alignment is within
680
+ * an ag, therefore ag has to be aligned at stripe boundary. Note that
681
+ * we must compute the free space and rmap btree geometry before doing
682
+ * this.
683
+ */
684
+ error = xfs_update_alignment (mp );
685
+ if (error )
686
+ goto out ;
687
+
667
688
/* enable fail_at_unmount as default */
668
689
mp -> m_fail_unmount = true;
669
690
0 commit comments