From: Eric Sandeen Date: Mon, 12 May 2008 23:13:49 +0000 (-0500) Subject: fix extent_goto for non-0 leaf levels X-Git-Tag: v1.41-WIP-0617~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9817a2ba2d408077dab12090b4b4250d0d9a282a;p=thirdparty%2Fe2fsprogs.git fix extent_goto for non-0 leaf levels The logic for stopping at the right level in extent_goto was wrong, so if you asked it to go to any level other than 0 (the leaf level) it would fail. Also add this argument to the tst_extents goto command to test it. (I thought this was a failure in my split code but it was this helper that was causing problems...) Signed-off-by: Eric Sandeen Signed-off-by: Theodore Ts'o --- diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c index e7b7e8556..b76abdcbc 100644 --- a/lib/ext2fs/extent.c +++ b/lib/ext2fs/extent.c @@ -556,6 +556,9 @@ errcode_t ext2fs_extent_free_path(ext2_extent_path_t path) /* * Go to the node at leaf_level which contains logical block blk. * + * leaf_level is height from the leaf node level, i.e. + * leaf_level 0 is at leaf node, leaf_level 1 is 1 above etc. + * * If "blk" has no mapping (hole) then handle is left at last * extent before blk. */ @@ -569,9 +572,15 @@ static errcode_t extent_goto(ext2_extent_handle_t handle, if (retval) return retval; + if (leaf_level > handle->max_depth) { + dbg_printf("leaf level %d greater than tree depth %d\n", + leaf_level, handle->max_depth); + return EXT2_ET_OP_NOT_SUPPORTED; + } + dbg_print_extent("root", &extent); while (1) { - if (handle->level - leaf_level == handle->max_depth) { + if (handle->max_depth - handle->level == leaf_level) { /* block is in this &extent */ if ((blk >= extent.e_lblk) && (blk < extent.e_lblk + extent.e_len)) @@ -1140,6 +1149,7 @@ void do_goto_block(int argc, char **argv) errcode_t retval; int op = EXT2_EXTENT_NEXT_LEAF; blk_t blk; + int level = 0; if (check_fs_open(argv[0])) return; @@ -1149,18 +1159,23 @@ void do_goto_block(int argc, char **argv) return; } - if (argc != 2) { - fprintf(stderr, "%s block\n", argv[0]); + if (argc < 2 || argc > 3) { + fprintf(stderr, "%s block [level]\n", argv[0]); return; } if (strtoblk(argv[0], argv[1], &blk)) return; - retval = ext2fs_extent_goto(current_handle, (blk64_t) blk); + if (argc == 3) + if (strtoblk(argv[0], argv[2], &level)) + return; + + retval = extent_goto(current_handle, level, (blk64_t) blk); + if (retval) { - com_err(argv[0], retval, "while trying to go to block %lu", - blk); + com_err(argv[0], retval, "while trying to go to block %lu, level %d", + blk, level); return; }