From patchwork Sat Apr 14 02:33:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Bo X-Patchwork-Id: 898127 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.alibaba.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40NJd04JSCz9s0t for ; Sat, 14 Apr 2018 12:34:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751050AbeDNCeZ (ORCPT ); Fri, 13 Apr 2018 22:34:25 -0400 Received: from out30-131.freemail.mail.aliyun.com ([115.124.30.131]:57143 "EHLO out30-131.freemail.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750904AbeDNCeZ (ORCPT ); Fri, 13 Apr 2018 22:34:25 -0400 X-Alimail-AntiSpam: AC=PASS; BC=-1|-1; BR=01201311R121e4; CH=green; FP=0|-1|-1|-1|0|-1|-1|-1; HT=e01f04452; MF=bo.liu@linux.alibaba.com; NM=1; PH=DS; RN=1; SR=0; TI=SMTPD_---0T.8zoqM_1523673262; Received: from localhost(mailfrom:bo.liu@linux.alibaba.com fp:SMTPD_---0T.8zoqM_1523673262) by smtp.aliyun-inc.com(127.0.0.1); Sat, 14 Apr 2018 10:34:22 +0800 From: Liu Bo To: linux-ext4@vger.kernel.org Subject: [PATCH] Ext4: Set BBITMAP_CORRUPT_BIT when failing to read the allocation bitmap Date: Sat, 14 Apr 2018 10:33:57 +0800 Message-Id: <1523673237-112405-1-git-send-email-bo.liu@linux.alibaba.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org With failing to read the allocation block bitmap due to disk read errors, ext4 might end up with in-memory buddy bitmap being inconsistent with on-disk block bitmap. And the behavior would be unpredictable, one of the situations I got was [943102.751298] ------------[ cut here ]------------ [943102.751299] kernel BUG at fs/ext4/mballoc.c:1911! [943102.751300] invalid opcode: 0000 [#1] SMP ... [943102.751353] Call Trace: [943102.751363] [] ext4_mb_regular_allocator+0x356/0x460 [ext4] [943102.751371] [] ext4_mb_new_blocks+0x5ec/0xaf0 [ext4] [943102.751379] [] ? __read_extent_tree_block+0x5d/0x1f0 [ext4] [943102.751386] [] ? ext4_find_extent+0x143/0x2d0 [ext4] [943102.751394] [] ext4_ext_map_blocks+0xb5e/0xf30 [ext4] [943102.751397] [] ? node_dirty_ok+0x12c/0x170 [943102.751403] [] ext4_map_blocks+0x172/0x600 [ext4] [943102.751406] [] ? alloc_buffer_head+0x21/0x60 [943102.751407] [] ? mem_cgroup_commit_charge+0x91/0x530 [943102.751413] [] _ext4_get_block+0x92/0x100 [ext4] [943102.751419] [] ext4_get_block+0x16/0x20 [ext4] [943102.751420] [] __block_write_begin_int+0x197/0x5e0 [943102.751425] [] ? _ext4_get_block+0x100/0x100 [ext4] [943102.751432] [] ? ext4_write_begin+0x126/0x5b0 [ext4] [943102.751433] [] __block_write_begin+0x11/0x20 [943102.751439] [] ext4_write_begin+0x1ac/0x5b0 [ext4] [943102.751446] [] ? __ext4_journal_stop+0x3d/0xa0 [ext4] [943102.751449] [] generic_perform_write+0xc8/0x1c0 [943102.751451] [] ? file_update_time+0x5e/0x110 [943102.751452] [] __generic_file_write_iter+0x185/0x1d0 [943102.751458] [] ext4_file_write_iter+0x8b/0x380 [ext4] [943102.751460] [] ? vfs_getattr_nosec+0x29/0x40 [943102.751462] [] ? cp_new_stat+0x14f/0x180 [943102.751463] [] __vfs_write+0xe5/0x160 [943102.751464] [] vfs_write+0xb5/0x1a0 [943102.751465] [] SyS_write+0x55/0xc0 [943102.751468] [] entry_SYSCALL_64_fastpath+0x1a/0xc5 [943102.751476] Code: 39 44 24 3c 75 27 49 8b 85 60 <0f> 0b 0f 0b e8 3b 57 b5 e0 90 66 [943102.751484] RIP [] ext4_mb_simple_scan_group+0x14c/0x160 [ext4] [943102.751484] RSP To avoid the above, EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT should be set in order to prevent any further allocations from this block group. Suggested-by: Theodore Y. Ts'o Signed-off-by: Liu Bo --- fs/ext4/balloc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index f9b3e0a83526..f0a5ed3df5fa 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -499,9 +499,19 @@ int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group, return -EFSCORRUPTED; wait_on_buffer(bh); if (!buffer_uptodate(bh)) { + struct ext4_group_info *grp = + ext4_get_group_info(sb, block_group); + struct ext4_sb_info *sbi = EXT4_SB(sb); + ext4_error(sb, "Cannot read block bitmap - " "block_group = %u, block_bitmap = %llu", block_group, (unsigned long long) bh->b_blocknr); + + if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) + percpu_counter_sub(&sbi->s_freeclusters_counter, + grp->bb_free); + set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); + return -EIO; } clear_buffer_new(bh);