From patchwork Wed Sep 20 06:35:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 9960893 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DF7CC60234 for ; Wed, 20 Sep 2017 06:35:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D115527D0C for ; Wed, 20 Sep 2017 06:35:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3E66284F4; Wed, 20 Sep 2017 06:35:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 14F3027D0C for ; Wed, 20 Sep 2017 06:35:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751529AbdITGfR (ORCPT ); Wed, 20 Sep 2017 02:35:17 -0400 Received: from mout.gmx.net ([212.227.17.20]:63471 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751095AbdITGfQ (ORCPT ); Wed, 20 Sep 2017 02:35:16 -0400 Received: from localhost.localdomain ([45.32.39.184]) by mail.gmx.com (mrgmx102 [212.227.17.174]) with ESMTPSA (Nemesis) id 0Lu2F0-1dDLiM3JZu-011RqL; Wed, 20 Sep 2017 08:35:09 +0200 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Cc: dsterba@suse.cz, rich@shroop.net, rrauenza@gmail.com, nborisov@suse.de Subject: [PATCH v2] btrfs: Make check for unaligned device size more gentle Date: Wed, 20 Sep 2017 15:35:03 +0900 Message-Id: <20170920063503.9304-1-quwenruo.btrfs@gmx.com> X-Mailer: git-send-email 2.13.3 X-Provags-ID: V03:K0:IT2RKexPZXO2M1ik/vFFfqseM+H/voZnlTnkEXZiOTECJd4eipv Q8nzbsEeJbX5kqdIqsi/ez0QLCWZl8u3OFBUX4ejrZhYeO4ktYlu5KXRvTmSUKP+lkYhsLy qwBc+TfSM8wVqRd5RBFrJSsdbu7u9BBkbL0c8jQb1MCinXX8DEUW7eMLrbDcViy7oZcyjx6 LAGl2tjF5/rEFsIop4pPw== X-UI-Out-Filterresults: notjunk:1; V01:K0:GsmLcKNkn38=:BMOR7KOXVCT0ud4XhhIt+i KyhMt0zqef9BxmQWmZk7XRSskvra5jM0CMkjJDxoK9ZbZV6PpNJzhAc3MBNGiHaUTYoDPEIY9 vmMxi90xCJSi17Gqd80HNfoeuzGBOsiKoPuGAtnlblSFMZ7J+CCZYPDI8oYq1F2esPD28K3Nt Q6tBrjqWMfwwKor3x0eCtKdg8BzmBCRu2dNug9L1GFFhfWUbgttyntktyIV1IT3Ulxfe5lMVc fPcSLe5mKB8jbBP59x5wBdDuXqpa/Amg3gB5z9BDMlUQ28Hy6Nzgu2bYsJSHuI0a/D4YnZsiu U5gbxPOyB9zLafFWUakSuulu0rNXmfWsi4J4qbmUFV26yUpaB7iSht+JFjiENrTNDWwW3lZXm C4J/GwrHRglFO3OBrySRWAPMAiN0omTIFpd9tw6Hg1H1wBrc1CnpIMM7yMD+qzAIQvLdeUL6m rlGYSUIBU9B2Gx6VW+pSpHiCSMxU+FUXIf05Itk8fM55UAUQN3gon79l79T+Ze6Qk5KwG9dBe +lQF9JeX0OE07fZEViHzOi0vKkeRhbW3ZilN9t9jcs+xOOrJRmB+16S4mRjQS/eE2ErZlnFUp S8Kn2LtsHgwHirfC3+o/av4t4VkvX0OoDRnJVjJUBE/eCrfgTBDa0fgO4nT/M9PyZqsWec0WF Pgrk/CBGFHRAtm2KX5Co/fDZ7lLvlkrOGKjFLRb7z2GYAiOjDaCHjjXGr/TyIUlr8vWiOL5NY q98qagoRCnTd13zkppv06+E33PnjbhtMWSF9LMJ+Hbsr5/v4Q5/q+p4Qq+f9cO9HLKJp3wSze pfXvYJY8bffNLkILRssVP+LqI9bww== Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Commit 7dfb8be11b5d ("btrfs: Round down values which are written for total_bytes_size") is fixing the unaligned device size caused by adding/shrinking device. It added a new WARN_ON() when device size is unaligned. This is fine for new device added to btrfs using v4.13 kernel, but not existing device whose total_bytes is already unaligned. And the WARN_ON() will get triggered every time a block group get created/removed on the unaligned device. This patch will only enable the WARN_ON() for CONFIG_BTRFS_DEBUG so developer won't miss any sanity check, but end user will not be troubled by tons of warning. And more useful fix will be output for end users. Reported-by: Rich Rauenzahn Fixes: 7dfb8be11b5d ("btrfs: Round down values which are written for total_bytes_size") Signed-off-by: Qu Wenruo --- changelog: v2: Use CONFIG_BTRFS_DEBUG to encapsulate the WARN_ON(), so end user won't see tons of kernel backtrace and developers can still catch the problem. --- fs/btrfs/ctree.h | 2 ++ fs/btrfs/volumes.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 5a8933da39a7..19b1a1789c52 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1562,7 +1562,9 @@ static inline void btrfs_set_device_total_bytes(struct extent_buffer *eb, { BUILD_BUG_ON(sizeof(u64) != sizeof(((struct btrfs_dev_item *)0))->total_bytes); +#ifdef CONFIG_BTRFS_DEBUG WARN_ON(!IS_ALIGNED(val, eb->fs_info->sectorsize)); +#endif btrfs_set_64(eb, s, offsetof(struct btrfs_dev_item, total_bytes), val); } diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 0e8f16c305df..afae25df6a8c 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -6472,15 +6472,23 @@ static int read_one_chunk(struct btrfs_fs_info *fs_info, struct btrfs_key *key, return 0; } -static void fill_device_from_item(struct extent_buffer *leaf, - struct btrfs_dev_item *dev_item, - struct btrfs_device *device) +static void fill_device_from_item(struct btrfs_fs_info *fs_info, + struct extent_buffer *leaf, + struct btrfs_dev_item *dev_item, + struct btrfs_device *device) { unsigned long ptr; device->devid = btrfs_device_id(leaf, dev_item); device->disk_total_bytes = btrfs_device_total_bytes(leaf, dev_item); device->total_bytes = device->disk_total_bytes; + if (!IS_ALIGNED(device->total_bytes, fs_info->sectorsize)) { + btrfs_warn(fs_info, + "devid %llu has unaligned total bytes %llu", + device->devid, device->disk_total_bytes); + btrfs_warn(fs_info, + "please shrink the device a little and resize back to fix it"); + } device->commit_total_bytes = device->disk_total_bytes; device->bytes_used = btrfs_device_bytes_used(leaf, dev_item); device->commit_bytes_used = device->bytes_used; @@ -6625,7 +6633,7 @@ static int read_one_dev(struct btrfs_fs_info *fs_info, return -EINVAL; } - fill_device_from_item(leaf, dev_item, device); + fill_device_from_item(fs_info, leaf, dev_item, device); device->in_fs_metadata = 1; if (device->writeable && !device->is_tgtdev_for_dev_replace) { device->fs_devices->total_rw_bytes += device->total_bytes;