From patchwork Tue Jul 25 20:54:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Mahoney X-Patchwork-Id: 9863561 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 64CF1600F5 for ; Tue, 25 Jul 2017 20:54:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4FF36286F7 for ; Tue, 25 Jul 2017 20:54:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 44F4528701; Tue, 25 Jul 2017 20:54:21 +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,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 B4208286F7 for ; Tue, 25 Jul 2017 20:54:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751976AbdGYUyP (ORCPT ); Tue, 25 Jul 2017 16:54:15 -0400 Received: from mx2.suse.de ([195.135.220.15]:45219 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752525AbdGYUyI (ORCPT ); Tue, 25 Jul 2017 16:54:08 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id D4D13AE7C; Tue, 25 Jul 2017 20:54:06 +0000 (UTC) Received: by starscream.home.jeffm.io (Postfix, from userid 1000) id CB5378147A; Tue, 25 Jul 2017 16:54:45 -0400 (EDT) From: jeffm@suse.com To: linux-btrfs@vger.kernel.org Cc: Jeff Mahoney , Qu Wenruo Subject: [PATCH 1/3] btrfs-progs: convert: properly handle reserved ranges while iterating files Date: Tue, 25 Jul 2017 16:54:41 -0400 Message-Id: <20170725205443.29874-1-jeffm@suse.com> X-Mailer: git-send-email 2.11.0 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 From: Jeff Mahoney Commit 522ef705e38 (btrfs-progs: convert: Introduce function to calculate the available space) changed how we handle migrating file data so that we never have btrfs space associated with the reserved ranges. This works pretty well and when we iterate over the file blocks, the associations are redirected to the migrated locations. This commit missed the case in block_iterate_proc where we just check for intersection with a superblock location before looking up a block group. intersect_with_sb checks to see if the range intersects with a stripe containing a superblock but, in fact, we've reserved the full 0-1MB range at the start of the disk. So a file block located at e.g. 160kB will fall in the reserved region but won't be excepted in block_iterate_block. We ultimately hit a BUG_ON when we fail to look up the block group for that location. This is reproducible using convert-tests/003-ext4-basic. The fix is to have intersect_with_sb and block_iterate_proc understand the full size of the reserved ranges. Since we use the range to determine the boundary for the block iterator, let's just return the boundary. 0 isn't a valid boundary and means that we proceed normally with block group lookup. Cc: Qu Wenruo Signed-off-by: Jeff Mahoney Reviewed-by: Qu Wenruo --- convert/source-fs.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/convert/source-fs.c b/convert/source-fs.c index 80e4e41..09f6995 100644 --- a/convert/source-fs.c +++ b/convert/source-fs.c @@ -28,18 +28,16 @@ const struct simple_range btrfs_reserved_ranges[3] = { { BTRFS_SB_MIRROR_OFFSET(2), SZ_64K } }; -static int intersect_with_sb(u64 bytenr, u64 num_bytes) +static u64 intersect_with_reserved(u64 bytenr, u64 num_bytes) { int i; - u64 offset; - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { - offset = btrfs_sb_offset(i); - offset &= ~((u64)BTRFS_STRIPE_LEN - 1); + for (i = 0; i < ARRAY_SIZE(btrfs_reserved_ranges); i++) { + const struct simple_range *range = &btrfs_reserved_ranges[i]; - if (bytenr < offset + BTRFS_STRIPE_LEN && - bytenr + num_bytes > offset) - return 1; + if (bytenr < range_end(range) && + bytenr + num_bytes >= range->start) + return range_end(range); } return 0; } @@ -64,14 +62,14 @@ int block_iterate_proc(u64 disk_block, u64 file_block, struct blk_iterate_data *idata) { int ret = 0; - int sb_region; + u64 reserved_boundary; int do_barrier; struct btrfs_root *root = idata->root; struct btrfs_block_group_cache *cache; u64 bytenr = disk_block * root->sectorsize; - sb_region = intersect_with_sb(bytenr, root->sectorsize); - do_barrier = sb_region || disk_block >= idata->boundary; + reserved_boundary = intersect_with_reserved(bytenr, root->sectorsize); + do_barrier = reserved_boundary || disk_block >= idata->boundary; if ((idata->num_blocks > 0 && do_barrier) || (file_block > idata->first_block + idata->num_blocks) || (disk_block != idata->disk_block + idata->num_blocks)) { @@ -91,9 +89,8 @@ int block_iterate_proc(u64 disk_block, u64 file_block, goto fail; } - if (sb_region) { - bytenr += BTRFS_STRIPE_LEN - 1; - bytenr &= ~((u64)BTRFS_STRIPE_LEN - 1); + if (reserved_boundary) { + bytenr = reserved_boundary; } else { cache = btrfs_lookup_block_group(root->fs_info, bytenr); BUG_ON(!cache);