|
@@ -1149,6 +1149,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
|
|
|
int retval;
|
|
|
|
|
|
clear_buffer_mapped(bh);
|
|
|
+ clear_buffer_unwritten(bh);
|
|
|
|
|
|
/*
|
|
|
* Try to see if we can get the block without requesting
|
|
@@ -1178,6 +1179,18 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
|
|
|
if (retval > 0 && buffer_mapped(bh))
|
|
|
return retval;
|
|
|
|
|
|
+ /*
|
|
|
+ * When we call get_blocks without the create flag, the
|
|
|
+ * BH_Unwritten flag could have gotten set if the blocks
|
|
|
+ * requested were part of a uninitialized extent. We need to
|
|
|
+ * clear this flag now that we are committed to convert all or
|
|
|
+ * part of the uninitialized extent to be an initialized
|
|
|
+ * extent. This is because we need to avoid the combination
|
|
|
+ * of BH_Unwritten and BH_Mapped flags being simultaneously
|
|
|
+ * set on the buffer_head.
|
|
|
+ */
|
|
|
+ clear_buffer_unwritten(bh);
|
|
|
+
|
|
|
/*
|
|
|
* New blocks allocate and/or writing to uninitialized extent
|
|
|
* will possibly result in updating i_data, so we take
|
|
@@ -2297,6 +2310,10 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
|
|
|
struct buffer_head *bh_result, int create)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
+ sector_t invalid_block = ~((sector_t) 0xffff);
|
|
|
+
|
|
|
+ if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es))
|
|
|
+ invalid_block = ~0;
|
|
|
|
|
|
BUG_ON(create == 0);
|
|
|
BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize);
|
|
@@ -2318,11 +2335,18 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
|
|
|
/* not enough space to reserve */
|
|
|
return ret;
|
|
|
|
|
|
- map_bh(bh_result, inode->i_sb, 0);
|
|
|
+ map_bh(bh_result, inode->i_sb, invalid_block);
|
|
|
set_buffer_new(bh_result);
|
|
|
set_buffer_delay(bh_result);
|
|
|
} else if (ret > 0) {
|
|
|
bh_result->b_size = (ret << inode->i_blkbits);
|
|
|
+ /*
|
|
|
+ * With sub-block writes into unwritten extents
|
|
|
+ * we also need to mark the buffer as new so that
|
|
|
+ * the unwritten parts of the buffer gets correctly zeroed.
|
|
|
+ */
|
|
|
+ if (buffer_unwritten(bh_result))
|
|
|
+ set_buffer_new(bh_result);
|
|
|
ret = 0;
|
|
|
}
|
|
|
|