| To: | linux-fsdevel@xxxxxxxxxxxxxxx |
|---|---|
| Subject: | [PATCH 2/2] ext4: Fix hole punching for files with indirect blocks |
| From: | Jan Kara <jack@xxxxxxx> |
| Date: | Fri, 10 Oct 2014 16:23:45 +0200 |
| Cc: | linux-ext4@xxxxxxxxxxxxxxx, Dave Chinner <david@xxxxxxxxxxxxx>, xfs@xxxxxxxxxxx, cluster-devel@xxxxxxxxxx, Steven Whitehouse <swhiteho@xxxxxxxxxx>, Mark Fasheh <mfasheh@xxxxxxxx>, Joel Becker <jlbec@xxxxxxxxxxxx>, ocfs2-devel@xxxxxxxxxxxxxx, reiserfs-devel@xxxxxxxxxxxxxxx, Jeff Mahoney <jeffm@xxxxxxx>, Dave Kleikamp <shaggy@xxxxxxxxxx>, jfs-discussion@xxxxxxxxxxxxxxxxxxxxx, tytso@xxxxxxx, viro@xxxxxxxxxxxxxxxxxx, Jan Kara <jack@xxxxxxx>, stable@xxxxxxxxxxxxxxx |
| Delivered-to: | xfs@xxxxxxxxxxx |
| In-reply-to: | <1412951028-4085-1-git-send-email-jack@xxxxxxx> |
| References: | <1412951028-4085-1-git-send-email-jack@xxxxxxx> |
Hole punching code for files with indirect blocks wrongly computed
number of blocks which need to be cleared when traversing the indirect
block tree. That could result in punching more blocks than actually
requested and thus effectively cause a data loss. For example:
fallocate -n -p 10240000 4096
will punch the range 10240000 - 12632064 instead of the range 1024000 -
10244096. Fix the calculation.
CC: stable@xxxxxxxxxxxxxxx
Fixes: 8bad6fc813a3a5300f51369c39d315679fd88c72
Signed-off-by: Jan Kara <jack@xxxxxxx>
---
fs/ext4/indirect.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 9d381707a6fc..771949c82715 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -1310,16 +1310,24 @@ static int free_hole_blocks(handle_t *handle, struct
inode *inode,
blk = *i_data;
if (level > 0) {
ext4_lblk_t first2;
+ ext4_lblk_t count2;
+
bh = sb_bread(inode->i_sb, le32_to_cpu(blk));
if (!bh) {
EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk),
"Read failure");
return -EIO;
}
- first2 = (first > offset) ? first - offset : 0;
+ if (first > offset) {
+ first2 = first - offset;
+ count2 = count;
+ } else {
+ first2 = 0;
+ count2 = count - (offset - first);
+ }
ret = free_hole_blocks(handle, inode, bh,
(__le32 *)bh->b_data, level - 1,
- first2, count - offset,
+ first2, count2,
inode->i_sb->s_blocksize >> 2);
if (ret) {
brelse(bh);
--
1.8.1.4
|
| Previous by Date: | [PATCH 2/2] printk: Debug patch 2, Jan Kara |
|---|---|
| Next by Date: | [PATCH 2/2] jbd2: Simplify calling convention around __jbd2_journal_clean_checkpoint_list, Jan Kara |
| Previous by Thread: | [PATCH 2/2] printk: Debug patch 2, Jan Kara |
| Next by Thread: | [PATCH 2/2] jbd2: Simplify calling convention around __jbd2_journal_clean_checkpoint_list, Jan Kara |
| Indexes: | [Date] [Thread] [Top] [All Lists] |