From patchwork Fri May 13 06:36:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Czerner X-Patchwork-Id: 95440 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 0F9DDB6EF1 for ; Fri, 13 May 2011 16:37:07 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754226Ab1EMGhF (ORCPT ); Fri, 13 May 2011 02:37:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:18409 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751650Ab1EMGhE (ORCPT ); Fri, 13 May 2011 02:37:04 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p4D6b2KH016464 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 May 2011 02:37:02 -0400 Received: from dhcp-27-109.brq.redhat.com (dhcp-1-233.brq.redhat.com [10.34.1.233]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p4D6axR5003076; Fri, 13 May 2011 02:37:00 -0400 From: Lukas Czerner To: linux-ext4@vger.kernel.org Cc: tytso@mit.edu, k-mio@sx.jp.nec.com, Lukas Czerner Subject: [PATCH] ext4: invalidate gap cache when writing extents last block Date: Fri, 13 May 2011 08:36:56 +0200 Message-Id: <1305268616-5167-1-git-send-email-lczerner@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Kazuya Mio reported that he was able to hit BUG_ON(next == lblock) in ext4_ext_put_gap_in_cache() while creating a sparse file in extent format and fill the tail of file up to its end. We will hit the BUG_ON when we write the last block (2^32-1) into the sparse file. That is because due to defensive programming we planted a lot of BUG_ON's to prevent the length of the gap cache to be zero, but in this case it actually will be zero, because there will be no gap at the end of the file. We could fix that as Kazuya Mio suggested by lowering the max file size of extent format file by one block. But I do not think this is necessary and we should rather fix the BUG_ON's to allow invalidating the gap cache by setting its lenght to zero and this is what this commit is doing. The bug which this commit fixes can be reproduced as follows: dd if=/dev/zero of=/mnt/mp1/file bs= count=1 seek=$((2**32-2)) sync dd if=/dev/zero of=/mnt/mp1/file bs= count=1 seek=$((2**32-1)) Reported-by: Kazuya Mio Signed-off-by: Lukas Czerner --- fs/ext4/extents.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 4890d6f..779ca49 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -1944,7 +1944,6 @@ ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block, __u32 len, ext4_fsblk_t start) { struct ext4_ext_cache *cex; - BUG_ON(len == 0); spin_lock(&EXT4_I(inode)->i_block_reservation_lock); cex = &EXT4_I(inode)->i_cached_extent; cex->ec_block = block; @@ -1991,7 +1990,7 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, le32_to_cpu(ex->ee_block), ext4_ext_get_actual_len(ex), block); - BUG_ON(next == lblock); + BUG_ON((next == lblock) && (next != EXT_MAX_BLOCK)); len = next - lblock; } else { lblock = len = 0;