Direct IO for holes and fallocate: unwritten extents spt for DIO
PATCH v2 2/2 Direct IO for holes and fallocate: unwritten extents spt for DIO
Version2 of the patch, fixing issues found with fsstress tests. We should not merge neighbor extents when do unwritten extents split for DIO before submit the IO.
handling unwritten extents lookup/map/convert for direct IO request.
For already fallocated extent, at the time DIO get_block() is called, ext4 will split the fallocated extent as necessary, mark the to-write fallocated extent mapped but still remains unwritten. Need to insert the splitted extents, to prevent ENOSPC later.
At the time all IO has completed, end_io call back function will mark the unwritten extent as written.
Patch against ext4 patch queue.
Comments?
Singed-Off-By Mingming Cao <[email protected]>
--- fs/ext4/ext4_extents.h | 5 fs/ext4/extents.c | 401 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 377 insertions(+), 29 deletions(-)
fs/ext4/ext4_extents.h +6 -1
@@ -219,6 +219,11 @@ static inline int ext4_ext_get_actual_le (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN)); } +static inline void ext4_ext_mark_initialized (struct ext4_extent *ext) +{ + ext->ee_len =cpu_to_le16 (ext4_ext_get_actual_len (ext)); +} +extern int ext4_ext_calc_metadata_amount (struct inode *inode,int blocks);extern ext4_fsblk_t ext_pblock (struct ext4_extent *ex);extern ext4_fsblk_t idx_pblock (struct ext4_extent_idx *);
@@ -229,7 +234,7 @@ extern int ext4_ext_calc_credits_for_sin struct ext4_ext_path *path);extern int ext4_can_extents_be_merged (struct inode *inode,struct ext4_extent *ex1, -struct ext4_extent *ex2); +struct ext4_extent *ex2,int flag);extern int ext4_ext_try_to_merge (struct inode *inode,struct ext4_ext_path *path,struct ext4_extent *);
fs/ext4/extents.c +411 -35
516 lines not on this page · raw message
fs/ext4/move_extent.c +2 -2
@@ -504,7 +504,7 @@ mext_leaf_block(handle_t *handle, struct* if these are contiguous and same extent type. */ if (ext4_can_extents_be_merged (orig_inode, prev_ext, - &new_ext) { + &new_ext,0 )) { o_start = prev_ext; start_ext.ee_len = cpu_to_le16( ext4_ext_get_actual_len(prev_ext) +
@@ -1216,7 +1216,7 @@ ext4_move_extents(struct file *o_filp, s* if extents are contiguous. */ if (ext4_can_extents_be_merged (orig_inode, - ext_prev, ext_cur) && + ext_prev, ext_cur,0 ) && block_end >=le32_to_cpu (ext_cur->ee_block) && !last_extent)continue ;
fs/ext4/inode.c +3 -0
@@ -1156,6 +1156,9 @@ int ext4_get_blocks(handle_t *handle, stclear_buffer_mapped (bh);clear_buffer_unwritten (bh); +ext_debug ("ext4_get_blocks(): inode %lu, flag %d, max_blocks %u," +"logical block %lu\n" , inode->i_ino, flags, max_blocks, + (unsigned long )block);/* * Try to see if we can get the block without requesting a new * file system block.