diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 43 |
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 | ||
3616 | int 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 |