verity: pull up maybe_read_entry

Since the latest refactoring it is now possible to pull up maybe_read_entry.

I also removed the PENDING flag and instead just call is_populated.

BUG=chromium-os:13872
TEST=Ran dm-verity.git unit tests. Ran platform_DMVerityCorruption on H/W.

kernel.git Review URL: http://codereview.chromium.org/6883252

TBRing since already LGTMed and committed to kernel.git

Change-Id: Ie9a60325b8a1f4d40325cd0211477551c9aed488
Reviewed-on: http://gerrit.chromium.org/gerrit/4278
Reviewed-by: Mandeep Singh Baines <msb@chromium.org>
Tested-by: Mandeep Singh Baines <msb@chromium.org>
diff --git a/dm-bht.c b/dm-bht.c
index 7467455..a9968c0 100644
--- a/dm-bht.c
+++ b/dm-bht.c
@@ -459,70 +459,6 @@
 }
 EXPORT_SYMBOL(dm_bht_write_completed);
 
-/* dm_bht_maybe_read_entry
- * Attempts to atomically acquire an entry, allocate any needed
- * memory, and issues the I/O callback to load the hash from disk.
- * Return value is negative on error. When positive, it is the state
- * value.
- */
-static int dm_bht_maybe_read_entry(struct dm_bht *bht, void *ctx,
-				   unsigned int depth, unsigned int index)
-{
-	struct dm_bht_level *level = &bht->levels[depth];
-	struct dm_bht_entry *entry = &level->entries[index];
-	sector_t current_sector = level->sector + to_sector(index * PAGE_SIZE);
-	struct page *node_page;
-	int state;
-
-	BUG_ON(depth >= bht->depth);
-
-	/* XXX: hardcoding PAGE_SIZE means that a perfectly valid image
-	 *      on one system may not work on a different kernel.
-	 * TODO(wad) abstract PAGE_SIZE with a bht->entry_size or
-	 *           at least a define and ensure bht->entry_size is
-	 *           sector aligned at least.
-	 */
-
-	/* If the entry's state is UNALLOCATED, then we'll claim it
-	 * for allocation and loading.
-	 */
-	state = atomic_cmpxchg(&entry->state,
-			       DM_BHT_ENTRY_UNALLOCATED,
-			       DM_BHT_ENTRY_PENDING);
-	DMDEBUG("dm_bht_maybe_read_entry(d=%u,ei=%u): ei=%lu, state=%d",
-		depth, index, (unsigned long)(entry - level->entries), state);
-
-	if (state != DM_BHT_ENTRY_UNALLOCATED)
-		goto out;
-
-	state = DM_BHT_ENTRY_REQUESTED;
-
-	/* Current entry is claimed for allocation and loading */
-	node_page = (struct page *) mempool_alloc(bht->entry_pool, GFP_NOIO);
-	if (!node_page)
-		goto nomem;
-	/* dm-bht guarantees page-aligned memory for callbacks. */
-	entry->nodes = page_address(node_page);
-
-	/* TODO(wad) error check callback here too */
-	DMDEBUG("dm_bht_maybe_read_entry(d=%u,ei=%u): reading %lu",
-		depth, index, (unsigned long)(entry - level->entries));
-	bht->read_cb(ctx, current_sector, entry->nodes,
-		     to_sector(PAGE_SIZE), entry);
-
-out:
-	if (state <= DM_BHT_ENTRY_ERROR)
-		DMCRIT("entry %u is in an error state", index);
-
-	return state;
-
-nomem:
-	DMCRIT("failed to allocate memory for entry->nodes from pool");
-	return -ENOMEM;
-
-
-}
-
 /* dm_bht_verify_path
  * Verifies the path. Returns 0 on ok.
  */
@@ -716,13 +652,18 @@
 
 		for (i = 0; i < level->count; i++, entry++) {
 			unsigned int count = bht->node_count;
+			struct page *pg;
 
-			r = dm_bht_maybe_read_entry(bht, read_cb_ctx, depth, i);
-			if (r < 0) {
+			pg = (struct page *) mempool_alloc(bht->entry_pool,
+							   GFP_NOIO);
+			if (!pg) {
 				DMCRIT("an error occurred while reading entry");
 				goto out;
 			}
 
+			entry->nodes = page_address(pg);
+			atomic_set(&entry->state, DM_BHT_ENTRY_READY);
+
 			if (i == (level->count - 1))
 				count = child_level->count % bht->node_count;
 			if (count == 0)
@@ -827,38 +768,63 @@
 /**
  * dm_bht_populate - reads entries from disk needed to verify a given block
  * @bht:	pointer to a dm_bht_create()d bht
- * @read_cb_ctx:context used for all read_cb calls on this request
+ * @ctx:        context used for all read_cb calls on this request
  * @block_index:specific block data is expected from
  *
- * Returns negative value on error.
+ * Returns negative value on error. Returns 0 on success.
  */
-int dm_bht_populate(struct dm_bht *bht, void *read_cb_ctx,
+int dm_bht_populate(struct dm_bht *bht, void *ctx,
 		    unsigned int block_index)
 {
-	unsigned int depth, entry_index;
-	int status, populated = 0;
+	unsigned int depth;
+	int state = 0;
 
 	BUG_ON(block_index >= bht->block_count);
 
 	DMDEBUG("dm_bht_populate(%u)", block_index);
 
 	for (depth = 0; depth < bht->depth; ++depth) {
-		entry_index = dm_bht_index_at_level(bht, depth, block_index);
-		status = dm_bht_maybe_read_entry(bht, read_cb_ctx, depth,
-						 entry_index);
-		if (status < 0)
-			goto read_error;
+		struct dm_bht_level *level;
+		struct dm_bht_entry *entry;
+		unsigned int index;
+		struct page *pg;
 
-		/* Accrue return code flags */
-		populated |= status;
+		entry = dm_bht_get_entry(bht, depth, block_index);
+		state = atomic_cmpxchg(&entry->state,
+				       DM_BHT_ENTRY_UNALLOCATED,
+				       DM_BHT_ENTRY_PENDING);
+
+		if (state <= DM_BHT_ENTRY_ERROR)
+			goto error_state;
+
+		if (state != DM_BHT_ENTRY_UNALLOCATED)
+			continue;
+
+		/* Current entry is claimed for allocation and loading */
+		pg = (struct page *) mempool_alloc(bht->entry_pool, GFP_NOIO);
+		if (!pg)
+			goto nomem;
+
+		/* dm-bht guarantees page-aligned memory for callbacks. */
+		entry->nodes = page_address(pg);
+
+		/* TODO(wad) error check callback here too */
+
+		level = &bht->levels[depth];
+		index = dm_bht_index_at_level(bht, depth, block_index);
+		bht->read_cb(ctx, level->sector + to_sector(index * PAGE_SIZE),
+			     entry->nodes, to_sector(PAGE_SIZE), entry);
 	}
 
-	return populated;
+	return 0;
 
-read_error:
-	DMCRIT("failure reading entry %u depth %u", entry_index, depth);
-	return status;
+error_state:
+	DMCRIT("block %u at depth %u is in an error state", block_index, depth);
+	return state;
 
+nomem:
+	DMCRIT("failed to allocate memory for entry->nodes from pool");
+	return -ENOMEM;
 }
 EXPORT_SYMBOL(dm_bht_populate);
 
diff --git a/dm-bht.h b/dm-bht.h
index 21d5e34..44a1c02 100644
--- a/dm-bht.h
+++ b/dm-bht.h
@@ -25,9 +25,6 @@
 #define DM_BHT_ENTRY_VERIFIED 8  /* 'nodes' has been checked against parent */
 #define DM_BHT_ENTRY_READY 4  /* 'nodes' is loaded and available */
 #define DM_BHT_ENTRY_PENDING 2  /* 'nodes' is being loaded */
-#define DM_BHT_ENTRY_REQUESTED 1  /* non-state response indicating entry is
-				   * pending because of the current call
-				   */
 #define DM_BHT_ENTRY_UNALLOCATED 0 /* untouched */
 #define DM_BHT_ENTRY_ERROR -1 /* entry is unsuitable for use */
 #define DM_BHT_ENTRY_ERROR_IO -2 /* I/O error on load */
diff --git a/dm-bht_unittest.cc b/dm-bht_unittest.cc
index 396b446..3725009 100644
--- a/dm-bht_unittest.cc
+++ b/dm-bht_unittest.cc
@@ -140,7 +140,7 @@
       EXPECT_GE(dm_bht_populate(bht_.get(),
                                 reinterpret_cast<void *>(this),
                                 blocks),
-                DM_BHT_ENTRY_REQUESTED);
+                DM_BHT_ENTRY_PENDING);
       // Since we're testing synchronously, a second run through should yield
       // READY.
       EXPECT_GE(dm_bht_populate(bht_.get(),