From patchwork Tue May 31 02:46:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 9143171 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 5A25C60761 for ; Tue, 31 May 2016 02:46:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 512B62793B for ; Tue, 31 May 2016 02:46:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 45C512819C; Tue, 31 May 2016 02:46:34 +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 B6ACC2793B for ; Tue, 31 May 2016 02:46:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1162705AbcEaCqa (ORCPT ); Mon, 30 May 2016 22:46:30 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:17620 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1161732AbcEaCq3 (ORCPT ); Mon, 30 May 2016 22:46:29 -0400 X-IronPort-AV: E=Sophos;i="5.20,367,1444665600"; d="scan'208";a="563986" Received: from unknown (HELO cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 31 May 2016 10:46:04 +0800 Received: from adam-work.localdomain (unknown [10.167.226.34]) by cn.fujitsu.com (Postfix) with ESMTP id 1B6F24056403; Tue, 31 May 2016 10:46:02 +0800 (CST) From: Qu Wenruo To: dsterba@suse.com, linux-btrfs@vger.kernel.org Subject: [PATCH] btrfs-progs: convert: Add support to rollback new convert image Date: Tue, 31 May 2016 10:46:00 +0800 Message-Id: <20160531024600.11382-1-quwenruo@cn.fujitsu.com> X-Mailer: git-send-email 2.8.3 MIME-Version: 1.0 X-yoursite-MailScanner-ID: 1B6F24056403.AC073 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: quwenruo@cn.fujitsu.com 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 For new btrfs-convert, it's less restrict for metadata chunk allocation. While the may_rollback() function is still following the restrict 1:1 mapping check for all chunks, it will not allow some new convert image to be rolled back. Add new per extent check for new convert to allow it to be rolled back. Signed-off-by: Qu Wenruo --- btrfs-convert.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/btrfs-convert.c b/btrfs-convert.c index f776a4f..c28dae6 100644 --- a/btrfs-convert.c +++ b/btrfs-convert.c @@ -2315,6 +2315,65 @@ fail: return -1; } +/* + * Check if a non 1:1 mapped chunk can be rolled back. + * For new convert, it's OK while for old convert it's NG + */ +static int may_rollback_chunk(struct btrfs_fs_info *fs_info, u64 bytenr) +{ + struct btrfs_block_group_cache *bg; + struct btrfs_key key; + struct btrfs_path path; + struct btrfs_root *extent_root = fs_info->extent_root; + u64 bg_start; + u64 bg_end; + int ret; + + bg = btrfs_lookup_first_block_group(fs_info, bytenr); + if (!bg) + return -ENOENT; + bg_start = bg->key.objectid; + bg_end = bg->key.objectid + bg->key.offset; + + key.objectid = bg_end; + key.type = BTRFS_METADATA_ITEM_KEY; + key.offset = 0; + btrfs_init_path(&path); + + ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0); + if (ret < 0) + return ret; + + while (1) { + struct btrfs_extent_item *ei; + + ret = btrfs_previous_extent_item(extent_root, &path, bg_start); + if (ret > 0) { + ret = 0; + break; + } + if (ret < 0) + break; + + btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]); + if (key.type == BTRFS_METADATA_ITEM_KEY) + continue; + /* Now it's EXTENT_ITEM_KEY only */ + ei = btrfs_item_ptr(path.nodes[0], path.slots[0], + struct btrfs_extent_item); + /* + * Found data extent, means this is old convert + * must follow 1:1 mapping. + */ + if (btrfs_extent_flags(path.nodes[0], ei) & BTRFS_EXTENT_FLAG_DATA) { + ret = -EINVAL; + break; + } + } + btrfs_release_path(&path); + return ret; +} + static int may_rollback(struct btrfs_root *root) { struct btrfs_fs_info *info = root->fs_info; @@ -2351,8 +2410,26 @@ static int may_rollback(struct btrfs_root *root) physical = multi->stripes[0].physical; kfree(multi); - if (num_stripes != 1 || physical != bytenr) + if (num_stripes != 1) { + error("Num stripes for bytenr %llu is not 1\n", + bytenr); goto fail; + } + + /* + * Extra check for new convert, as metadata chunk from + * new convert is much more free than old convert, it doesn't + * need to do 1:1 mapping. + */ + if (physical != bytenr) { + /* + * Check if it's a metadata chunk and has only + * metadata extent + */ + ret = may_rollback_chunk(info, bytenr); + if (ret < 0) + goto fail; + } next: bytenr += length; if (bytenr >= total_bytes)