From patchwork Fri Jan 26 18:41:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10186767 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 30976601D5 for ; Fri, 26 Jan 2018 18:42:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2259729EC8 for ; Fri, 26 Jan 2018 18:42:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 16E7A29ED0; Fri, 26 Jan 2018 18:42:26 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 7519A29EC8 for ; Fri, 26 Jan 2018 18:42:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752321AbeAZSmU (ORCPT ); Fri, 26 Jan 2018 13:42:20 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:39459 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752000AbeAZSlp (ORCPT ); Fri, 26 Jan 2018 13:41:45 -0500 Received: by mail-pf0-f194.google.com with SMTP id e11so818383pff.6 for ; Fri, 26 Jan 2018 10:41:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=NnsyiqS4U7wdg6uKSQ8PVvXTRgEeLeqCgXjx1ghM+4I=; b=HIfNgjh4vzJpG3Pbsi3+fLPp2hfDr3KOdki8sU+M/cS2rkFGkDpObBKkwQdgbFBoAN Sy6x7w+zaOXUpFjX5PrVSnSLLPwcFd/O6cL4lWbIgU6NtJxgYso9TNg4mkGJXix1KGBR 7JpfgIFv4eslCYDSyDw7rtjmuILkraWjCdIdlxafkDO4Z+FaiLb+mxs4Zx+BmcH+QLUz 53e9iswDZ6tIlqrJBUvbBHmNYh41ZYiKL3gpM49Nk+SIaw2XwWgilfpRzg9J+m5rMY7H YqEGFk1JXGp/xJiJMA8qrSWeuqjO2yVUTGXe7mznPowGYR+HBJCFVB2Z1BjZsqixQku7 uWKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=NnsyiqS4U7wdg6uKSQ8PVvXTRgEeLeqCgXjx1ghM+4I=; b=sBYVzpudZRS+x13etOqcWVzvY+IIx6O91eR8IKCIOSzrD8Nv/00ArZ4pexiIJXFWJ/ Z9On4n3k5bc3z9kDLkQJKf7M+5RWqlzOEHcpzOChXc6MW7AQxJrkkdwhneh+zpuR9b2q dZsJTEl3uIH6tMal6mML53KgKbvfiOHIrcp3zagDntb5/kb8vAkDcc9vDkS9bnNR9i22 F0yjQOYzSZCtO6jOnK2d8LWeTs9vDBdEpLeU7W0n0nL0N5wNNjxGMcSI1GvLF2LUhgK7 JYd1qzTx5i19xkLMWHNtI2Zn3D0j55uCGN6ssaseY5XamxaU+g4sMb3lj6Xp/t7Lmv89 wkRw== X-Gm-Message-State: AKwxytf+PIEQSymhshUcX2kDtmX98/R7c5/mXobaExHRVAh7FBYPRuPi ZiDyIwqsnPclkM6iqOxUOrwoUZ9pTiM= X-Google-Smtp-Source: AH8x224fWO3pBcrZOu41Xf76gb6RbOPRbXGcomJoGhEcHorQcSio0rnBrkkTmbKGfb/6P8ru3s842w== X-Received: by 10.99.143.84 with SMTP id r20mr16433366pgn.142.1516992104105; Fri, 26 Jan 2018 10:41:44 -0800 (PST) Received: from vader.thefacebook.com ([2620:10d:c090:200::6:7f96]) by smtp.gmail.com with ESMTPSA id y29sm19627400pff.24.2018.01.26.10.41.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Jan 2018 10:41:43 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 22/26] btrfs-progs: use libbtrfsutil for subvol sync Date: Fri, 26 Jan 2018 10:41:10 -0800 Message-Id: <3d8f99faa984c53b4e4ec4ac5abfe56df8682101.1516991902.git.osandov@fb.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: References: In-Reply-To: References: 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: Omar Sandoval btrfs_util_f_deleted_subvolumes() replaces enumerate_dead_subvols() and btrfs_util_f_subvolume_info() replaces is_subvolume_cleaned(). Signed-off-by: Omar Sandoval --- cmds-subvolume.c | 217 ++++++------------------------------------------------- 1 file changed, 21 insertions(+), 196 deletions(-) diff --git a/cmds-subvolume.c b/cmds-subvolume.c index b969fc88..8dbb3e49 100644 --- a/cmds-subvolume.c +++ b/cmds-subvolume.c @@ -42,38 +42,11 @@ #include "utils.h" #include "help.h" -static int is_subvolume_cleaned(int fd, u64 subvolid) +static int wait_for_subvolume_cleaning(int fd, size_t count, uint64_t *ids, + int sleep_interval) { - int ret; - struct btrfs_ioctl_search_args args; - struct btrfs_ioctl_search_key *sk = &args.key; - - sk->tree_id = BTRFS_ROOT_TREE_OBJECTID; - sk->min_objectid = subvolid; - sk->max_objectid = subvolid; - sk->min_type = BTRFS_ROOT_ITEM_KEY; - sk->max_type = BTRFS_ROOT_ITEM_KEY; - sk->min_offset = 0; - sk->max_offset = (u64)-1; - sk->min_transid = 0; - sk->max_transid = (u64)-1; - sk->nr_items = 1; - - ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); - if (ret < 0) - return -errno; - - if (sk->nr_items == 0) - return 1; - - return 0; -} - -static int wait_for_subvolume_cleaning(int fd, int count, u64 *ids, - int sleep_interval) -{ - int ret; - int i; + size_t i; + enum btrfs_util_error err; while (1) { int clean = 1; @@ -81,16 +54,14 @@ static int wait_for_subvolume_cleaning(int fd, int count, u64 *ids, for (i = 0; i < count; i++) { if (!ids[i]) continue; - ret = is_subvolume_cleaned(fd, ids[i]); - if (ret < 0) { - error( - "cannot read status of dead subvolume %llu: %s", - (unsigned long long)ids[i], strerror(-ret)); - return ret; - } - if (ret) { - printf("Subvolume id %llu is gone\n", ids[i]); + err = btrfs_util_f_subvolume_info(fd, ids[i], NULL); + if (err == BTRFS_UTIL_ERROR_SUBVOLUME_NOT_FOUND) { + printf("Subvolume id %" PRIu64 " is gone\n", + ids[i]); ids[i] = 0; + } else if (err) { + error_btrfs_util(err); + return -errno; } else { clean = 0; } @@ -1031,160 +1002,15 @@ static const char * const cmd_subvol_sync_usage[] = { NULL }; -#if 0 -/* - * If we're looking for any dead subvolume, take a shortcut and look - * for any ORPHAN_ITEMs in the tree root - */ -static int fs_has_dead_subvolumes(int fd) -{ - int ret; - struct btrfs_ioctl_search_args args; - struct btrfs_ioctl_search_key *sk = &args.key; - struct btrfs_ioctl_search_header sh; - u64 min_subvolid = 0; - -again: - sk->tree_id = BTRFS_ROOT_TREE_OBJECTID; - sk->min_objectid = BTRFS_ORPHAN_OBJECTID; - sk->max_objectid = BTRFS_ORPHAN_OBJECTID; - sk->min_type = BTRFS_ORPHAN_ITEM_KEY; - sk->max_type = BTRFS_ORPHAN_ITEM_KEY; - sk->min_offset = min_subvolid; - sk->max_offset = (u64)-1; - sk->min_transid = 0; - sk->max_transid = (u64)-1; - sk->nr_items = 1; - - ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); - if (ret < 0) - return -errno; - - if (!sk->nr_items) - return 0; - - memcpy(&sh, args.buf, sizeof(sh)); - min_subvolid = sh.offset; - - /* - * Verify that the root item is really there and we haven't hit - * a stale orphan - */ - sk->tree_id = BTRFS_ROOT_TREE_OBJECTID; - sk->min_objectid = min_subvolid; - sk->max_objectid = min_subvolid; - sk->min_type = BTRFS_ROOT_ITEM_KEY; - sk->max_type = BTRFS_ROOT_ITEM_KEY; - sk->min_offset = 0; - sk->max_offset = (u64)-1; - sk->min_transid = 0; - sk->max_transid = (u64)-1; - sk->nr_items = 1; - - ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); - if (ret < 0) - return -errno; - - /* - * Stale orphan, try the next one - */ - if (!sk->nr_items) { - min_subvolid++; - goto again; - } - - return 1; -} -#endif - -#define SUBVOL_ID_BATCH 1024 - -/* - * Enumerate all dead subvolumes that exist in the filesystem. - * Fill @ids and reallocate to bigger size if needed. - */ -static int enumerate_dead_subvols(int fd, u64 **ids) -{ - int ret; - struct btrfs_ioctl_search_args args; - struct btrfs_ioctl_search_key *sk = &args.key; - int idx = 0; - int count = 0; - - memset(&args, 0, sizeof(args)); - - sk->tree_id = BTRFS_ROOT_TREE_OBJECTID; - sk->min_objectid = BTRFS_ORPHAN_OBJECTID; - sk->max_objectid = BTRFS_ORPHAN_OBJECTID; - sk->min_type = BTRFS_ORPHAN_ITEM_KEY; - sk->max_type = BTRFS_ORPHAN_ITEM_KEY; - sk->min_offset = 0; - sk->max_offset = (u64)-1; - sk->min_transid = 0; - sk->max_transid = (u64)-1; - sk->nr_items = 4096; - - *ids = NULL; - while (1) { - struct btrfs_ioctl_search_header *sh; - unsigned long off; - int i; - - ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args); - if (ret < 0) - return -errno; - - if (!sk->nr_items) - return idx; - - off = 0; - for (i = 0; i < sk->nr_items; i++) { - sh = (struct btrfs_ioctl_search_header*)(args.buf + off); - off += sizeof(*sh); - - if (btrfs_search_header_type(sh) - == BTRFS_ORPHAN_ITEM_KEY) { - if (idx >= count) { - u64 *newids; - - count += SUBVOL_ID_BATCH; - newids = (u64*)realloc(*ids, - count * sizeof(u64)); - if (!newids) - return -ENOMEM; - *ids = newids; - } - (*ids)[idx] = btrfs_search_header_offset(sh); - idx++; - } - off += btrfs_search_header_len(sh); - - sk->min_objectid = btrfs_search_header_objectid(sh); - sk->min_type = btrfs_search_header_type(sh); - sk->min_offset = btrfs_search_header_offset(sh); - } - if (sk->min_offset < (u64)-1) - sk->min_offset++; - else - break; - if (sk->min_type != BTRFS_ORPHAN_ITEM_KEY) - break; - if (sk->min_objectid != BTRFS_ORPHAN_OBJECTID) - break; - } - - return idx; -} - static int cmd_subvol_sync(int argc, char **argv) { int fd = -1; - int i; int ret = 1; DIR *dirstream = NULL; - u64 *ids = NULL; - int id_count; + uint64_t *ids; + size_t id_count, i; int sleep_interval = 1; + enum btrfs_util_error err; while (1) { int c = getopt(argc, argv, "s:"); @@ -1218,10 +1044,9 @@ static int cmd_subvol_sync(int argc, char **argv) id_count = argc - optind; if (!id_count) { - id_count = enumerate_dead_subvols(fd, &ids); - if (id_count < 0) { - error("can't enumerate dead subvolumes: %s", - strerror(-id_count)); + err = btrfs_util_f_deleted_subvolumes(fd, &ids, &id_count); + if (err) { + error_btrfs_util(err); ret = 1; goto out; } @@ -1230,7 +1055,7 @@ static int cmd_subvol_sync(int argc, char **argv) goto out; } } else { - ids = (u64*)malloc(id_count * sizeof(u64)); + ids = malloc(id_count * sizeof(uint64_t)); if (!ids) { error("not enough memory"); ret = 1; @@ -1244,13 +1069,13 @@ static int cmd_subvol_sync(int argc, char **argv) arg = argv[optind + i]; errno = 0; id = strtoull(arg, NULL, 10); - if (errno < 0) { + if (errno) { error("unrecognized subvolume id %s", arg); ret = 1; goto out; } - if (id < BTRFS_FIRST_FREE_OBJECTID - || id > BTRFS_LAST_FREE_OBJECTID) { + if (id < BTRFS_FIRST_FREE_OBJECTID || + id > BTRFS_LAST_FREE_OBJECTID) { error("subvolume id %s out of range", arg); ret = 1; goto out;