Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: dm-bht.c

Issue 6670096: verity: create a regular trie when depth=0 (Closed) Base URL: http://git.chromium.org/git/dm-verity.git@master
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | dm-bht_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> 2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org>
3 * 3 *
4 * Device-Mapper block hash tree interface. 4 * Device-Mapper block hash tree interface.
5 * See Documentation/device-mapper/dm-bht.txt for details. 5 * See Documentation/device-mapper/dm-bht.txt for details.
6 * 6 *
7 * This file is released under the GPL. 7 * This file is released under the GPL.
8 */ 8 */
9 9
10 #include <asm/atomic.h> 10 #include <asm/atomic.h>
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 258
259 /* Configure the tree */ 259 /* Configure the tree */
260 bht->block_count = block_count; 260 bht->block_count = block_count;
261 DMDEBUG("Setting block_count %u", block_count); 261 DMDEBUG("Setting block_count %u", block_count);
262 if (block_count == 0) { 262 if (block_count == 0) {
263 DMERR("block_count must be non-zero"); 263 DMERR("block_count must be non-zero");
264 status = -EINVAL; 264 status = -EINVAL;
265 goto bad_block_count; 265 goto bad_block_count;
266 } 266 }
267 267
268 bht->depth = depth; /* assignment below */
269 DMDEBUG("Setting depth %u", depth);
270 if (!depth || depth > UINT_MAX / sizeof(struct dm_bht_level)) {
271 DMERR("bht depth is invalid: %u", depth);
272 status = -EINVAL;
273 goto bad_depth;
274 }
275
276 /* Allocate levels. Each level of the tree may have an arbitrary number
277 * of dm_bht_entry structs. Each entry contains node_count nodes.
278 * Each node in the tree is a cryptographic digest of either node_count
279 * nodes on the subsequent level or of a specific block on disk.
280 */
281 bht->levels = (struct dm_bht_level *)
282 kcalloc(depth, sizeof(struct dm_bht_level), GFP_KERNEL);
283 if (!bht->levels) {
284 DMERR("failed to allocate tree levels");
285 status = -ENOMEM;
286 goto bad_level_alloc;
287 }
288
289 /* Each dm_bht_entry->nodes is one page. The node code tracks 268 /* Each dm_bht_entry->nodes is one page. The node code tracks
290 * how many nodes fit into one entry where a node is a single 269 * how many nodes fit into one entry where a node is a single
291 * hash (message digest). 270 * hash (message digest).
292 */ 271 */
293 bht->node_count_shift = fls(PAGE_SIZE / bht->digest_size) - 1; 272 bht->node_count_shift = fls(PAGE_SIZE / bht->digest_size) - 1;
294 /* Round down to the nearest power of two. This makes indexing 273 /* Round down to the nearest power of two. This makes indexing
295 * into the tree much less painful. 274 * into the tree much less painful.
296 */ 275 */
297 bht->node_count = 1 << bht->node_count_shift; 276 bht->node_count = 1 << bht->node_count_shift;
298 277
299 /* This is unlikely to happen, but with 64k pages, who knows. */ 278 /* This is unlikely to happen, but with 64k pages, who knows. */
300 if (bht->node_count > UINT_MAX / bht->digest_size) { 279 if (bht->node_count > UINT_MAX / bht->digest_size) {
301 DMERR("node_count * hash_len exceeds UINT_MAX!"); 280 DMERR("node_count * hash_len exceeds UINT_MAX!");
302 status = -EINVAL; 281 status = -EINVAL;
303 goto bad_node_count; 282 goto bad_node_count;
304 } 283 }
284
285 /* if depth == 0, create a "regular" trie with a single root block */
286 if (depth == 0)
287 depth = DIV_ROUND_UP(fls(block_count - 1),
288 bht->node_count_shift);
289 if (depth > UINT_MAX / sizeof(struct dm_bht_level)) {
290 DMERR("bht depth is invalid: %u", depth);
291 status = -EINVAL;
292 goto bad_depth;
293 }
294 DMDEBUG("Setting depth to %u.", depth);
295 bht->depth = depth;
296
305 /* Ensure that we can safely shift by this value. */ 297 /* Ensure that we can safely shift by this value. */
306 if (depth * bht->node_count_shift >= sizeof(unsigned int) * 8) { 298 if (depth * bht->node_count_shift >= sizeof(unsigned int) * 8) {
307 DMERR("specified depth and node_count_shift is too large"); 299 DMERR("specified depth and node_count_shift is too large");
308 status = -EINVAL; 300 status = -EINVAL;
309 goto bad_node_count; 301 goto bad_node_count;
310 } 302 }
311 303
304 /* Allocate levels. Each level of the tree may have an arbitrary number
305 * of dm_bht_entry structs. Each entry contains node_count nodes.
306 * Each node in the tree is a cryptographic digest of either node_count
307 * nodes on the subsequent level or of a specific block on disk.
308 */
309 bht->levels = (struct dm_bht_level *)
310 kcalloc(depth, sizeof(struct dm_bht_level), GFP_KERNEL);
311 if (!bht->levels) {
312 DMERR("failed to allocate tree levels");
313 status = -ENOMEM;
314 goto bad_level_alloc;
315 }
316
312 /* Setup callback stubs */ 317 /* Setup callback stubs */
313 bht->read_cb = &dm_bht_read_callback_stub; 318 bht->read_cb = &dm_bht_read_callback_stub;
314 bht->write_cb = &dm_bht_write_callback_stub; 319 bht->write_cb = &dm_bht_write_callback_stub;
315 320
316 status = dm_bht_initialize_entries(bht); 321 status = dm_bht_initialize_entries(bht);
317 if (status) 322 if (status)
318 goto bad_entries_alloc; 323 goto bad_entries_alloc;
319 324
320 return 0; 325 return 0;
321 326
322 bad_entries_alloc: 327 bad_entries_alloc:
323 while (bht->depth-- > 0) 328 while (bht->depth-- > 0)
324 kfree(bht->levels[bht->depth].entries); 329 kfree(bht->levels[bht->depth].entries);
330 kfree(bht->levels);
325 bad_node_count: 331 bad_node_count:
326 kfree(bht->levels);
327 bad_level_alloc: 332 bad_level_alloc:
328 bad_block_count: 333 bad_block_count:
329 bad_depth: 334 bad_depth:
330 kfree(bht->root_digest); 335 kfree(bht->root_digest);
331 bad_root_digest_alloc: 336 bad_root_digest_alloc:
332 bad_digest_len: 337 bad_digest_len:
333 for (cpu = 0; cpu < nr_cpu_ids; ++cpu) 338 for (cpu = 0; cpu < nr_cpu_ids; ++cpu)
334 if (bht->hash_desc[cpu].tfm) 339 if (bht->hash_desc[cpu].tfm)
335 crypto_free_hash(bht->hash_desc[cpu].tfm); 340 crypto_free_hash(bht->hash_desc[cpu].tfm);
336 bad_hash_alg: 341 bad_hash_alg:
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 if (!bht->root_digest) { 1190 if (!bht->root_digest) {
1186 DMERR("no root digest exists to export"); 1191 DMERR("no root digest exists to export");
1187 if (available > 0) 1192 if (available > 0)
1188 *hexdigest = 0; 1193 *hexdigest = 0;
1189 return -1; 1194 return -1;
1190 } 1195 }
1191 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); 1196 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size);
1192 return 0; 1197 return 0;
1193 } 1198 }
1194 EXPORT_SYMBOL(dm_bht_root_hexdigest); 1199 EXPORT_SYMBOL(dm_bht_root_hexdigest);
OLDNEW
« no previous file with comments | « no previous file | dm-bht_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698