aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2007-08-27 23:58:06 -0400
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-10-15 02:49:09 -0400
commit2bdf7cd0baa67608ada1517a281af359faf4c58c (patch)
tree645d283fd4938a9b21b4b9e2585224ed4eeb4adb /fs/xfs/xfs_mount.c
parent347d1c01956d567c18afef0cc253eb235cafacd8 (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.c134
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
410void
411xfs_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 */
419void 467void
420xfs_xlatesb( 468xfs_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
1372STATIC void
1373xfs_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
1338int 1390int
1339xfs_unmountfs_writesb(xfs_mount_t *mp) 1391xfs_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