diff options
| -rw-r--r-- | fs/btrfs/extent_io.c | 32 | ||||
| -rw-r--r-- | fs/btrfs/tests/extent-io-tests.c | 9 | 
2 files changed, 27 insertions, 14 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 8ff17bc30d5a..c467c664f600 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1593,21 +1593,25 @@ void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,  	/* Find first extent with bits cleared */  	while (1) {  		node = __etree_search(tree, start, &next, &prev, NULL, NULL); -		if (!node) { +		if (!node && !next && !prev) { +			/* +			 * Tree is completely empty, send full range and let +			 * caller deal with it +			 */ +			*start_ret = 0; +			*end_ret = -1; +			goto out; +		} else if (!node && !next) { +			/* +			 * We are past the last allocated chunk, set start at +			 * the end of the last extent. +			 */ +			state = rb_entry(prev, struct extent_state, rb_node); +			*start_ret = state->end + 1; +			*end_ret = -1; +			goto out; +		} else if (!node) {  			node = next; -			if (!node) { -				/* -				 * We are past the last allocated chunk, -				 * set start at the end of the last extent. The -				 * device alloc tree should never be empty so -				 * prev is always set. -				 */ -				ASSERT(prev); -				state = rb_entry(prev, struct extent_state, rb_node); -				*start_ret = state->end + 1; -				*end_ret = -1; -				goto out; -			}  		}  		/*  		 * At this point 'node' either contains 'start' or start is diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index 123d9a614357..df7ce874a74b 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c @@ -441,8 +441,17 @@ static int test_find_first_clear_extent_bit(void)  	int ret = -EINVAL;  	test_msg("running find_first_clear_extent_bit test"); +  	extent_io_tree_init(NULL, &tree, IO_TREE_SELFTEST, NULL); +	/* Test correct handling of empty tree */ +	find_first_clear_extent_bit(&tree, 0, &start, &end, CHUNK_TRIMMED); +	if (start != 0 || end != -1) { +		test_err( +	"error getting a range from completely empty tree: start %llu end %llu", +			 start, end); +		goto out; +	}  	/*  	 * Set 1M-4M alloc/discard and 32M-64M thus leaving a hole between  	 * 4M-32M  | 
