|
@@ -2226,13 +2226,14 @@ errout:
|
|
|
* removes index from the index block.
|
|
|
*/
|
|
|
static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
|
|
|
- struct ext4_ext_path *path)
|
|
|
+ struct ext4_ext_path *path, int depth)
|
|
|
{
|
|
|
int err;
|
|
|
ext4_fsblk_t leaf;
|
|
|
|
|
|
/* free index block */
|
|
|
- path--;
|
|
|
+ depth--;
|
|
|
+ path = path + depth;
|
|
|
leaf = ext4_idx_pblock(path->p_idx);
|
|
|
if (unlikely(path->p_hdr->eh_entries == 0)) {
|
|
|
EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0");
|
|
@@ -2257,6 +2258,19 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
|
|
|
|
|
|
ext4_free_blocks(handle, inode, NULL, leaf, 1,
|
|
|
EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
|
|
|
+
|
|
|
+ while (--depth >= 0) {
|
|
|
+ if (path->p_idx != EXT_FIRST_INDEX(path->p_hdr))
|
|
|
+ break;
|
|
|
+ path--;
|
|
|
+ err = ext4_ext_get_access(handle, inode, path);
|
|
|
+ if (err)
|
|
|
+ break;
|
|
|
+ path->p_idx->ei_block = (path+1)->p_idx->ei_block;
|
|
|
+ err = ext4_ext_dirty(handle, inode, path);
|
|
|
+ if (err)
|
|
|
+ break;
|
|
|
+ }
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -2599,7 +2613,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
|
|
|
/* if this leaf is free, then we should
|
|
|
* remove it from index block above */
|
|
|
if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL)
|
|
|
- err = ext4_ext_rm_idx(handle, inode, path + depth);
|
|
|
+ err = ext4_ext_rm_idx(handle, inode, path, depth);
|
|
|
|
|
|
out:
|
|
|
return err;
|
|
@@ -2802,7 +2816,7 @@ again:
|
|
|
/* index is empty, remove it;
|
|
|
* handle must be already prepared by the
|
|
|
* truncatei_leaf() */
|
|
|
- err = ext4_ext_rm_idx(handle, inode, path + i);
|
|
|
+ err = ext4_ext_rm_idx(handle, inode, path, i);
|
|
|
}
|
|
|
/* root level has p_bh == NULL, brelse() eats this */
|
|
|
brelse(path[i].p_bh);
|