From: Lukas Czerner Subject: [PATCH 2/5] ext4: Correctly handle EOFBLOCKS flag in ext4_ext_punch_hole Date: Wed, 21 Mar 2012 08:23:55 +0100 Message-ID: <1332314639-22875-2-git-send-email-lczerner@redhat.com> References: <1332314639-22875-1-git-send-email-lczerner@redhat.com> Cc: tytso@mit.edu, achender@linux.vnet.ibm.com, Lukas Czerner To: linux-ext4@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:46278 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751468Ab2CUHYQ (ORCPT ); Wed, 21 Mar 2012 03:24:16 -0400 In-Reply-To: <1332314639-22875-1-git-send-email-lczerner@redhat.com> Sender: linux-ext4-owner@vger.kernel.org List-ID: We have to clear the EOFBLOCK flag in the case that we just punched out all blocks allocated past the i_size, so that e2fsck does not compain about it. Even though we're going to remove EOFBLOCKS flag in the future we still have to handle it correctly for now as there are e2fsck versions out there which would complain about it. We can remove this after the new e2fsck code ignoring the EOFBLOCKS flag is common enough. Signed-off-by: Lukas Czerner --- fs/ext4/extents.c | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 06b0792..7b822c0 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4822,6 +4822,41 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length) up_write(&EXT4_I(inode)->i_data_sem); + /* + * This is fugly, but even though we're going to get rid of the + * EOFBLOCKS_LF in the future, we have to handle it correctly now + * because there are still versions of e2fsck out there which + * would scream otherwise. Once the new e2fsck code ignoring + * this flag is common enough this can be removed entirely. + */ + if (ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS)) { + struct ext4_ext_path *path; + ext4_lblk_t last_block; + + mutex_lock(&inode->i_mutex); + down_read(&EXT4_I(inode)->i_data_sem); + + last_block = inode->i_size >> EXT4_BLOCK_SIZE_BITS(sb); + + /* + * We have to check whether there is any extent past the + * i_size. If not, we probably punched that out, so we need + * to clear the EOFBLOCKS flag + */ + path = ext4_ext_find_extent(inode, last_block, NULL); + if (IS_ERR(path)) + err = PTR_ERR(path); + else { + err = check_eofblocks_fl(handle, inode, last_block, + path, 1); + ext4_ext_drop_refs(path); + kfree(path); + } + + up_read(&EXT4_I(inode)->i_data_sem); + mutex_unlock(&inode->i_mutex); + } + out: ext4_orphan_del(handle, inode); inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -- 1.7.4.4