aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_btree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_btree.c')
-rw-r--r--fs/xfs/libxfs/xfs_btree.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 21e6a6ab6b9a..c3decedc9455 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -50,8 +50,18 @@ static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = {
50 XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC, 50 XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC,
51 XFS_REFC_CRC_MAGIC } 51 XFS_REFC_CRC_MAGIC }
52}; 52};
53#define xfs_btree_magic(cur) \ 53
54 xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum] 54__uint32_t
55xfs_btree_magic(
56 int crc,
57 xfs_btnum_t btnum)
58{
59 __uint32_t magic = xfs_magics[crc][btnum];
60
61 /* Ensure we asked for crc for crc-only magics. */
62 ASSERT(magic != 0);
63 return magic;
64}
55 65
56STATIC int /* error (0 or EFSCORRUPTED) */ 66STATIC int /* error (0 or EFSCORRUPTED) */
57xfs_btree_check_lblock( 67xfs_btree_check_lblock(
@@ -62,10 +72,13 @@ xfs_btree_check_lblock(
62{ 72{
63 int lblock_ok = 1; /* block passes checks */ 73 int lblock_ok = 1; /* block passes checks */
64 struct xfs_mount *mp; /* file system mount point */ 74 struct xfs_mount *mp; /* file system mount point */
75 xfs_btnum_t btnum = cur->bc_btnum;
76 int crc;
65 77
66 mp = cur->bc_mp; 78 mp = cur->bc_mp;
79 crc = xfs_sb_version_hascrc(&mp->m_sb);
67 80
68 if (xfs_sb_version_hascrc(&mp->m_sb)) { 81 if (crc) {
69 lblock_ok = lblock_ok && 82 lblock_ok = lblock_ok &&
70 uuid_equal(&block->bb_u.l.bb_uuid, 83 uuid_equal(&block->bb_u.l.bb_uuid,
71 &mp->m_sb.sb_meta_uuid) && 84 &mp->m_sb.sb_meta_uuid) &&
@@ -74,7 +87,7 @@ xfs_btree_check_lblock(
74 } 87 }
75 88
76 lblock_ok = lblock_ok && 89 lblock_ok = lblock_ok &&
77 be32_to_cpu(block->bb_magic) == xfs_btree_magic(cur) && 90 be32_to_cpu(block->bb_magic) == xfs_btree_magic(crc, btnum) &&
78 be16_to_cpu(block->bb_level) == level && 91 be16_to_cpu(block->bb_level) == level &&
79 be16_to_cpu(block->bb_numrecs) <= 92 be16_to_cpu(block->bb_numrecs) <=
80 cur->bc_ops->get_maxrecs(cur, level) && 93 cur->bc_ops->get_maxrecs(cur, level) &&
@@ -110,13 +123,16 @@ xfs_btree_check_sblock(
110 struct xfs_agf *agf; /* ag. freespace structure */ 123 struct xfs_agf *agf; /* ag. freespace structure */
111 xfs_agblock_t agflen; /* native ag. freespace length */ 124 xfs_agblock_t agflen; /* native ag. freespace length */
112 int sblock_ok = 1; /* block passes checks */ 125 int sblock_ok = 1; /* block passes checks */
126 xfs_btnum_t btnum = cur->bc_btnum;
127 int crc;
113 128
114 mp = cur->bc_mp; 129 mp = cur->bc_mp;
130 crc = xfs_sb_version_hascrc(&mp->m_sb);
115 agbp = cur->bc_private.a.agbp; 131 agbp = cur->bc_private.a.agbp;
116 agf = XFS_BUF_TO_AGF(agbp); 132 agf = XFS_BUF_TO_AGF(agbp);
117 agflen = be32_to_cpu(agf->agf_length); 133 agflen = be32_to_cpu(agf->agf_length);
118 134
119 if (xfs_sb_version_hascrc(&mp->m_sb)) { 135 if (crc) {
120 sblock_ok = sblock_ok && 136 sblock_ok = sblock_ok &&
121 uuid_equal(&block->bb_u.s.bb_uuid, 137 uuid_equal(&block->bb_u.s.bb_uuid,
122 &mp->m_sb.sb_meta_uuid) && 138 &mp->m_sb.sb_meta_uuid) &&
@@ -125,7 +141,7 @@ xfs_btree_check_sblock(
125 } 141 }
126 142
127 sblock_ok = sblock_ok && 143 sblock_ok = sblock_ok &&
128 be32_to_cpu(block->bb_magic) == xfs_btree_magic(cur) && 144 be32_to_cpu(block->bb_magic) == xfs_btree_magic(crc, btnum) &&
129 be16_to_cpu(block->bb_level) == level && 145 be16_to_cpu(block->bb_level) == level &&
130 be16_to_cpu(block->bb_numrecs) <= 146 be16_to_cpu(block->bb_numrecs) <=
131 cur->bc_ops->get_maxrecs(cur, level) && 147 cur->bc_ops->get_maxrecs(cur, level) &&
@@ -810,7 +826,8 @@ xfs_btree_read_bufl(
810 xfs_daddr_t d; /* real disk block address */ 826 xfs_daddr_t d; /* real disk block address */
811 int error; 827 int error;
812 828
813 ASSERT(fsbno != NULLFSBLOCK); 829 if (!XFS_FSB_SANITY_CHECK(mp, fsbno))
830 return -EFSCORRUPTED;
814 d = XFS_FSB_TO_DADDR(mp, fsbno); 831 d = XFS_FSB_TO_DADDR(mp, fsbno);
815 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 832 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
816 mp->m_bsize, lock, &bp, ops); 833 mp->m_bsize, lock, &bp, ops);
@@ -1084,12 +1101,15 @@ xfs_btree_init_block_int(
1084 struct xfs_mount *mp, 1101 struct xfs_mount *mp,
1085 struct xfs_btree_block *buf, 1102 struct xfs_btree_block *buf,
1086 xfs_daddr_t blkno, 1103 xfs_daddr_t blkno,
1087 __u32 magic, 1104 xfs_btnum_t btnum,
1088 __u16 level, 1105 __u16 level,
1089 __u16 numrecs, 1106 __u16 numrecs,
1090 __u64 owner, 1107 __u64 owner,
1091 unsigned int flags) 1108 unsigned int flags)
1092{ 1109{
1110 int crc = xfs_sb_version_hascrc(&mp->m_sb);
1111 __u32 magic = xfs_btree_magic(crc, btnum);
1112
1093 buf->bb_magic = cpu_to_be32(magic); 1113 buf->bb_magic = cpu_to_be32(magic);
1094 buf->bb_level = cpu_to_be16(level); 1114 buf->bb_level = cpu_to_be16(level);
1095 buf->bb_numrecs = cpu_to_be16(numrecs); 1115 buf->bb_numrecs = cpu_to_be16(numrecs);
@@ -1097,7 +1117,7 @@ xfs_btree_init_block_int(
1097 if (flags & XFS_BTREE_LONG_PTRS) { 1117 if (flags & XFS_BTREE_LONG_PTRS) {
1098 buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLFSBLOCK); 1118 buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLFSBLOCK);
1099 buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLFSBLOCK); 1119 buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLFSBLOCK);
1100 if (flags & XFS_BTREE_CRC_BLOCKS) { 1120 if (crc) {
1101 buf->bb_u.l.bb_blkno = cpu_to_be64(blkno); 1121 buf->bb_u.l.bb_blkno = cpu_to_be64(blkno);
1102 buf->bb_u.l.bb_owner = cpu_to_be64(owner); 1122 buf->bb_u.l.bb_owner = cpu_to_be64(owner);
1103 uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid); 1123 uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid);
@@ -1110,7 +1130,7 @@ xfs_btree_init_block_int(
1110 1130
1111 buf->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK); 1131 buf->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
1112 buf->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK); 1132 buf->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
1113 if (flags & XFS_BTREE_CRC_BLOCKS) { 1133 if (crc) {
1114 buf->bb_u.s.bb_blkno = cpu_to_be64(blkno); 1134 buf->bb_u.s.bb_blkno = cpu_to_be64(blkno);
1115 buf->bb_u.s.bb_owner = cpu_to_be32(__owner); 1135 buf->bb_u.s.bb_owner = cpu_to_be32(__owner);
1116 uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid); 1136 uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid);
@@ -1123,14 +1143,14 @@ void
1123xfs_btree_init_block( 1143xfs_btree_init_block(
1124 struct xfs_mount *mp, 1144 struct xfs_mount *mp,
1125 struct xfs_buf *bp, 1145 struct xfs_buf *bp,
1126 __u32 magic, 1146 xfs_btnum_t btnum,
1127 __u16 level, 1147 __u16 level,
1128 __u16 numrecs, 1148 __u16 numrecs,
1129 __u64 owner, 1149 __u64 owner,
1130 unsigned int flags) 1150 unsigned int flags)
1131{ 1151{
1132 xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn, 1152 xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,
1133 magic, level, numrecs, owner, flags); 1153 btnum, level, numrecs, owner, flags);
1134} 1154}
1135 1155
1136STATIC void 1156STATIC void
@@ -1140,7 +1160,7 @@ xfs_btree_init_block_cur(
1140 int level, 1160 int level,
1141 int numrecs) 1161 int numrecs)
1142{ 1162{
1143 __u64 owner; 1163 __u64 owner;
1144 1164
1145 /* 1165 /*
1146 * we can pull the owner from the cursor right now as the different 1166 * we can pull the owner from the cursor right now as the different
@@ -1154,7 +1174,7 @@ xfs_btree_init_block_cur(
1154 owner = cur->bc_private.a.agno; 1174 owner = cur->bc_private.a.agno;
1155 1175
1156 xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn, 1176 xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,
1157 xfs_btree_magic(cur), level, numrecs, 1177 cur->bc_btnum, level, numrecs,
1158 owner, cur->bc_flags); 1178 owner, cur->bc_flags);
1159} 1179}
1160 1180