|
@@ -192,12 +192,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
|
|
|
static ext4_fsblk_t
|
|
|
ext4_ext_new_meta_block(handle_t *handle, struct inode *inode,
|
|
|
struct ext4_ext_path *path,
|
|
|
- struct ext4_extent *ex, int *err)
|
|
|
+ struct ext4_extent *ex, int *err, unsigned int flags)
|
|
|
{
|
|
|
ext4_fsblk_t goal, newblock;
|
|
|
|
|
|
goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block));
|
|
|
- newblock = ext4_new_meta_blocks(handle, inode, goal, NULL, err);
|
|
|
+ newblock = ext4_new_meta_blocks(handle, inode, goal, flags,
|
|
|
+ NULL, err);
|
|
|
return newblock;
|
|
|
}
|
|
|
|
|
@@ -792,8 +793,9 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
|
|
|
* - initializes subtree
|
|
|
*/
|
|
|
static int ext4_ext_split(handle_t *handle, struct inode *inode,
|
|
|
- struct ext4_ext_path *path,
|
|
|
- struct ext4_extent *newext, int at)
|
|
|
+ unsigned int flags,
|
|
|
+ struct ext4_ext_path *path,
|
|
|
+ struct ext4_extent *newext, int at)
|
|
|
{
|
|
|
struct buffer_head *bh = NULL;
|
|
|
int depth = ext_depth(inode);
|
|
@@ -847,7 +849,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
|
|
|
ext_debug("allocate %d blocks for indexes/leaf\n", depth - at);
|
|
|
for (a = 0; a < depth - at; a++) {
|
|
|
newblock = ext4_ext_new_meta_block(handle, inode, path,
|
|
|
- newext, &err);
|
|
|
+ newext, &err, flags);
|
|
|
if (newblock == 0)
|
|
|
goto cleanup;
|
|
|
ablocks[a] = newblock;
|
|
@@ -1056,8 +1058,9 @@ cleanup:
|
|
|
* just created block
|
|
|
*/
|
|
|
static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
|
|
|
- struct ext4_ext_path *path,
|
|
|
- struct ext4_extent *newext)
|
|
|
+ unsigned int flags,
|
|
|
+ struct ext4_ext_path *path,
|
|
|
+ struct ext4_extent *newext)
|
|
|
{
|
|
|
struct ext4_ext_path *curp = path;
|
|
|
struct ext4_extent_header *neh;
|
|
@@ -1065,7 +1068,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
|
|
|
ext4_fsblk_t newblock;
|
|
|
int err = 0;
|
|
|
|
|
|
- newblock = ext4_ext_new_meta_block(handle, inode, path, newext, &err);
|
|
|
+ newblock = ext4_ext_new_meta_block(handle, inode, path,
|
|
|
+ newext, &err, flags);
|
|
|
if (newblock == 0)
|
|
|
return err;
|
|
|
|
|
@@ -1140,8 +1144,9 @@ out:
|
|
|
* if no free index is found, then it requests in-depth growing.
|
|
|
*/
|
|
|
static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
|
|
|
- struct ext4_ext_path *path,
|
|
|
- struct ext4_extent *newext)
|
|
|
+ unsigned int flags,
|
|
|
+ struct ext4_ext_path *path,
|
|
|
+ struct ext4_extent *newext)
|
|
|
{
|
|
|
struct ext4_ext_path *curp;
|
|
|
int depth, i, err = 0;
|
|
@@ -1161,7 +1166,7 @@ repeat:
|
|
|
if (EXT_HAS_FREE_INDEX(curp)) {
|
|
|
/* if we found index with free entry, then use that
|
|
|
* entry: create all needed subtree and add new leaf */
|
|
|
- err = ext4_ext_split(handle, inode, path, newext, i);
|
|
|
+ err = ext4_ext_split(handle, inode, flags, path, newext, i);
|
|
|
if (err)
|
|
|
goto out;
|
|
|
|
|
@@ -1174,7 +1179,8 @@ repeat:
|
|
|
err = PTR_ERR(path);
|
|
|
} else {
|
|
|
/* tree is full, time to grow in depth */
|
|
|
- err = ext4_ext_grow_indepth(handle, inode, path, newext);
|
|
|
+ err = ext4_ext_grow_indepth(handle, inode, flags,
|
|
|
+ path, newext);
|
|
|
if (err)
|
|
|
goto out;
|
|
|
|
|
@@ -1693,6 +1699,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
|
|
|
int depth, len, err;
|
|
|
ext4_lblk_t next;
|
|
|
unsigned uninitialized = 0;
|
|
|
+ int flags = 0;
|
|
|
|
|
|
if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
|
|
|
EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
|
|
@@ -1767,7 +1774,9 @@ repeat:
|
|
|
* There is no free space in the found leaf.
|
|
|
* We're gonna add a new leaf in the tree.
|
|
|
*/
|
|
|
- err = ext4_ext_create_new_leaf(handle, inode, path, newext);
|
|
|
+ if (flag & EXT4_GET_BLOCKS_PUNCH_OUT_EXT)
|
|
|
+ flags = EXT4_MB_USE_ROOT_BLOCKS;
|
|
|
+ err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext);
|
|
|
if (err)
|
|
|
goto cleanup;
|
|
|
depth = ext_depth(inode);
|