[Devel] [PATCH RHEL7 COMMIT] ext4: rework fallocate(FALLOC_FL_CONVERT_AND_EXTEND)

Konstantin Khorenko khorenko at virtuozzo.com
Wed Mar 16 02:23:58 PDT 2016


The commit is pushed to "branch-rh7-3.10.0-327.10.1.vz7.12.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.10.1.vz7.12.2
------>
commit 74d36a32a523656cff738d4a56b636c6821157f7
Author: Maxim Patlasov <mpatlasov at virtuozzo.com>
Date:   Wed Mar 16 13:23:58 2016 +0400

    ext4: rework fallocate(FALLOC_FL_CONVERT_AND_EXTEND)
    
    Patchset description:
    
    The patch reworks the feature and renames it to FALLOC_FL_CONVERT_UNWRITTEN.
    
    Intended use:
    
    0) pos := i_size_read(inode); len := 1MB; prealloc := 100MB
    
    1) fallocate(file, 0, pos, prealloc)
    2) fiemap(inode, &fieinfo, pos, 1)
    3) dio pwrite(block_device, data, len, fi_extent.fe_physical)
    4) fallocate(file, FALLOC_FL_CONVERT_UNWRITTEN, pos, len)
    
    ===
    This patch description:
    
    Since Oct 9 2014 (commit 671ddaaab74a8495a549fccae49eb4305c11e5d2), ploop has
    not used FALLOC_FL_KEEP_SIZE. This means that the part of
    fallocate(FALLOC_FL_CONVERT_AND_EXTEND) extending i_size is redundant now.
    Hence, we can use existing (and well tested) ext4_convert_unwritten_extents()
    instead of our home-made (buggy) algorithm.
    
    https://jira.sw.ru/browse/PSBM-22381
    
    Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
    Acked-by: Dmitry Monakhov <dmonakhov at virtuozzo.com>
---
 fs/ext4/extents.c | 111 +-----------------------------------------------------
 1 file changed, 1 insertion(+), 110 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 34afee9..cf248ce 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4666,115 +4666,6 @@ retry:
 	ext4_std_error(inode->i_sb, err);
 }
 
-static int ext4_convert_and_extend_locked(struct inode *inode, loff_t offset,
-					  loff_t len)
-{
-	struct ext4_ext_path *path = NULL;
-	loff_t new_size = offset + len;
-	ext4_lblk_t iblock = offset >> inode->i_blkbits;
-	ext4_lblk_t new_iblock = new_size >> inode->i_blkbits;
-	unsigned int max_blocks = new_iblock - iblock;
-	handle_t *handle;
-	unsigned int credits;
-	int err = 0;
-	int ret = 0;
-
-	if ((loff_t)iblock << inode->i_blkbits != offset ||
-	    (loff_t)new_iblock << inode->i_blkbits != new_size)
-		return -EINVAL;
-
-	while (max_blocks > 0) {
-		struct ext4_extent *ex;
-		ext4_lblk_t ee_block;
-		ext4_fsblk_t ee_start;
-		unsigned short ee_len;
-		int depth;
-
-		/*
-		 * credits to insert 1 extents into extent tree
-		 */
-		credits = ext4_chunk_trans_blocks(inode, max_blocks);
-		handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, credits);
-		if (IS_ERR(handle))
-		       return PTR_ERR(handle);
-
-		down_write((&EXT4_I(inode)->i_data_sem));
-
-		/* find extent for this block */
-		path = ext4_ext_find_extent(inode, iblock, NULL, 0);
-		if (IS_ERR(path)) {
-			err = PTR_ERR(path);
-			goto done;
-		}
-
-		depth = ext_depth(inode);
-		ex = path[depth].p_ext;
-		BUG_ON(ex == NULL && depth != 0);
-
-		if (ex == NULL) {
-			err = -ENOENT;
-			goto done;
-		}
-
-		ee_block = le32_to_cpu(ex->ee_block);
-		ee_start = ext4_ext_pblock(ex);
-		ee_len = ext4_ext_get_actual_len(ex);
-		if (!in_range(iblock, ee_block, ee_len)) {
-			err = -ERANGE;
-			goto done;
-		}
-
-		if (ext4_ext_is_unwritten(ex)) {
-			struct ext4_map_blocks map = {0};
-
-			map.m_lblk = iblock;
-			map.m_len = max_blocks;
-			err = ext4_convert_unwritten_extents_endio(handle, inode,
-								   &map,
-								   path);
-			if (err < 0)
-				goto done;
-
-			ext4_update_inode_fsync_trans(handle, inode, 1);
-			err = check_eofblocks_fl(handle, inode, iblock, path,
-						 max_blocks);
-			if (err)
-				goto done;
-		}
-
-
-		up_write((&EXT4_I(inode)->i_data_sem));
-
-		iblock += ee_len;
-		max_blocks -= (ee_len < max_blocks) ? ee_len : max_blocks;
-
-		if (!max_blocks && new_size > i_size_read(inode)) {
-			i_size_write(inode, new_size);
-			ext4_update_i_disksize(inode, new_size);
-		}
-
-		ret = ext4_mark_inode_dirty(handle, inode);
-done:
-		if (err)
-			up_write((&EXT4_I(inode)->i_data_sem));
-		else
-			err = ret;
-
-		if (path) {
-			ext4_ext_drop_refs(path);
-			kfree(path);
-		}
-
-		ret = ext4_journal_stop(handle);
-		if (!err && ret)
-			err = ret;
-		if (err)
-			return err;
-	}
-
-	return 0;
-}
-
 static int ext4_convert_and_extend(struct inode *inode, loff_t offset,
 				   loff_t len)
 {
@@ -4784,7 +4675,7 @@ static int ext4_convert_and_extend(struct inode *inode, loff_t offset,
 		return -EACCES;
 
 	mutex_lock(&inode->i_mutex);
-	err = ext4_convert_and_extend_locked(inode, offset, len);
+	err = ext4_convert_unwritten_extents(NULL, inode, offset, len);
 	mutex_unlock(&inode->i_mutex);
 
 	return err;


More information about the Devel mailing list