diff options
author | Christoph Hellwig <hch@infradead.org> | 2007-08-27 23:58:06 -0400 |
---|---|---|
committer | Tim Shimmin <tes@chook.melbourne.sgi.com> | 2007-10-15 02:49:09 -0400 |
commit | 2bdf7cd0baa67608ada1517a281af359faf4c58c (patch) | |
tree | 645d283fd4938a9b21b4b9e2585224ed4eeb4adb /fs/xfs/xfs_mount.c | |
parent | 347d1c01956d567c18afef0cc253eb235cafacd8 (diff) |
[XFS] superblock endianess annotations
Creates a new xfs_dsb_t that is __be annotated and keeps xfs_sb_t for the
incore one. xfs_xlatesb is renamed to xfs_sb_to_disk and only handles the
incore -> disk conversion. A new helper xfs_sb_from_disk handles the other
direction and doesn't need the slightly hacky table-driven approach
because we only ever read the full sb from disk.
The handling of shared r/o filesystems has been buggy on little endian
system and fixing this required shuffling around of some code in that
area.
SGI-PV: 968563
SGI-Modid: xfs-linux-melb:xfs-kern:29477a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 134 |
1 files changed, 88 insertions, 46 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index eef27f21f9ab..f4daf1ec9931 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -407,37 +407,79 @@ xfs_initialize_perag( | |||
407 | return index; | 407 | return index; |
408 | } | 408 | } |
409 | 409 | ||
410 | void | ||
411 | xfs_sb_from_disk( | ||
412 | xfs_sb_t *to, | ||
413 | xfs_dsb_t *from) | ||
414 | { | ||
415 | to->sb_magicnum = be32_to_cpu(from->sb_magicnum); | ||
416 | to->sb_blocksize = be32_to_cpu(from->sb_blocksize); | ||
417 | to->sb_dblocks = be64_to_cpu(from->sb_dblocks); | ||
418 | to->sb_rblocks = be64_to_cpu(from->sb_rblocks); | ||
419 | to->sb_rextents = be64_to_cpu(from->sb_rextents); | ||
420 | memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); | ||
421 | to->sb_logstart = be64_to_cpu(from->sb_logstart); | ||
422 | to->sb_rootino = be64_to_cpu(from->sb_rootino); | ||
423 | to->sb_rbmino = be64_to_cpu(from->sb_rbmino); | ||
424 | to->sb_rsumino = be64_to_cpu(from->sb_rsumino); | ||
425 | to->sb_rextsize = be32_to_cpu(from->sb_rextsize); | ||
426 | to->sb_agblocks = be32_to_cpu(from->sb_agblocks); | ||
427 | to->sb_agcount = be32_to_cpu(from->sb_agcount); | ||
428 | to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); | ||
429 | to->sb_logblocks = be32_to_cpu(from->sb_logblocks); | ||
430 | to->sb_versionnum = be16_to_cpu(from->sb_versionnum); | ||
431 | to->sb_sectsize = be16_to_cpu(from->sb_sectsize); | ||
432 | to->sb_inodesize = be16_to_cpu(from->sb_inodesize); | ||
433 | to->sb_inopblock = be16_to_cpu(from->sb_inopblock); | ||
434 | memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); | ||
435 | to->sb_blocklog = from->sb_blocklog; | ||
436 | to->sb_sectlog = from->sb_sectlog; | ||
437 | to->sb_inodelog = from->sb_inodelog; | ||
438 | to->sb_inopblog = from->sb_inopblog; | ||
439 | to->sb_agblklog = from->sb_agblklog; | ||
440 | to->sb_rextslog = from->sb_rextslog; | ||
441 | to->sb_inprogress = from->sb_inprogress; | ||
442 | to->sb_imax_pct = from->sb_imax_pct; | ||
443 | to->sb_icount = be64_to_cpu(from->sb_icount); | ||
444 | to->sb_ifree = be64_to_cpu(from->sb_ifree); | ||
445 | to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); | ||
446 | to->sb_frextents = be64_to_cpu(from->sb_frextents); | ||
447 | to->sb_uquotino = be64_to_cpu(from->sb_uquotino); | ||
448 | to->sb_gquotino = be64_to_cpu(from->sb_gquotino); | ||
449 | to->sb_qflags = be16_to_cpu(from->sb_qflags); | ||
450 | to->sb_flags = from->sb_flags; | ||
451 | to->sb_shared_vn = from->sb_shared_vn; | ||
452 | to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt); | ||
453 | to->sb_unit = be32_to_cpu(from->sb_unit); | ||
454 | to->sb_width = be32_to_cpu(from->sb_width); | ||
455 | to->sb_dirblklog = from->sb_dirblklog; | ||
456 | to->sb_logsectlog = from->sb_logsectlog; | ||
457 | to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); | ||
458 | to->sb_logsunit = be32_to_cpu(from->sb_logsunit); | ||
459 | to->sb_features2 = be32_to_cpu(from->sb_features2); | ||
460 | } | ||
461 | |||
410 | /* | 462 | /* |
411 | * xfs_xlatesb | 463 | * Copy in core superblock to ondisk one. |
412 | * | 464 | * |
413 | * data - on disk version of sb | 465 | * The fields argument is mask of superblock fields to copy. |
414 | * sb - a superblock | ||
415 | * dir - conversion direction: <0 - convert sb to buf | ||
416 | * >0 - convert buf to sb | ||
417 | * fields - which fields to copy (bitmask) | ||
418 | */ | 466 | */ |
419 | void | 467 | void |
420 | xfs_xlatesb( | 468 | xfs_sb_to_disk( |
421 | void *data, | 469 | xfs_dsb_t *to, |
422 | xfs_sb_t *sb, | 470 | xfs_sb_t *from, |
423 | int dir, | ||
424 | __int64_t fields) | 471 | __int64_t fields) |
425 | { | 472 | { |
426 | xfs_caddr_t buf_ptr; | 473 | xfs_caddr_t to_ptr = (xfs_caddr_t)to; |
427 | xfs_caddr_t mem_ptr; | 474 | xfs_caddr_t from_ptr = (xfs_caddr_t)from; |
428 | xfs_sb_field_t f; | 475 | xfs_sb_field_t f; |
429 | int first; | 476 | int first; |
430 | int size; | 477 | int size; |
431 | 478 | ||
432 | ASSERT(dir); | ||
433 | ASSERT(fields); | 479 | ASSERT(fields); |
434 | |||
435 | if (!fields) | 480 | if (!fields) |
436 | return; | 481 | return; |
437 | 482 | ||
438 | buf_ptr = (xfs_caddr_t)data; | ||
439 | mem_ptr = (xfs_caddr_t)sb; | ||
440 | |||
441 | while (fields) { | 483 | while (fields) { |
442 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); | 484 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); |
443 | first = xfs_sb_info[f].offset; | 485 | first = xfs_sb_info[f].offset; |
@@ -446,26 +488,20 @@ xfs_xlatesb( | |||
446 | ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); | 488 | ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); |
447 | 489 | ||
448 | if (size == 1 || xfs_sb_info[f].type == 1) { | 490 | if (size == 1 || xfs_sb_info[f].type == 1) { |
449 | if (dir > 0) { | 491 | memcpy(to_ptr + first, from_ptr + first, size); |
450 | memcpy(mem_ptr + first, buf_ptr + first, size); | ||
451 | } else { | ||
452 | memcpy(buf_ptr + first, mem_ptr + first, size); | ||
453 | } | ||
454 | } else { | 492 | } else { |
455 | switch (size) { | 493 | switch (size) { |
456 | case 2: | 494 | case 2: |
457 | INT_XLATE(*(__uint16_t*)(buf_ptr+first), | 495 | *(__be16 *)(to_ptr + first) = |
458 | *(__uint16_t*)(mem_ptr+first), | 496 | cpu_to_be16(*(__u16 *)(from_ptr + first)); |
459 | dir, ARCH_CONVERT); | ||
460 | break; | 497 | break; |
461 | case 4: | 498 | case 4: |
462 | INT_XLATE(*(__uint32_t*)(buf_ptr+first), | 499 | *(__be32 *)(to_ptr + first) = |
463 | *(__uint32_t*)(mem_ptr+first), | 500 | cpu_to_be32(*(__u32 *)(from_ptr + first)); |
464 | dir, ARCH_CONVERT); | ||
465 | break; | 501 | break; |
466 | case 8: | 502 | case 8: |
467 | INT_XLATE(*(__uint64_t*)(buf_ptr+first), | 503 | *(__be64 *)(to_ptr + first) = |
468 | *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT); | 504 | cpu_to_be64(*(__u64 *)(from_ptr + first)); |
469 | break; | 505 | break; |
470 | default: | 506 | default: |
471 | ASSERT(0); | 507 | ASSERT(0); |
@@ -487,7 +523,6 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
487 | unsigned int sector_size; | 523 | unsigned int sector_size; |
488 | unsigned int extra_flags; | 524 | unsigned int extra_flags; |
489 | xfs_buf_t *bp; | 525 | xfs_buf_t *bp; |
490 | xfs_sb_t *sbp; | ||
491 | int error; | 526 | int error; |
492 | 527 | ||
493 | ASSERT(mp->m_sb_bp == NULL); | 528 | ASSERT(mp->m_sb_bp == NULL); |
@@ -515,8 +550,7 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
515 | * Initialize the mount structure from the superblock. | 550 | * Initialize the mount structure from the superblock. |
516 | * But first do some basic consistency checking. | 551 | * But first do some basic consistency checking. |
517 | */ | 552 | */ |
518 | sbp = XFS_BUF_TO_SBP(bp); | 553 | xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp)); |
519 | xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS); | ||
520 | 554 | ||
521 | error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags); | 555 | error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags); |
522 | if (error) { | 556 | if (error) { |
@@ -1335,11 +1369,28 @@ xfs_log_sbcount( | |||
1335 | return 0; | 1369 | return 0; |
1336 | } | 1370 | } |
1337 | 1371 | ||
1372 | STATIC void | ||
1373 | xfs_mark_shared_ro( | ||
1374 | xfs_mount_t *mp, | ||
1375 | xfs_buf_t *bp) | ||
1376 | { | ||
1377 | xfs_dsb_t *sb = XFS_BUF_TO_SBP(bp); | ||
1378 | __uint16_t version; | ||
1379 | |||
1380 | if (!(sb->sb_flags & XFS_SBF_READONLY)) | ||
1381 | sb->sb_flags |= XFS_SBF_READONLY; | ||
1382 | |||
1383 | version = be16_to_cpu(sb->sb_versionnum); | ||
1384 | if ((version & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4 || | ||
1385 | !(version & XFS_SB_VERSION_SHAREDBIT)) | ||
1386 | version |= XFS_SB_VERSION_SHAREDBIT; | ||
1387 | sb->sb_versionnum = cpu_to_be16(version); | ||
1388 | } | ||
1389 | |||
1338 | int | 1390 | int |
1339 | xfs_unmountfs_writesb(xfs_mount_t *mp) | 1391 | xfs_unmountfs_writesb(xfs_mount_t *mp) |
1340 | { | 1392 | { |
1341 | xfs_buf_t *sbp; | 1393 | xfs_buf_t *sbp; |
1342 | xfs_sb_t *sb; | ||
1343 | int error = 0; | 1394 | int error = 0; |
1344 | 1395 | ||
1345 | /* | 1396 | /* |
@@ -1350,19 +1401,12 @@ xfs_unmountfs_writesb(xfs_mount_t *mp) | |||
1350 | XFS_FORCED_SHUTDOWN(mp))) { | 1401 | XFS_FORCED_SHUTDOWN(mp))) { |
1351 | 1402 | ||
1352 | sbp = xfs_getsb(mp, 0); | 1403 | sbp = xfs_getsb(mp, 0); |
1353 | sb = XFS_BUF_TO_SBP(sbp); | ||
1354 | 1404 | ||
1355 | /* | 1405 | /* |
1356 | * mark shared-readonly if desired | 1406 | * mark shared-readonly if desired |
1357 | */ | 1407 | */ |
1358 | if (mp->m_mk_sharedro) { | 1408 | if (mp->m_mk_sharedro) |
1359 | if (!(sb->sb_flags & XFS_SBF_READONLY)) | 1409 | xfs_mark_shared_ro(mp, sbp); |
1360 | sb->sb_flags |= XFS_SBF_READONLY; | ||
1361 | if (!XFS_SB_VERSION_HASSHARED(sb)) | ||
1362 | XFS_SB_VERSION_ADDSHARED(sb); | ||
1363 | xfs_fs_cmn_err(CE_NOTE, mp, | ||
1364 | "Unmounting, marking shared read-only"); | ||
1365 | } | ||
1366 | 1410 | ||
1367 | XFS_BUF_UNDONE(sbp); | 1411 | XFS_BUF_UNDONE(sbp); |
1368 | XFS_BUF_UNREAD(sbp); | 1412 | XFS_BUF_UNREAD(sbp); |
@@ -1397,7 +1441,6 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1397 | int first; | 1441 | int first; |
1398 | int last; | 1442 | int last; |
1399 | xfs_mount_t *mp; | 1443 | xfs_mount_t *mp; |
1400 | xfs_sb_t *sbp; | ||
1401 | xfs_sb_field_t f; | 1444 | xfs_sb_field_t f; |
1402 | 1445 | ||
1403 | ASSERT(fields); | 1446 | ASSERT(fields); |
@@ -1405,13 +1448,12 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1405 | return; | 1448 | return; |
1406 | mp = tp->t_mountp; | 1449 | mp = tp->t_mountp; |
1407 | bp = xfs_trans_getsb(tp, mp, 0); | 1450 | bp = xfs_trans_getsb(tp, mp, 0); |
1408 | sbp = XFS_BUF_TO_SBP(bp); | ||
1409 | first = sizeof(xfs_sb_t); | 1451 | first = sizeof(xfs_sb_t); |
1410 | last = 0; | 1452 | last = 0; |
1411 | 1453 | ||
1412 | /* translate/copy */ | 1454 | /* translate/copy */ |
1413 | 1455 | ||
1414 | xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields); | 1456 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); |
1415 | 1457 | ||
1416 | /* find modified range */ | 1458 | /* find modified range */ |
1417 | 1459 | ||