* Calculate which level n block references the data at the level 0 offset * provided. */
| 1166 | * provided. |
| 1167 | */ |
| 1168 | uint64_t |
| 1169 | dbuf_whichblock(const dnode_t *dn, const int64_t level, const uint64_t offset) |
| 1170 | { |
| 1171 | if (dn->dn_datablkshift != 0 && dn->dn_indblkshift != 0) { |
| 1172 | /* |
| 1173 | * The level n blkid is equal to the level 0 blkid divided by |
| 1174 | * the number of level 0s in a level n block. |
| 1175 | * |
| 1176 | * The level 0 blkid is offset >> datablkshift = |
| 1177 | * offset / 2^datablkshift. |
| 1178 | * |
| 1179 | * The number of level 0s in a level n is the number of block |
| 1180 | * pointers in an indirect block, raised to the power of level. |
| 1181 | * This is 2^(indblkshift - SPA_BLKPTRSHIFT)^level = |
| 1182 | * 2^(level*(indblkshift - SPA_BLKPTRSHIFT)). |
| 1183 | * |
| 1184 | * Thus, the level n blkid is: offset / |
| 1185 | * ((2^datablkshift)*(2^(level*(indblkshift-SPA_BLKPTRSHIFT)))) |
| 1186 | * = offset / 2^(datablkshift + level * |
| 1187 | * (indblkshift - SPA_BLKPTRSHIFT)) |
| 1188 | * = offset >> (datablkshift + level * |
| 1189 | * (indblkshift - SPA_BLKPTRSHIFT)) |
| 1190 | */ |
| 1191 | |
| 1192 | const unsigned exp = dn->dn_datablkshift + |
| 1193 | level * (dn->dn_indblkshift - SPA_BLKPTRSHIFT); |
| 1194 | |
| 1195 | if (exp >= 8 * sizeof (offset)) { |
| 1196 | /* This only happens on the highest indirection level */ |
| 1197 | ASSERT3U(level, ==, dn->dn_nlevels - 1); |
| 1198 | return (0); |
| 1199 | } |
| 1200 | |
| 1201 | ASSERT3U(exp, <, 8 * sizeof (offset)); |
| 1202 | |
| 1203 | return (offset >> exp); |
| 1204 | } else { |
| 1205 | ASSERT3U(offset, <, dn->dn_datablksz); |
| 1206 | return (0); |
| 1207 | } |
| 1208 | } |
| 1209 | |
| 1210 | /* |
| 1211 | * This function is used to lock the parent of the provided dbuf. This should be |
no outgoing calls
no test coverage detected