int pextents);
extern int ext4_block_zero_eof(struct inode *inode, loff_t from, loff_t end);
extern int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart,
- loff_t length);
+ loff_t length, bool *did_zero);
extern vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf);
extern qsize_t *ext4_get_reserved_space(struct inode *inode);
extern int ext4_get_projid(struct inode *inode, kprojid_t *projid);
loff_t align_start, align_end, new_size = 0;
loff_t end = offset + len;
unsigned int blocksize = i_blocksize(inode);
+ bool partial_zeroed = false;
int ret, flags;
trace_ext4_zero_range(inode, offset, len, mode);
return ret;
/* Zero out partial block at the edges of the range */
- ret = ext4_zero_partial_blocks(inode, offset, len);
+ ret = ext4_zero_partial_blocks(inode, offset, len, &partial_zeroed);
if (ret)
return ret;
+ if (((file->f_flags & O_SYNC) || IS_SYNC(inode)) && partial_zeroed) {
+ ret = filemap_write_and_wait_range(inode->i_mapping, offset,
+ end - 1);
+ if (ret)
+ return ret;
+ }
handle = ext4_journal_start(inode, EXT4_HT_MISC, 1);
if (IS_ERR(handle)) {
return 0;
}
-int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, loff_t length)
+int ext4_zero_partial_blocks(struct inode *inode, loff_t lstart, loff_t length,
+ bool *did_zero)
{
struct super_block *sb = inode->i_sb;
unsigned partial_start, partial_end;
/* Handle partial zero within the single block */
if (start == end &&
(partial_start || (partial_end != sb->s_blocksize - 1))) {
- err = ext4_block_zero_range(inode, lstart, length, NULL, NULL);
+ err = ext4_block_zero_range(inode, lstart, length, did_zero,
+ NULL);
return err;
}
/* Handle partial zero out on the start of the range */
if (partial_start) {
err = ext4_block_zero_range(inode, lstart, sb->s_blocksize,
- NULL, NULL);
+ did_zero, NULL);
if (err)
return err;
}
/* Handle partial zero out on the end of the range */
if (partial_end != sb->s_blocksize - 1)
err = ext4_block_zero_range(inode, byte_end - partial_end,
- partial_end + 1, NULL, NULL);
+ partial_end + 1, did_zero, NULL);
return err;
}
loff_t end = offset + length;
handle_t *handle;
unsigned int credits;
+ bool partial_zeroed = false;
int ret;
trace_ext4_punch_hole(inode, offset, length, 0);
if (ret)
return ret;
- ret = ext4_zero_partial_blocks(inode, offset, length);
+ ret = ext4_zero_partial_blocks(inode, offset, length, &partial_zeroed);
if (ret)
return ret;
+ if (((file->f_flags & O_SYNC) || IS_SYNC(inode)) && partial_zeroed) {
+ ret = filemap_write_and_wait_range(inode->i_mapping, offset,
+ end - 1);
+ if (ret)
+ return ret;
+ }
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
credits = ext4_chunk_trans_extent(inode, 0);