@@ -287,7 +287,7 @@
errcode_t retval;
blk_t blk;
blk64_t end_blk;
- int orig_op, op;
+ int orig_op, op, orig_level;
EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
@@ -295,6 +295,7 @@
return EXT2_ET_NO_CURRENT_NODE;
orig_op = op = flags & EXT2_EXTENT_MOVE_MASK;
+ orig_level = handle->level;
retry:
path = handle->path + handle->level;
@@ -309,16 +310,20 @@
op = EXT2_EXTENT_NEXT_SIB;
else if (handle->level > 0)
op = EXT2_EXTENT_UP;
- else
+ else {
+ handle->level = orig_level;
return EXT2_ET_EXTENT_NO_NEXT;
+ }
} else {
/* leaf node */
if (path->left > 0)
op = EXT2_EXTENT_NEXT_SIB;
else if (handle->level > 0)
op = EXT2_EXTENT_UP;
- else
+ else {
+ handle->level = orig_level;
return EXT2_ET_EXTENT_NO_NEXT;
+ }
}
if (op != EXT2_EXTENT_NEXT_SIB) {
#ifdef DEBUG_GET_EXTENT
@@ -340,8 +345,10 @@
op = EXT2_EXTENT_PREV_SIB;
else if (handle->level > 0)
op = EXT2_EXTENT_UP;
- else
+ else {
+ handle->level = orig_level;
return EXT2_ET_EXTENT_NO_PREV;
+ }
} else {
/* leaf node */
if (path->left < path->entries-1)
@@ -417,12 +424,16 @@
case EXT2_EXTENT_UP:
if (handle->level <= 0)
return EXT2_ET_EXTENT_NO_UP;
+ path->visit_num = 0;
handle->level--;
path--;
ix = path->curr;
if ((orig_op == EXT2_EXTENT_PREV) ||
(orig_op == EXT2_EXTENT_PREV_LEAF))
path->visit_num = 0;
+ if ((orig_op == EXT2_EXTENT_NEXT) ||
+ (orig_op == EXT2_EXTENT_NEXT_LEAF))
+ path->visit_num = 1;
break;
case EXT2_EXTENT_DOWN:
case EXT2_EXTENT_DOWN_AND_LAST:
@@ -536,6 +547,16 @@
(path->left != 0)))
goto retry;
+ if (((orig_op == EXT2_EXTENT_NEXT_LEAF) ||
+ (orig_op == EXT2_EXTENT_NEXT)) &&
+ (op == EXT2_EXTENT_UP))
+ goto retry;
+
+ if ((orig_op == EXT2_EXTENT_PREV) &&
+ (op == EXT2_EXTENT_PREV_SIB) &&
+ (handle->level != handle->max_depth))
+ goto retry;
+
return 0;
}