From patchwork Tue Dec 1 07:11:39 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 7733331 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 67816BEEE5 for ; Tue, 1 Dec 2015 07:14:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6E94A2045A for ; Tue, 1 Dec 2015 07:14:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 180A6206AC for ; Tue, 1 Dec 2015 07:14:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755332AbbLAHOi (ORCPT ); Tue, 1 Dec 2015 02:14:38 -0500 Received: from cn.fujitsu.com ([59.151.112.132]:15517 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1755236AbbLAHOe (ORCPT ); Tue, 1 Dec 2015 02:14:34 -0500 X-IronPort-AV: E=Sophos;i="5.20,346,1444665600"; d="scan'208";a="1025431" Received: from unknown (HELO cn.fujitsu.com) ([10.167.250.3]) by heian.cn.fujitsu.com with ESMTP; 01 Dec 2015 15:14:22 +0800 Received: from localhost.localdomain (unknown [10.167.226.34]) by cn.fujitsu.com (Postfix) with ESMTP id 6463240444DD for ; Tue, 1 Dec 2015 15:14:12 +0800 (CST) From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 19/25] btrfs-progs: convert: Introduce function to migrate reserved ranges Date: Tue, 1 Dec 2015 15:11:39 +0800 Message-Id: <1448953905-28673-20-git-send-email-quwenruo@cn.fujitsu.com> X-Mailer: git-send-email 2.6.2 In-Reply-To: <1448953905-28673-1-git-send-email-quwenruo@cn.fujitsu.com> References: <1448953905-28673-1-git-send-email-quwenruo@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-Information: Please contact the ISP for more information X-yoursite-MailScanner-ID: 6463240444DD.AA2E0 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: quwenruo@cn.fujitsu.com X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce new function, migrate_reserved_ranges() to migrate used fs data in btrfs reserved space. Unlike old implement, which will need to relocate all the complicated csum and reference relocation, previous patches already ensure such reserved ranges won't be allocated. So here we only need copy these data out and create new extent/csum/reference. Signed-off-by: Qu Wenruo --- btrfs-convert.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/btrfs-convert.c b/btrfs-convert.c index 16e2309..f6126db 100644 --- a/btrfs-convert.c +++ b/btrfs-convert.c @@ -1679,6 +1679,123 @@ static int create_image_file_range_v2(struct btrfs_trans_handle *trans, return ret; } + +/* + * Relocate old fs data in one reserved ranges + * + * Since all old fs data in reserved range is not covered by any chunk nor + * data extent, we don't need to handle any reference but add new + * extent/reference, which makes codes more clear + */ +static int migrate_one_reserved_range(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct cache_tree *used, + struct btrfs_inode_item *inode, int fd, + u64 ino, u64 start, u64 len, int datacsum) +{ + u64 cur_off = start; + u64 cur_len = len; + struct cache_extent *cache; + struct btrfs_key key; + struct extent_buffer *eb; + int ret = 0; + + while (cur_off < start + len) { + cache = lookup_cache_extent(used, cur_off, cur_len); + if (!cache) + break; + cur_off = max(cache->start, cur_off); + cur_len = min(cache->start + cache->size, start + len) - + cur_off; + BUG_ON(cur_len < root->sectorsize); + + /* reserve extent for the data */ + ret = btrfs_reserve_extent(trans, root, cur_len, 0, 0, (u64)-1, + &key, 1); + if (ret < 0) + break; + + eb = malloc(sizeof(*eb) + cur_len); + if (!eb) { + ret = -ENOMEM; + break; + } + + ret = pread(fd, eb->data, cur_len, cur_off); + if (ret < cur_len) { + ret = (ret < 0 ? ret : -EIO); + free(eb); + break; + } + eb->start = key.objectid; + eb->len = key.offset; + + /* Write the data */ + ret = write_and_map_eb(trans, root, eb); + free(eb); + if (ret < 0) + break; + + /* Now handle extent item and file extent things */ + ret = btrfs_record_file_extent(trans, root, ino, inode, cur_off, + key.objectid, key.offset); + if (ret < 0) + break; + /* Finally, insert csum items */ + if (datacsum) + ret = csum_disk_extent(trans, root, key.objectid, + key.offset); + + cur_off += key.offset; + cur_len = start + len - cur_off; + } + return ret; +} + +/* + * Relocate the used ext2 data in reserved ranges + * [0,1M) + * [btrfs_sb_offset(1), +BTRFS_STRIPE_LEN) + * [btrfs_sb_offset(2), +BTRFS_STRIPE_LEN) + */ +static int migrate_reserved_ranges(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct cache_tree *used, + struct btrfs_inode_item *inode, int fd, + u64 ino, u64 total_bytes, int datacsum) +{ + u64 cur_off; + u64 cur_len; + int ret = 0; + + /* 0 ~ 1M */ + cur_off = 0; + cur_len = 1024 * 1024; + ret = migrate_one_reserved_range(trans, root, used, inode, fd, ino, + cur_off, cur_len, datacsum); + if (ret < 0) + return ret; + + /* second sb(fisrt sb is included in 0~1M) */ + cur_off = btrfs_sb_offset(1); + cur_len = min(total_bytes, cur_off + BTRFS_STRIPE_LEN) - cur_off; + if (cur_off < total_bytes) + return ret; + ret = migrate_one_reserved_range(trans, root, used, inode, fd, ino, + cur_off, cur_len, datacsum); + if (ret < 0) + return ret; + + /* Last sb */ + cur_off = btrfs_sb_offset(2); + cur_len = min(total_bytes, cur_off + BTRFS_STRIPE_LEN) - cur_off; + if (cur_off < total_bytes) + return ret; + ret = migrate_one_reserved_range(trans, root, used, inode, fd, ino, + cur_off, cur_len, datacsum); + return ret; +} + static int wipe_reserved_ranges(struct cache_tree *tree, u64 min_stripe_size, int ensure_size); @@ -1687,11 +1804,10 @@ static int wipe_reserved_ranges(struct cache_tree *tree, u64 min_stripe_size, * * This is completely fs independent as we have cctx->used, only * need to create file extents point to all the posistions. - * TODO: Add handler for reserved ranges in next patch */ static int create_image_v2(struct btrfs_root *root, struct btrfs_mkfs_config *cfg, - struct btrfs_convert_context *cctx, + struct btrfs_convert_context *cctx, int fd, u64 size, char *name, int datacsum) { struct btrfs_inode_item buf; @@ -1769,6 +1885,10 @@ static int create_image_v2(struct btrfs_root *root, goto out; cur += len; } + /* Handle the reserved ranges */ + ret = migrate_reserved_ranges(trans, root, &cctx->used, &buf, fd, ino, + cfg->num_bytes, datacsum); + key.objectid = ino; key.type = BTRFS_INODE_ITEM_KEY;