Introduce --fix-dev-size option to fix device related problems. This repairing is also included in --repair, but considering the safety and potential affected users, it's better to provide a option to fix and only fix device size related problem to avoid full --repair.
Reported-by: Asif Youssuff <yoa...@gmail.com> Reported-by: Rich Rauenzahn <rraue...@gmail.com> Signed-off-by: Qu Wenruo <quwenruo.bt...@gmx.com> --- Documentation/btrfs-check.asciidoc | 23 +++++++++++++++++++++++ cmds-check.c | 28 +++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/Documentation/btrfs-check.asciidoc b/Documentation/btrfs-check.asciidoc index fbf48847ac25..e45c7a457bac 100644 --- a/Documentation/btrfs-check.asciidoc +++ b/Documentation/btrfs-check.asciidoc @@ -93,6 +93,29 @@ the entire free space cache. This option with 'v2' provides an alternative method of clearing the free space cache that doesn't require mounting the filesystem. +--fix-dev-size:: +From v4.14-rc kernels, a more restrict device size checker is introduced, while +old kernel doesn't strictly align its device size, so it may cause noisy kernel +warning for newer kernel, like: ++ +.... +WARNING: CPU: 3 PID: 439 at fs/btrfs/ctree.h:1559 btrfs_update_device+0x1c5/0x1d0 [btrfs] +.... ++ +And for some case where super block total device size may mismatch with all +devices, and the filesystem will be unable to be mounted, with kernel message +like: ++ +.... +BTRFS error (device sdb): super_total_bytes 92017859088384 mismatch with fs_devices total_rw_bytes 92017859094528 +.... ++ +This option will fix both problems by aligning all size of devices, and +re-calculating superblock total bytes. ++ +Although such repairing is included in *--repair* option, considering the +safety of *--repair*, this option is provided to suppress all other dangerous +repairing and only fix device sizes related problems. DANGEROUS OPTIONS ----------------- diff --git a/cmds-check.c b/cmds-check.c index 007781fa5d1b..fdb6d832eee1 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -11746,6 +11746,8 @@ out: return err; } +static int reset_devs_size(struct btrfs_fs_info *fs_info); + static int do_check_chunks_and_extents(struct btrfs_fs_info *fs_info) { int ret; @@ -11756,6 +11758,12 @@ static int do_check_chunks_and_extents(struct btrfs_fs_info *fs_info) ret = check_chunks_and_extents_v2(fs_info); else ret = check_chunks_and_extents(fs_info); + /* Also repair device sizes if needed */ + if (repair && !ret) { + ret = reset_devs_size(fs_info); + if (ret > 0) + ret = 0; + } return ret; } @@ -13088,6 +13096,8 @@ const char * const cmd_check_usage[] = { "-b|--backup use the first valid backup root copy", "--force skip mount checks, repair is not possible", "--repair try to repair the filesystem", + "--fix-dev-size repair device size related problem", + " will not trigger other repair", "--readonly run in read-only mode (default)", "--init-csum-tree create a new CRC tree", "--init-extent-tree create a new extent tree", @@ -13128,6 +13138,7 @@ int cmd_check(int argc, char **argv) int qgroups_repaired = 0; unsigned ctree_flags = OPEN_CTREE_EXCLUSIVE; int force = 0; + bool fix_dev_size = false; while(1) { int c; @@ -13135,7 +13146,7 @@ int cmd_check(int argc, char **argv) GETOPT_VAL_INIT_EXTENT, GETOPT_VAL_CHECK_CSUM, GETOPT_VAL_READONLY, GETOPT_VAL_CHUNK_TREE, GETOPT_VAL_MODE, GETOPT_VAL_CLEAR_SPACE_CACHE, - GETOPT_VAL_FORCE }; + GETOPT_VAL_FORCE, GETOPT_VAL_FIX_DEV_SIZE }; static const struct option long_options[] = { { "super", required_argument, NULL, 's' }, { "repair", no_argument, NULL, GETOPT_VAL_REPAIR }, @@ -13158,6 +13169,8 @@ int cmd_check(int argc, char **argv) { "clear-space-cache", required_argument, NULL, GETOPT_VAL_CLEAR_SPACE_CACHE}, { "force", no_argument, NULL, GETOPT_VAL_FORCE }, + { "fix-dev-size", no_argument, NULL, + GETOPT_VAL_FIX_DEV_SIZE }, { NULL, 0, NULL, 0} }; @@ -13245,6 +13258,11 @@ int cmd_check(int argc, char **argv) case GETOPT_VAL_FORCE: force = 1; break; + case GETOPT_VAL_FIX_DEV_SIZE: + fix_dev_size = true; + repair = 1; + ctree_flags |= OPEN_CTREE_WRITES; + break; } } @@ -13371,6 +13389,14 @@ int cmd_check(int argc, char **argv) report_qgroups(1); goto close_out; } + + if (fix_dev_size) { + ret = reset_devs_size(info); + if (ret > 0) + ret = 0; + err |= !!ret; + goto close_out; + } if (subvolid) { printf("Print extent state for subvolume %llu on %s\nUUID: %s\n", subvolid, argv[optind], uuidbuf); -- 2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html