diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_btree.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 48 |
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 |
55 | xfs_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 | ||
56 | STATIC int /* error (0 or EFSCORRUPTED) */ | 66 | STATIC int /* error (0 or EFSCORRUPTED) */ |
57 | xfs_btree_check_lblock( | 67 | xfs_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 | |||
1123 | xfs_btree_init_block( | 1143 | xfs_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 | ||
1136 | STATIC void | 1156 | STATIC 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 | ||