From patchwork Mon Feb 9 20:03:16 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 5803231 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 16AF1BF6C3 for ; Mon, 9 Feb 2015 20:04:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1277E2011B for ; Mon, 9 Feb 2015 20:04:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E5E922011E for ; Mon, 9 Feb 2015 20:04:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760997AbbBIUEL (ORCPT ); Mon, 9 Feb 2015 15:04:11 -0500 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:11003 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760946AbbBIUD6 (ORCPT ); Mon, 9 Feb 2015 15:03:58 -0500 Received: from pps.filterd (m0004077 [127.0.0.1]) by mx0b-00082601.pphosted.com (8.14.5/8.14.5) with SMTP id t19K3l5Z022536; Mon, 9 Feb 2015 12:03:56 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wit.ai; h=from : to : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=mx2; bh=6dDavC7aUDJ/+2Dh9W3CDhrB7KCF/2+KAlXm3p4HuxQ=; b=UEQgfEe8b1K046fRSkl5XSYO5q1dFx0wlnujbhRSVrc52J0CMCi1OBexrpTrte6Sn0oa DY+T2jRghjOO1xYPjZa+BpxhCG0LMJwm7vGGn2oV1bf+Snse5SS2Xp2tQhMp0kXE94K5 MytfTugEJtaDV887yYpo9iaxgptU16N5LcL4ZkZjxY6ljAJJN3OXXOJG7C8IInC32ull Brp3xTVrpv8Zkj+OcSxaSkDl79wPs6hPZtQ04g4HLVhSy0bO43XInMlQUnhb0Xbn1SMm KY/rnY4Kv8fqifI2I466DzZKAsNcvUxSgK0RB0E6DkyS4ilw+0XITKmJ2GdocdYVaTfG mA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=from : to : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=facebook; bh=6dDavC7aUDJ/+2Dh9W3CDhrB7KCF/2+KAlXm3p4HuxQ=; b=nbiwANqnLk55hAoPHeeNOpE4eCiqmmL3LQ6RYPZTJ+W/F9ee1CRfRzuUqSm+qkLqE+qI TnYxVmZMnRQrS0HYD7P9GW3ZvF7C/klR79KT2VRHyr4VlCNRVwoghR0WQOxxrLJ7vtSf eQJQh/HwlkhsaARPmViihSG6PavJEXIkLPg= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0b-00082601.pphosted.com with ESMTP id 1sf2yv04b4-11 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Mon, 09 Feb 2015 12:03:56 -0800 Received: from localhost (192.168.57.29) by mail.thefacebook.com (192.168.16.23) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 9 Feb 2015 12:03:47 -0800 From: Josef Bacik To: , Subject: [PATCH 13/16] Btrfs-progs: make restore update dev items Date: Mon, 9 Feb 2015 15:03:16 -0500 Message-ID: <1423512199-16552-14-git-send-email-jbacik@fb.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1423512199-16552-1-git-send-email-jbacik@fb.com> References: <1423512199-16552-1-git-send-email-jbacik@fb.com> MIME-Version: 1.0 X-Originating-IP: [192.168.57.29] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.13.68, 1.0.33, 0.0.0000 definitions=2015-02-09_02:2015-02-09, 2015-02-08, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 kscore.is_bulkscore=0 kscore.compositescore=0 circleOfTrustscore=2.87009407511322 compositescore=0.980601274849849 urlsuspect_oldscore=0.980601274849849 suspectscore=2 recipient_domain_to_sender_totalscore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 recipient_to_sender_totalscore=0 recipient_domain_to_sender_domain_totalscore=64355 rbsscore=0.980601274849849 spamscore=0 recipient_to_sender_domain_totalscore=0 urlsuspectscore=0.9 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1502090197 X-FB-Internal: deliver Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When we restore a multi disk image onto a single disk we need to update the dev items used and total bytes so that fsck doesn't freak out and that we get normal results from stuff like btrfs fi show. Thanks, Signed-off-by: Josef Bacik --- btrfs-image.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 131 insertions(+), 19 deletions(-) diff --git a/btrfs-image.c b/btrfs-image.c index feb4a62..3c78388 100644 --- a/btrfs-image.c +++ b/btrfs-image.c @@ -133,6 +133,7 @@ struct mdrestore_struct { size_t num_items; u32 leafsize; u64 devid; + u64 alloced_chunks; u64 last_physical_offset; u8 uuid[BTRFS_UUID_SIZE]; u8 fsid[BTRFS_FSID_SIZE]; @@ -1856,6 +1857,7 @@ static int mdrestore_init(struct mdrestore_struct *mdres, mdres->multi_devices = multi_devices; mdres->clear_space_cache = 0; mdres->last_physical_offset = 0; + mdres->alloced_chunks = 0; if (!num_threads) return 0; @@ -2087,6 +2089,7 @@ static int read_chunk_block(struct mdrestore_struct *mdres, u8 *buffer, mdres->last_physical_offset) mdres->last_physical_offset = fs_chunk->physical + fs_chunk->bytes; + mdres->alloced_chunks += fs_chunk->bytes; tree_insert(&mdres->chunk_tree, &fs_chunk->l, chunk_cmp); } out: @@ -2372,9 +2375,107 @@ static void remap_overlapping_chunks(struct mdrestore_struct *mdres) } } -static int __restore_metadump(const char *input, FILE *out, int old_restore, - int num_threads, int fixup_offset, - const char *target, int multi_devices) +static int fixup_devices(struct btrfs_fs_info *fs_info, + struct mdrestore_struct *mdres, off_t dev_size) +{ + struct btrfs_trans_handle *trans; + struct btrfs_dev_item *dev_item; + struct btrfs_path *path; + struct extent_buffer *leaf; + struct btrfs_root *root = fs_info->chunk_root; + struct btrfs_key key; + u64 devid, cur_devid; + int ret; + + path = btrfs_alloc_path(); + if (!path) { + fprintf(stderr, "Error alloc'ing path\n"); + return -ENOMEM; + } + + trans = btrfs_start_transaction(fs_info->tree_root, 1); + if (IS_ERR(trans)) { + fprintf(stderr, "Error starting transaction %ld\n", + PTR_ERR(trans)); + btrfs_free_path(path); + return PTR_ERR(trans); + } + + dev_item = &fs_info->super_copy->dev_item; + + devid = btrfs_stack_device_id(dev_item); + + btrfs_set_stack_device_total_bytes(dev_item, dev_size); + btrfs_set_stack_device_bytes_used(dev_item, mdres->alloced_chunks); + + key.objectid = BTRFS_DEV_ITEMS_OBJECTID; + key.type = BTRFS_DEV_ITEM_KEY; + key.offset = 0; + +again: + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret < 0) { + fprintf(stderr, "search failed %d\n", ret); + exit(1); + } + + while (1) { + leaf = path->nodes[0]; + if (path->slots[0] >= btrfs_header_nritems(leaf)) { + ret = btrfs_next_leaf(root, path); + if (ret < 0) { + fprintf(stderr, "Error going to next leaf " + "%d\n", ret); + exit(1); + } + if (ret > 0) { + ret = 0; + break; + } + leaf = path->nodes[0]; + } + + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); + if (key.type > BTRFS_DEV_ITEM_KEY) + break; + if (key.type != BTRFS_DEV_ITEM_KEY) { + path->slots[0]++; + continue; + } + + dev_item = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_dev_item); + cur_devid = btrfs_device_id(leaf, dev_item); + if (devid != cur_devid) { + ret = btrfs_del_item(trans, root, path); + if (ret) { + fprintf(stderr, "Error deleting item %d\n", + ret); + exit(1); + } + btrfs_release_path(path); + goto again; + } + + btrfs_set_device_total_bytes(leaf, dev_item, dev_size); + btrfs_set_device_bytes_used(leaf, dev_item, + mdres->alloced_chunks); + btrfs_mark_buffer_dirty(leaf); + path->slots[0]++; + } + + btrfs_free_path(path); + ret = btrfs_commit_transaction(trans, fs_info->tree_root); + if (ret) { + fprintf(stderr, "Commit failed %d\n", ret); + return ret; + } + return 0; +} + +static int restore_metadump(const char *input, FILE *out, int old_restore, + int num_threads, int fixup_offset, + const char *target, int multi_devices) { struct meta_cluster *cluster = NULL; struct meta_cluster_header *header; @@ -2454,6 +2555,30 @@ static int __restore_metadump(const char *input, FILE *out, int old_restore, } } ret = wait_for_worker(&mdrestore); + + if (!ret && !multi_devices && !old_restore) { + struct stat st; + + info = open_ctree_fs_info(target, 0, 0, + OPEN_CTREE_PARTIAL | + OPEN_CTREE_WRITES); + if (!info) { + fprintf(stderr, "unable to open %s\n", target); + ret = -EIO; + goto out; + } + + if (stat(target, &st)) { + fprintf(stderr, "statting %s failed\n", target); + close_ctree(info->chunk_root); + return 1; + } + + ret = fixup_devices(info, &mdrestore, st.st_size); + close_ctree(info->chunk_root); + if (ret) + goto out; + } out: mdrestore_destroy(&mdrestore, num_threads); failed_cluster: @@ -2467,19 +2592,6 @@ failed_open: return ret; } -static int restore_metadump(const char *input, FILE *out, int old_restore, - int num_threads, int multi_devices) -{ - return __restore_metadump(input, out, old_restore, num_threads, 0, NULL, - multi_devices); -} - -static int fixup_metadump(const char *input, FILE *out, int num_threads, - const char *target) -{ - return __restore_metadump(input, out, 0, num_threads, 1, target, 1); -} - static int update_disk_super_on_device(struct btrfs_fs_info *info, const char *other_dev, u64 cur_devid) { @@ -2705,7 +2817,7 @@ int main(int argc, char *argv[]) compress_level, sanitize, walk_trees); } else { ret = restore_metadump(source, out, old_restore, num_threads, - multi_devices); + 0, target, multi_devices); } if (ret) { printk("%s failed (%s)\n", (create) ? "create" : "restore", @@ -2752,14 +2864,14 @@ int main(int argc, char *argv[]) close_ctree(info->chunk_root); /* fix metadata block to map correct chunk */ - ret = fixup_metadump(source, out, 1, target); + ret = restore_metadump(source, out, 0, num_threads, 1, + target, 1); if (ret) { fprintf(stderr, "fix metadump failed (error=%d)\n", ret); exit(1); } } - out: if (out == stdout) { fflush(out);