aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_mount.c24
-rw-r--r--fs/xfs/xfs_sb.c3
2 files changed, 17 insertions, 10 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 02df7b408a26..f96c05669a9e 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -282,22 +282,29 @@ xfs_readsb(
282 struct xfs_sb *sbp = &mp->m_sb; 282 struct xfs_sb *sbp = &mp->m_sb;
283 int error; 283 int error;
284 int loud = !(flags & XFS_MFSI_QUIET); 284 int loud = !(flags & XFS_MFSI_QUIET);
285 const struct xfs_buf_ops *buf_ops;
285 286
286 ASSERT(mp->m_sb_bp == NULL); 287 ASSERT(mp->m_sb_bp == NULL);
287 ASSERT(mp->m_ddev_targp != NULL); 288 ASSERT(mp->m_ddev_targp != NULL);
288 289
289 /* 290 /*
291 * For the initial read, we must guess at the sector
292 * size based on the block device. It's enough to
293 * get the sb_sectsize out of the superblock and
294 * then reread with the proper length.
295 * We don't verify it yet, because it may not be complete.
296 */
297 sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);
298 buf_ops = NULL;
299
300 /*
290 * Allocate a (locked) buffer to hold the superblock. 301 * Allocate a (locked) buffer to hold the superblock.
291 * This will be kept around at all times to optimize 302 * This will be kept around at all times to optimize
292 * access to the superblock. 303 * access to the superblock.
293 */ 304 */
294 sector_size = xfs_getsize_buftarg(mp->m_ddev_targp);
295
296reread: 305reread:
297 bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, 306 bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR,
298 BTOBB(sector_size), 0, 307 BTOBB(sector_size), 0, buf_ops);
299 loud ? &xfs_sb_buf_ops
300 : &xfs_sb_quiet_buf_ops);
301 if (!bp) { 308 if (!bp) {
302 if (loud) 309 if (loud)
303 xfs_warn(mp, "SB buffer read failed"); 310 xfs_warn(mp, "SB buffer read failed");
@@ -328,12 +335,13 @@ reread:
328 } 335 }
329 336
330 /* 337 /*
331 * If device sector size is smaller than the superblock size, 338 * Re-read the superblock so the buffer is correctly sized,
332 * re-read the superblock so the buffer is correctly sized. 339 * and properly verified.
333 */ 340 */
334 if (sector_size < sbp->sb_sectsize) { 341 if (buf_ops == NULL) {
335 xfs_buf_relse(bp); 342 xfs_buf_relse(bp);
336 sector_size = sbp->sb_sectsize; 343 sector_size = sbp->sb_sectsize;
344 buf_ops = loud ? &xfs_sb_buf_ops : &xfs_sb_quiet_buf_ops;
337 goto reread; 345 goto reread;
338 } 346 }
339 347
diff --git a/fs/xfs/xfs_sb.c b/fs/xfs/xfs_sb.c
index 5071ccb67f07..359b19a4df42 100644
--- a/fs/xfs/xfs_sb.c
+++ b/fs/xfs/xfs_sb.c
@@ -611,7 +611,7 @@ xfs_sb_read_verify(
611 XFS_SB_VERSION_5) || 611 XFS_SB_VERSION_5) ||
612 dsb->sb_crc != 0)) { 612 dsb->sb_crc != 0)) {
613 613
614 if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize), 614 if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
615 offsetof(struct xfs_sb, sb_crc))) { 615 offsetof(struct xfs_sb, sb_crc))) {
616 /* Only fail bad secondaries on a known V5 filesystem */ 616 /* Only fail bad secondaries on a known V5 filesystem */
617 if (bp->b_bn == XFS_SB_DADDR || 617 if (bp->b_bn == XFS_SB_DADDR ||
@@ -644,7 +644,6 @@ xfs_sb_quiet_read_verify(
644{ 644{
645 struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); 645 struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp);
646 646
647
648 if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) { 647 if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) {
649 /* XFS filesystem, verify noisily! */ 648 /* XFS filesystem, verify noisily! */
650 xfs_sb_read_verify(bp); 649 xfs_sb_read_verify(bp);