From patchwork Tue May 29 11:45:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 922019 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FJ9rfvJZ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40wBkB0Fhcz9s0W for ; Tue, 29 May 2018 21:45:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933376AbeE2Lph (ORCPT ); Tue, 29 May 2018 07:45:37 -0400 Received: from mail-pl0-f68.google.com ([209.85.160.68]:44833 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933367AbeE2Lpd (ORCPT ); Tue, 29 May 2018 07:45:33 -0400 Received: by mail-pl0-f68.google.com with SMTP id z9-v6so5458374plk.11 for ; Tue, 29 May 2018 04:45:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/0D2w79GJqvY4Ra2pkgHzwDFFdnHkmVDA7omofo6dzA=; b=FJ9rfvJZXIru+GugiXMvICAgUMFV+cWcJ43I+h+JBUEcaUL4o1rqqaFK5RRGywFrhY B0300xbNPYGm36ubQEZZM7g/r3mMgrNJwpRGWxzYjp0tm/IK4ZAub5e2ff4fLixAerl5 AZSWM08ZdqRVo8fau9WYuzWWzoJzNljDPIJ7l6qIcDjOcUBOyBm8isbo1KbccN/7Mvl9 adhe6pxTm43JNvUu+xtk2JZoN11FMRCyJnJ5crEQRnOthoxWpNjn3PMC+xV+p4yzA3Kf vPkOa7l/q0TFV8JHUMuUMc9YU0fI859shTDYNuJUuw0n9MfxskJF/8lzTwD8zpvM4d+f FJyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/0D2w79GJqvY4Ra2pkgHzwDFFdnHkmVDA7omofo6dzA=; b=XgRkLNg2LBCB9HYY/V5CKmoJyRM/gDPqXWrF5AZgonm84+zUhD7qmX7X8gbXG4AEQt 0ZpMsK/PS1VBdT1i7BXuvXXsWnLaLOY9xBgwvVGIwqow6I/f1nTy3JIk3YRzoqOtsA5f fm/DKUyeUg7YJGilExw7/ybmBPmLyNyKU04NcqQe9iQ4uVcE7ic3/7gEtjtkivlepyu7 Lc13cl+Sq7S1mE4aai0ROH4exVGB9/midknN7w2yMqXNGwFGaQ/vTw/O20DgsNkcvhNH qurvn8Hz/TqFgtGxi74jjsoCVpcQKQr3TCwAJLCvmxOxa/HPDuLzD7RbHwBa3KMAkRw2 iu2g== X-Gm-Message-State: ALKqPwfOG2/CGG1D3fG9RgTteZL40h+AHcuU8EP9Z6UEcRVdNI0+7A3w wRyRU6BjDUvkyAaXpS4rBGmpLw== X-Google-Smtp-Source: AB8JxZpZs0t3aosQ8axIGXkBBOZD44QZa0QA5rf3P4K5k23mcku7z2e4cvDCmO2WTmF+Xf9c8tWKdw== X-Received: by 2002:a17:902:d882:: with SMTP id b2-v6mr16728007plz.220.1527594332922; Tue, 29 May 2018 04:45:32 -0700 (PDT) Received: from localhost.localdomain (fs276ec80e.tkyc203.ap.nuro.jp. [39.110.200.14]) by smtp.gmail.com with ESMTPSA id s16-v6sm51226151pfm.114.2018.05.29.04.45.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 May 2018 04:45:32 -0700 (PDT) From: Wang Shilong X-Google-Original-From: Wang Shilong To: linux-ext4@vger.kernel.org Cc: andreas.dilger@intel.com, sihara@ddn.com, wshilong@ddn.com Subject: [PATCH v2 5/5] ext4: add suppport to make bitmaps corruptions nonfatal Date: Tue, 29 May 2018 20:45:17 +0900 Message-Id: <1527594317-9214-5-git-send-email-wshilong1991@gmail.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1527594317-9214-1-git-send-email-wshilong1991@gmail.com> References: <1527594317-9214-1-git-send-email-wshilong1991@gmail.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Wang Shilong Originally, we saw bitmaps corruptions on Lustre server, which could be ext4 bugs or disk corruptions, but currently ext4 use ext4_error() for this which make filesystem RO in default. Ext4 have handled bitmaps corruptions very well, use corrupted bit to isolate erros and prevent us any further allocations to this block group, add an mount option 'bitmaps=warn' for this which will record error state to superblock, and next offline e2fsck will fix inconsitency problems, this gurantee our Clusters usable with minimal risk. Suggested-by: Andreas Dilger Signed-off-by: Wang Shilong Reviewed-by: Andreas Dilger --- v1->v2: add mount option to control, don't leak fatal error that is not related to bitmap corruptions --- fs/ext4/balloc.c | 6 ++++-- fs/ext4/ext4.h | 27 +++++++++++++++++++++------ fs/ext4/mballoc.c | 45 +++++++++++++++++++++++---------------------- fs/ext4/super.c | 20 ++++++++++++++------ 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 5fe63ff..bef6ae8 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -451,8 +451,10 @@ struct buffer_head * ext4_unlock_group(sb, block_group); unlock_buffer(bh); if (err) { - ext4_error(sb, "Failed to init block bitmap for group " - "%u: %d", block_group, err); + if (!EXT4_MB_GRP_BBITMAP_CORRUPT( + ext4_get_group_info(sb, block_group))) + ext4_error(sb, "Failed to init block bitmap for group " + "%u: %d", block_group, err); goto out; } goto verify; diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 26f8c12..96c5c1c 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1113,6 +1113,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ #define EXT4_MOUNT_DISCARD 0x40000000 /* Issue DISCARD requests */ #define EXT4_MOUNT_INIT_INODE_TABLE 0x80000000 /* Initialize uninitialized itables */ +#define EXT4_MOUNT_BITMAPS_WARN 0x100000000 /* warn on bitmaps corruptions */ /* * Mount flags set either automatically (could not be set by mount option) @@ -1338,7 +1339,7 @@ struct ext4_sb_info { struct buffer_head * s_sbh; /* Buffer containing the super block */ struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */ struct buffer_head **s_group_desc; - unsigned int s_mount_opt; + unsigned long long s_mount_opt; unsigned int s_mount_opt2; unsigned int s_mount_flags; unsigned int s_def_mount_opt; @@ -2563,6 +2564,8 @@ void __ext4_grp_locked_error(const char *, unsigned int, struct super_block *, ext4_group_t, unsigned long, ext4_fsblk_t, unsigned int, const char *, ...); +void save_error_info(struct super_block *sb, const char *func, + unsigned int line); #define EXT4_ERROR_INODE(inode, fmt, a...) \ ext4_error_inode((inode), __func__, __LINE__, 0, (fmt), ## a) @@ -2598,10 +2601,17 @@ void __ext4_grp_locked_error(const char *, unsigned int, do { \ int ret; \ ret = __ext4_mark_group_bitmap_corrupted(sb, group, \ - flags); \ - if (ret) \ - __ext4_error(sb, __func__, __LINE__, \ - fmt, ##__VA_ARGS__); \ + flags); \ + if (ret) { \ + if (test_opt(sb, BITMAPS_WARN)) { \ + __ext4_warning(sb, __func__, __LINE__, \ + fmt, ##__VA_ARGS__); \ + save_error_info(sb, __func__, __LINE__);\ + } else { \ + __ext4_error(sb, __func__, __LINE__, \ + fmt, ##__VA_ARGS__); \ + } \ + } \ } while (0) @@ -2656,7 +2666,12 @@ void __ext4_grp_locked_error(const char *, unsigned int, flags); \ if (ret) { \ no_printk(fmt, ##__VA_ARGS__); \ - __ext4_error(sb, "", 0, " "); \ + if (test_opt(sb, BITMAPS_WARN) { \ + __ext4_warning(sb, "", 0, " "); \ + save_error_info(sb, __func__, __LINE__);\ + } else { \ + __ext4_error(sb, "", 0, " "); \ + } \ } \ } while (0) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 3680623..1ee3138 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3907,15 +3907,16 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) bitmap_bh = ext4_read_block_bitmap(sb, group); if (IS_ERR(bitmap_bh)) { err = PTR_ERR(bitmap_bh); - ext4_error(sb, "Error %d reading block bitmap for %u", - err, group); return 0; } err = ext4_mb_load_buddy(sb, group, &e4b); if (err) { - ext4_warning(sb, "Error %d loading buddy information for %u", - err, group); + if (!EXT4_MB_GRP_BBITMAP_CORRUPT( + ext4_get_group_info(sb, group))) + ext4_warning(sb, + "Error %d loading buddy information for %u", + err, group); put_bh(bitmap_bh); return 0; } @@ -4075,16 +4076,17 @@ void ext4_discard_preallocations(struct inode *inode) err = ext4_mb_load_buddy_gfp(sb, group, &e4b, GFP_NOFS|__GFP_NOFAIL); if (err) { - ext4_error(sb, "Error %d loading buddy information for %u", - err, group); + if (!EXT4_MB_GRP_BBITMAP_CORRUPT( + ext4_get_group_info(sb, group))) + ext4_error(sb, + "Error %d loading buddy information for %u", + err, group); continue; } bitmap_bh = ext4_read_block_bitmap(sb, group); if (IS_ERR(bitmap_bh)) { err = PTR_ERR(bitmap_bh); - ext4_error(sb, "Error %d reading block bitmap for %u", - err, group); ext4_mb_unload_buddy(&e4b); continue; } @@ -4338,8 +4340,10 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) err = ext4_mb_load_buddy_gfp(sb, group, &e4b, GFP_NOFS|__GFP_NOFAIL); if (err) { - ext4_error(sb, "Error %d loading buddy information for %u", - err, group); + if (!EXT4_MB_GRP_BBITMAP_CORRUPT( + ext4_get_group_info(sb, group))) + ext4_error(sb, "Error %d loading buddy information for %u", + err, group); continue; } ext4_lock_group(sb, group); @@ -4819,11 +4823,8 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, } count_clusters = EXT4_NUM_B2C(sbi, count); bitmap_bh = ext4_read_block_bitmap(sb, block_group); - if (IS_ERR(bitmap_bh)) { - err = PTR_ERR(bitmap_bh); - bitmap_bh = NULL; - goto error_return; - } + if (IS_ERR(bitmap_bh)) + return; gdp = ext4_get_group_desc(sb, block_group, &gd_bh); if (!gdp) { err = -EIO; @@ -5001,11 +5002,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, } bitmap_bh = ext4_read_block_bitmap(sb, block_group); - if (IS_ERR(bitmap_bh)) { - err = PTR_ERR(bitmap_bh); - bitmap_bh = NULL; - goto error_return; - } + if (IS_ERR(bitmap_bh)) + return PTR_ERR(bitmap_bh); desc = ext4_get_group_desc(sb, block_group, &gd_bh); if (!desc) { @@ -5168,8 +5166,11 @@ static int ext4_trim_extent(struct super_block *sb, int start, int count, ret = ext4_mb_load_buddy(sb, group, &e4b); if (ret) { - ext4_warning(sb, "Error %d loading buddy information for %u", - ret, group); + if (!EXT4_MB_GRP_BBITMAP_CORRUPT( + ext4_get_group_info(sb, group))) + ext4_warning(sb, + "Error %d loading buddy information for %u", + ret, group); return ret; } bitmap = e4b.bd_bitmap; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 9f88991..63f40ae 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -342,8 +342,8 @@ static void __save_error_info(struct super_block *sb, const char *func, le32_add_cpu(&es->s_error_count, 1); } -static void save_error_info(struct super_block *sb, const char *func, - unsigned int line) +void save_error_info(struct super_block *sb, const char *func, + unsigned int line) { __save_error_info(sb, func, line); ext4_commit_super(sb, 1); @@ -743,7 +743,8 @@ void __ext4_grp_locked_error(const char *function, unsigned int line, if (flags) __ext4_mark_group_bitmap_corrupted(sb, grp, flags); - if (test_opt(sb, ERRORS_CONT)) { + if (test_opt(sb, ERRORS_CONT) || + (flags && test_opt(sb, BITMAPS_WARN))) { ext4_commit_super(sb, 0); return; } @@ -1373,7 +1374,8 @@ static struct dquot **ext4_get_dquots(struct inode *inode) }; enum { - Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, + Opt_bsd_df, Opt_minix_df, Opt_bitmaps_warn, + Opt_bitmaps_err, Opt_grpid, Opt_nogrpid, Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, Opt_nouid32, Opt_debug, Opt_removed, Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, @@ -1398,6 +1400,8 @@ enum { static const match_table_t tokens = { {Opt_bsd_df, "bsddf"}, {Opt_minix_df, "minixdf"}, + {Opt_bitmaps_warn, "bitmaps=warn"}, + {Opt_bitmaps_err, "bitmaps=error"}, {Opt_grpid, "grpid"}, {Opt_grpid, "bsdgroups"}, {Opt_nogrpid, "nogrpid"}, @@ -1598,11 +1602,13 @@ static int clear_qf_name(struct super_block *sb, int qtype) static const struct mount_opts { int token; - int mount_opt; + unsigned long long mount_opt; int flags; } ext4_mount_opts[] = { {Opt_minix_df, EXT4_MOUNT_MINIX_DF, MOPT_SET}, {Opt_bsd_df, EXT4_MOUNT_MINIX_DF, MOPT_CLEAR}, + {Opt_bitmaps_warn, EXT4_MOUNT_BITMAPS_WARN, MOPT_SET}, + {Opt_bitmaps_err, EXT4_MOUNT_BITMAPS_WARN, MOPT_CLEAR}, {Opt_grpid, EXT4_MOUNT_GRPID, MOPT_SET}, {Opt_nogrpid, EXT4_MOUNT_GRPID, MOPT_CLEAR}, {Opt_block_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_SET}, @@ -2099,6 +2105,8 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb, SEQ_OPTS_PUTS("errors=continue"); if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC) SEQ_OPTS_PUTS("errors=panic"); + if (test_opt(sb, BITMAPS_WARN)) + SEQ_OPTS_PUTS("bitmaps=warn"); if (nodefs || sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) SEQ_OPTS_PRINT("commit=%lu", sbi->s_commit_interval / HZ); if (nodefs || sbi->s_min_batch_time != EXT4_DEF_MIN_BATCH_TIME) @@ -2197,7 +2205,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, done: if (test_opt(sb, DEBUG)) printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, " - "bpg=%lu, ipg=%lu, mo=%04x, mo2=%04x]\n", + "bpg=%lu, ipg=%lu, mo=%04llx, mo2=%04x]\n", sb->s_blocksize, sbi->s_groups_count, EXT4_BLOCKS_PER_GROUP(sb),