aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index dd32a2eacd0d..c2ca04e67a4f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3533,6 +3533,18 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
3533 offset; 3533 offset;
3534 } 3534 }
3535 3535
3536 if (offset & (sb->s_blocksize - 1) ||
3537 (offset + length) & (sb->s_blocksize - 1)) {
3538 /*
3539 * Attach jinode to inode for jbd2 if we do any zeroing of
3540 * partial block
3541 */
3542 ret = ext4_inode_attach_jinode(inode);
3543 if (ret < 0)
3544 goto out_mutex;
3545
3546 }
3547
3536 first_block_offset = round_up(offset, sb->s_blocksize); 3548 first_block_offset = round_up(offset, sb->s_blocksize);
3537 last_block_offset = round_down((offset + length), sb->s_blocksize) - 1; 3549 last_block_offset = round_down((offset + length), sb->s_blocksize) - 1;
3538 3550
@@ -3601,6 +3613,31 @@ out_mutex:
3601 return ret; 3613 return ret;
3602} 3614}
3603 3615
3616int ext4_inode_attach_jinode(struct inode *inode)
3617{
3618 struct ext4_inode_info *ei = EXT4_I(inode);
3619 struct jbd2_inode *jinode;
3620
3621 if (ei->jinode || !EXT4_SB(inode->i_sb)->s_journal)
3622 return 0;
3623
3624 jinode = jbd2_alloc_inode(GFP_KERNEL);
3625 spin_lock(&inode->i_lock);
3626 if (!ei->jinode) {
3627 if (!jinode) {
3628 spin_unlock(&inode->i_lock);
3629 return -ENOMEM;
3630 }
3631 ei->jinode = jinode;
3632 jbd2_journal_init_jbd_inode(ei->jinode, inode);
3633 jinode = NULL;
3634 }
3635 spin_unlock(&inode->i_lock);
3636 if (unlikely(jinode != NULL))
3637 jbd2_free_inode(jinode);
3638 return 0;
3639}
3640
3604/* 3641/*
3605 * ext4_truncate() 3642 * ext4_truncate()
3606 * 3643 *
@@ -3661,6 +3698,12 @@ void ext4_truncate(struct inode *inode)
3661 return; 3698 return;
3662 } 3699 }
3663 3700
3701 /* If we zero-out tail of the page, we have to create jinode for jbd2 */
3702 if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
3703 if (ext4_inode_attach_jinode(inode) < 0)
3704 return;
3705 }
3706
3664 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) 3707 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
3665 credits = ext4_writepage_trans_blocks(inode); 3708 credits = ext4_writepage_trans_blocks(inode);
3666 else 3709 else