diff mbox series

[U-Boot,v2] fs: btrfs: fix btrfs_search_tree invalid results

Message ID 20190416004714.27299-1-delroth@gmail.com
State Accepted
Commit 1627e5e5985d92bebdbfb19ab783eaf69337900e
Delegated to: Tom Rini
Headers show
Series [U-Boot,v2] fs: btrfs: fix btrfs_search_tree invalid results | expand

Commit Message

Pierre Bourdon April 16, 2019, 12:47 a.m. UTC
btrfs_search_tree should return the first item in the tree that is
greater or equal to the searched item.

The search algorithm did not properly handle the edge case where the
searched item is higher than the last item of the node but lower than
the first item of the next node. Instead of properly returning the first
item of the next node, it was returning an invalid path pointer
(pointing to a non-existent item after the last item of the node + 1).

This fixes two issues in the btrfs driver:
  - Looking for a ROOT_ITEM could fail if it was the first item of its
    leaf node.
  - Iterating through DIR_INDEX entries (for readdir) could fail if the
    first DIR_INDEX entry was the first item of a leaf node.

Signed-off-by: Pierre Bourdon <delroth@gmail.com>
Cc: Marek Behun <marek.behun@nic.cz>
---
v2: coding style (braces), clearer comment

 fs/btrfs/ctree.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Tom Rini April 27, 2019, 2:46 p.m. UTC | #1
On Tue, Apr 16, 2019 at 02:47:14AM +0200, Pierre Bourdon wrote:

> btrfs_search_tree should return the first item in the tree that is
> greater or equal to the searched item.
> 
> The search algorithm did not properly handle the edge case where the
> searched item is higher than the last item of the node but lower than
> the first item of the next node. Instead of properly returning the first
> item of the next node, it was returning an invalid path pointer
> (pointing to a non-existent item after the last item of the node + 1).
> 
> This fixes two issues in the btrfs driver:
>   - Looking for a ROOT_ITEM could fail if it was the first item of its
>     leaf node.
>   - Iterating through DIR_INDEX entries (for readdir) could fail if the
>     first DIR_INDEX entry was the first item of a leaf node.
> 
> Signed-off-by: Pierre Bourdon <delroth@gmail.com>
> Cc: Marek Behun <marek.behun@nic.cz>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index d248d79932..7fae383f15 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -185,10 +185,20 @@  int btrfs_search_tree(const struct btrfs_root *root, struct btrfs_key *key,
 		p->slots[lvl] = slot;
 		p->nodes[lvl] = buf;
 
-		if (lvl)
+		if (lvl) {
 			logical = buf->node.ptrs[slot].blockptr;
-		else
+		} else {
+			/*
+			 * The path might be invalid if:
+			 *   cur leaf max < searched value < next leaf min
+			 *
+			 * Jump to the next valid element if it exists.
+			 */
+			if (slot >= buf->header.nritems)
+				if (btrfs_next_slot(p) < 0)
+					goto err;
 			break;
+		}
 	}
 
 	return 0;