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 | |
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>
-rw-r--r-- | fs/xfs/xfs_fsops.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 134 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_sb.h | 68 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 72 |
6 files changed, 191 insertions, 94 deletions
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 432e82347ed6..3d27909770ea 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -136,7 +136,6 @@ xfs_growfs_data_private( | |||
136 | xfs_rfsblock_t nfree; | 136 | xfs_rfsblock_t nfree; |
137 | xfs_agnumber_t oagcount; | 137 | xfs_agnumber_t oagcount; |
138 | int pct; | 138 | int pct; |
139 | xfs_sb_t *sbp; | ||
140 | xfs_trans_t *tp; | 139 | xfs_trans_t *tp; |
141 | 140 | ||
142 | nb = in->newblocks; | 141 | nb = in->newblocks; |
@@ -377,8 +376,7 @@ xfs_growfs_data_private( | |||
377 | error, agno); | 376 | error, agno); |
378 | break; | 377 | break; |
379 | } | 378 | } |
380 | sbp = XFS_BUF_TO_SBP(bp); | 379 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); |
381 | xfs_xlatesb(sbp, &mp->m_sb, -1, XFS_SB_ALL_BITS); | ||
382 | /* | 380 | /* |
383 | * If we get an error writing out the alternate superblocks, | 381 | * If we get an error writing out the alternate superblocks, |
384 | * just issue a warning and continue. The real work is | 382 | * just issue a warning and continue. The real work is |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 758543443b66..eb341461feb9 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -3846,7 +3846,7 @@ xlog_do_recover( | |||
3846 | 3846 | ||
3847 | /* Convert superblock from on-disk format */ | 3847 | /* Convert superblock from on-disk format */ |
3848 | sbp = &log->l_mp->m_sb; | 3848 | sbp = &log->l_mp->m_sb; |
3849 | xfs_xlatesb(XFS_BUF_TO_SBP(bp), sbp, 1, XFS_SB_ALL_BITS); | 3849 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); |
3850 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); | 3850 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); |
3851 | ASSERT(XFS_SB_GOOD_VERSION(sbp)); | 3851 | ASSERT(XFS_SB_GOOD_VERSION(sbp)); |
3852 | xfs_buf_relse(bp); | 3852 | xfs_buf_relse(bp); |
@@ -4024,7 +4024,7 @@ xlog_recover_check_summary( | |||
4024 | sbbp = xfs_getsb(mp, 0); | 4024 | sbbp = xfs_getsb(mp, 0); |
4025 | #ifdef XFS_LOUD_RECOVERY | 4025 | #ifdef XFS_LOUD_RECOVERY |
4026 | sbp = &mp->m_sb; | 4026 | sbp = &mp->m_sb; |
4027 | xfs_xlatesb(XFS_BUF_TO_SBP(sbbp), sbp, 1, XFS_SB_ALL_BITS); | 4027 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(sbbp)); |
4028 | cmn_err(CE_NOTE, | 4028 | cmn_err(CE_NOTE, |
4029 | "xlog_recover_check_summary: sb_icount %Lu itotal %Lu", | 4029 | "xlog_recover_check_summary: sb_icount %Lu itotal %Lu", |
4030 | sbp->sb_icount, itotal); | 4030 | sbp->sb_icount, itotal); |
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 | ||
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 1a5d1d360d80..9ceff40326d0 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -630,7 +630,8 @@ extern int xfs_syncsub(xfs_mount_t *, int, int *); | |||
630 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); | 630 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); |
631 | extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, | 631 | extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, |
632 | xfs_agnumber_t); | 632 | xfs_agnumber_t); |
633 | extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); | 633 | extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); |
634 | extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); | ||
634 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); | 635 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); |
635 | 636 | ||
636 | extern struct xfs_dmops xfs_dmcore_stub; | 637 | extern struct xfs_dmops xfs_dmcore_stub; |
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index ef42537a607a..94660b1a6ccc 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h | |||
@@ -87,8 +87,10 @@ struct xfs_mount; | |||
87 | (XFS_SB_VERSION2_OKREALFBITS | \ | 87 | (XFS_SB_VERSION2_OKREALFBITS | \ |
88 | XFS_SB_VERSION2_OKSASHFBITS ) | 88 | XFS_SB_VERSION2_OKSASHFBITS ) |
89 | 89 | ||
90 | typedef struct xfs_sb | 90 | /* |
91 | { | 91 | * Superblock - in core version. Must match the ondisk version below. |
92 | */ | ||
93 | typedef struct xfs_sb { | ||
92 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ | 94 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ |
93 | __uint32_t sb_blocksize; /* logical block size, bytes */ | 95 | __uint32_t sb_blocksize; /* logical block size, bytes */ |
94 | xfs_drfsbno_t sb_dblocks; /* number of data blocks */ | 96 | xfs_drfsbno_t sb_dblocks; /* number of data blocks */ |
@@ -146,6 +148,66 @@ typedef struct xfs_sb | |||
146 | } xfs_sb_t; | 148 | } xfs_sb_t; |
147 | 149 | ||
148 | /* | 150 | /* |
151 | * Superblock - on disk version. Must match the in core version below. | ||
152 | */ | ||
153 | typedef struct xfs_dsb { | ||
154 | __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */ | ||
155 | __be32 sb_blocksize; /* logical block size, bytes */ | ||
156 | __be64 sb_dblocks; /* number of data blocks */ | ||
157 | __be64 sb_rblocks; /* number of realtime blocks */ | ||
158 | __be64 sb_rextents; /* number of realtime extents */ | ||
159 | uuid_t sb_uuid; /* file system unique id */ | ||
160 | __be64 sb_logstart; /* starting block of log if internal */ | ||
161 | __be64 sb_rootino; /* root inode number */ | ||
162 | __be64 sb_rbmino; /* bitmap inode for realtime extents */ | ||
163 | __be64 sb_rsumino; /* summary inode for rt bitmap */ | ||
164 | __be32 sb_rextsize; /* realtime extent size, blocks */ | ||
165 | __be32 sb_agblocks; /* size of an allocation group */ | ||
166 | __be32 sb_agcount; /* number of allocation groups */ | ||
167 | __be32 sb_rbmblocks; /* number of rt bitmap blocks */ | ||
168 | __be32 sb_logblocks; /* number of log blocks */ | ||
169 | __be16 sb_versionnum; /* header version == XFS_SB_VERSION */ | ||
170 | __be16 sb_sectsize; /* volume sector size, bytes */ | ||
171 | __be16 sb_inodesize; /* inode size, bytes */ | ||
172 | __be16 sb_inopblock; /* inodes per block */ | ||
173 | char sb_fname[12]; /* file system name */ | ||
174 | __u8 sb_blocklog; /* log2 of sb_blocksize */ | ||
175 | __u8 sb_sectlog; /* log2 of sb_sectsize */ | ||
176 | __u8 sb_inodelog; /* log2 of sb_inodesize */ | ||
177 | __u8 sb_inopblog; /* log2 of sb_inopblock */ | ||
178 | __u8 sb_agblklog; /* log2 of sb_agblocks (rounded up) */ | ||
179 | __u8 sb_rextslog; /* log2 of sb_rextents */ | ||
180 | __u8 sb_inprogress; /* mkfs is in progress, don't mount */ | ||
181 | __u8 sb_imax_pct; /* max % of fs for inode space */ | ||
182 | /* statistics */ | ||
183 | /* | ||
184 | * These fields must remain contiguous. If you really | ||
185 | * want to change their layout, make sure you fix the | ||
186 | * code in xfs_trans_apply_sb_deltas(). | ||
187 | */ | ||
188 | __be64 sb_icount; /* allocated inodes */ | ||
189 | __be64 sb_ifree; /* free inodes */ | ||
190 | __be64 sb_fdblocks; /* free data blocks */ | ||
191 | __be64 sb_frextents; /* free realtime extents */ | ||
192 | /* | ||
193 | * End contiguous fields. | ||
194 | */ | ||
195 | __be64 sb_uquotino; /* user quota inode */ | ||
196 | __be64 sb_gquotino; /* group quota inode */ | ||
197 | __be16 sb_qflags; /* quota flags */ | ||
198 | __u8 sb_flags; /* misc. flags */ | ||
199 | __u8 sb_shared_vn; /* shared version number */ | ||
200 | __be32 sb_inoalignmt; /* inode chunk alignment, fsblocks */ | ||
201 | __be32 sb_unit; /* stripe or raid unit */ | ||
202 | __be32 sb_width; /* stripe or raid width */ | ||
203 | __u8 sb_dirblklog; /* log2 of dir block size (fsbs) */ | ||
204 | __u8 sb_logsectlog; /* log2 of the log sector size */ | ||
205 | __be16 sb_logsectsize; /* sector size for the log, bytes */ | ||
206 | __be32 sb_logsunit; /* stripe unit size for the log */ | ||
207 | __be32 sb_features2; /* additional feature bits */ | ||
208 | } xfs_dsb_t; | ||
209 | |||
210 | /* | ||
149 | * Sequence number values for the fields. | 211 | * Sequence number values for the fields. |
150 | */ | 212 | */ |
151 | typedef enum { | 213 | typedef enum { |
@@ -446,7 +508,7 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) | |||
446 | 508 | ||
447 | #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ | 509 | #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ |
448 | #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) | 510 | #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) |
449 | #define XFS_BUF_TO_SBP(bp) ((xfs_sb_t *)XFS_BUF_PTR(bp)) | 511 | #define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp)) |
450 | 512 | ||
451 | #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) | 513 | #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) |
452 | #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ | 514 | #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 356d6627f581..668996aae36d 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -548,7 +548,7 @@ STATIC void | |||
548 | xfs_trans_apply_sb_deltas( | 548 | xfs_trans_apply_sb_deltas( |
549 | xfs_trans_t *tp) | 549 | xfs_trans_t *tp) |
550 | { | 550 | { |
551 | xfs_sb_t *sbp; | 551 | xfs_dsb_t *sbp; |
552 | xfs_buf_t *bp; | 552 | xfs_buf_t *bp; |
553 | int whole = 0; | 553 | int whole = 0; |
554 | 554 | ||
@@ -566,57 +566,51 @@ xfs_trans_apply_sb_deltas( | |||
566 | * Only update the superblock counters if we are logging them | 566 | * Only update the superblock counters if we are logging them |
567 | */ | 567 | */ |
568 | if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { | 568 | if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { |
569 | if (tp->t_icount_delta != 0) { | 569 | if (tp->t_icount_delta) |
570 | INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta); | 570 | be64_add(&sbp->sb_icount, tp->t_icount_delta); |
571 | } | 571 | if (tp->t_ifree_delta) |
572 | if (tp->t_ifree_delta != 0) { | 572 | be64_add(&sbp->sb_ifree, tp->t_ifree_delta); |
573 | INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta); | 573 | if (tp->t_fdblocks_delta) |
574 | } | 574 | be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta); |
575 | 575 | if (tp->t_res_fdblocks_delta) | |
576 | if (tp->t_fdblocks_delta != 0) { | 576 | be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta); |
577 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta); | ||
578 | } | ||
579 | if (tp->t_res_fdblocks_delta != 0) { | ||
580 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta); | ||
581 | } | ||
582 | } | 577 | } |
583 | 578 | ||
584 | if (tp->t_frextents_delta != 0) { | 579 | if (tp->t_frextents_delta) |
585 | INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_frextents_delta); | 580 | be64_add(&sbp->sb_frextents, tp->t_frextents_delta); |
586 | } | 581 | if (tp->t_res_frextents_delta) |
587 | if (tp->t_res_frextents_delta != 0) { | 582 | be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta); |
588 | INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_res_frextents_delta); | 583 | |
589 | } | 584 | if (tp->t_dblocks_delta) { |
590 | if (tp->t_dblocks_delta != 0) { | 585 | be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta); |
591 | INT_MOD(sbp->sb_dblocks, ARCH_CONVERT, tp->t_dblocks_delta); | ||
592 | whole = 1; | 586 | whole = 1; |
593 | } | 587 | } |
594 | if (tp->t_agcount_delta != 0) { | 588 | if (tp->t_agcount_delta) { |
595 | INT_MOD(sbp->sb_agcount, ARCH_CONVERT, tp->t_agcount_delta); | 589 | be32_add(&sbp->sb_agcount, tp->t_agcount_delta); |
596 | whole = 1; | 590 | whole = 1; |
597 | } | 591 | } |
598 | if (tp->t_imaxpct_delta != 0) { | 592 | if (tp->t_imaxpct_delta) { |
599 | INT_MOD(sbp->sb_imax_pct, ARCH_CONVERT, tp->t_imaxpct_delta); | 593 | sbp->sb_imax_pct += tp->t_imaxpct_delta; |
600 | whole = 1; | 594 | whole = 1; |
601 | } | 595 | } |
602 | if (tp->t_rextsize_delta != 0) { | 596 | if (tp->t_rextsize_delta) { |
603 | INT_MOD(sbp->sb_rextsize, ARCH_CONVERT, tp->t_rextsize_delta); | 597 | be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta); |
604 | whole = 1; | 598 | whole = 1; |
605 | } | 599 | } |
606 | if (tp->t_rbmblocks_delta != 0) { | 600 | if (tp->t_rbmblocks_delta) { |
607 | INT_MOD(sbp->sb_rbmblocks, ARCH_CONVERT, tp->t_rbmblocks_delta); | 601 | be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta); |
608 | whole = 1; | 602 | whole = 1; |
609 | } | 603 | } |
610 | if (tp->t_rblocks_delta != 0) { | 604 | if (tp->t_rblocks_delta) { |
611 | INT_MOD(sbp->sb_rblocks, ARCH_CONVERT, tp->t_rblocks_delta); | 605 | be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta); |
612 | whole = 1; | 606 | whole = 1; |
613 | } | 607 | } |
614 | if (tp->t_rextents_delta != 0) { | 608 | if (tp->t_rextents_delta) { |
615 | INT_MOD(sbp->sb_rextents, ARCH_CONVERT, tp->t_rextents_delta); | 609 | be64_add(&sbp->sb_rextents, tp->t_rextents_delta); |
616 | whole = 1; | 610 | whole = 1; |
617 | } | 611 | } |
618 | if (tp->t_rextslog_delta != 0) { | 612 | if (tp->t_rextslog_delta) { |
619 | INT_MOD(sbp->sb_rextslog, ARCH_CONVERT, tp->t_rextslog_delta); | 613 | sbp->sb_rextslog += tp->t_rextslog_delta; |
620 | whole = 1; | 614 | whole = 1; |
621 | } | 615 | } |
622 | 616 | ||
@@ -624,14 +618,14 @@ xfs_trans_apply_sb_deltas( | |||
624 | /* | 618 | /* |
625 | * Log the whole thing, the fields are noncontiguous. | 619 | * Log the whole thing, the fields are noncontiguous. |
626 | */ | 620 | */ |
627 | xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1); | 621 | xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1); |
628 | else | 622 | else |
629 | /* | 623 | /* |
630 | * Since all the modifiable fields are contiguous, we | 624 | * Since all the modifiable fields are contiguous, we |
631 | * can get away with this. | 625 | * can get away with this. |
632 | */ | 626 | */ |
633 | xfs_trans_log_buf(tp, bp, offsetof(xfs_sb_t, sb_icount), | 627 | xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount), |
634 | offsetof(xfs_sb_t, sb_frextents) + | 628 | offsetof(xfs_dsb_t, sb_frextents) + |
635 | sizeof(sbp->sb_frextents) - 1); | 629 | sizeof(sbp->sb_frextents) - 1); |
636 | 630 | ||
637 | XFS_MTOVFS(tp->t_mountp)->vfs_super->s_dirt = 1; | 631 | XFS_MTOVFS(tp->t_mountp)->vfs_super->s_dirt = 1; |