From patchwork Thu Nov 7 10:01:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anand Jain X-Patchwork-Id: 3151911 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.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9371EBEEB3 for ; Thu, 7 Nov 2013 09:54:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6037020384 for ; Thu, 7 Nov 2013 09:54:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 245F720304 for ; Thu, 7 Nov 2013 09:54:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754167Ab3KGJy2 (ORCPT ); Thu, 7 Nov 2013 04:54:28 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:34222 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753945Ab3KGJyS (ORCPT ); Thu, 7 Nov 2013 04:54:18 -0500 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id rA79r9G9006423 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 7 Nov 2013 09:53:09 GMT Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rA79r8LU001473 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 7 Nov 2013 09:53:09 GMT Received: from abhmt106.oracle.com (abhmt106.oracle.com [141.146.116.58]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rA79r8bp001470; Thu, 7 Nov 2013 09:53:08 GMT Received: from wish.sg.oracle.com (/10.186.101.18) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 07 Nov 2013 01:53:07 -0800 From: Anand Jain To: linux-btrfs@vger.kernel.org Cc: jbacik@fusionio.com, zab@redhat.com, dsterba@suse.cz Subject: [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Date: Thu, 7 Nov 2013 18:01:41 +0800 Message-Id: <1383818503-29607-1-git-send-email-anand.jain@oracle.com> X-Mailer: git-send-email 1.8.1.164.g2d0029e In-Reply-To: <1383536745-4635-1-git-send-email-anand.jain@oracle.com> References: <1383536745-4635-1-git-send-email-anand.jain@oracle.com> X-Source-IP: acsinet22.oracle.com [141.146.126.238] 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.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 need fsinfo from btrfs-control that is when mount path is not known. current method of going through each mount points isn't efficient, and multiple subvol of a fsid could be mounted means extra logic to handle that. Further this will help to revamp check_mounted() (planned) check_mounted is heavily used in the btrfs-progs, it does full scan of all the disks in the system to confirm if a multi-disk btrfs is mounted it doesn't scalable well with few hundreds luns, check_mounted for sure needs a revamp. using this it can be done easily. which is planned. v3: accepts Josef suggested and fix git screwup v2: commit reword Signed-off-by: Anand Jain --- ioctl.h | 19 +++++++++++++++ utils.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.h | 1 + 3 files changed, 96 insertions(+), 0 deletions(-) diff --git a/ioctl.h b/ioctl.h index d21413f..29575d8 100644 --- a/ioctl.h +++ b/ioctl.h @@ -506,6 +506,23 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code) } } +/* fs flags */ +#define BTRFS_FS_MOUNTED (1LLU << 0) + +struct btrfs_ioctl_fslist { + __u64 self_sz; /* in/out */ + __u8 fsid[BTRFS_FSID_SIZE]; /* out */ + __u64 num_devices; + __u64 missing_devices; + __u64 total_devices; + __u64 flags; +}; + +struct btrfs_ioctl_fslist_args { + __u64 self_sz; /* in/out */ + __u64 count; /* out */ +}; + #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ @@ -604,6 +621,8 @@ struct btrfs_ioctl_clone_range_args { struct btrfs_ioctl_dev_replace_args) #define BTRFS_IOC_DEDUP_CTL _IOWR(BTRFS_IOCTL_MAGIC, 55, \ struct btrfs_ioctl_dedup_args) +#define BTRFS_IOC_GET_FSLIST _IOWR(BTRFS_IOCTL_MAGIC, 56, \ + struct btrfs_ioctl_fslist_args) #ifdef __cplusplus } #endif diff --git a/utils.c b/utils.c index 60d2c3a..4b90026 100644 --- a/utils.c +++ b/utils.c @@ -47,6 +47,7 @@ #include "utils.h" #include "volumes.h" #include "ioctl.h" +#include "btrfs-list.h" #ifndef BLKDISCARD #define BLKDISCARD _IO(0x12,119) @@ -2087,3 +2088,78 @@ int lookup_ino_rootid(int fd, u64 *rootid) return 0; } + +/* scans for fsid(s) in the kernel using the btrfs-control + * interface. + */ +int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count) +{ + int ret, fd, e; + struct btrfs_ioctl_fslist_args *fsargs; + struct btrfs_ioctl_fslist_args *fsargs_saved = NULL; + struct btrfs_ioctl_fslist *fslist; + u64 sz; + int count; + + fd = open("/dev/btrfs-control", O_RDWR); + e = errno; + if (fd < 0) { + perror("failed to open /dev/btrfs-control"); + return -e; + } + + /* space to hold 512 fsids, doesn't matter if small + * it would fail and return count so then we try again + */ + count = 512; +again: + sz = sizeof(*fsargs) + sizeof(*fslist) * count; + + fsargs = malloc(sz); + if (!fsargs) { + close(fd); + return -ENOMEM; + } + + memset(fsargs, 0, sz); + fsargs->count = count; + + ret = ioctl(fd, BTRFS_IOC_GET_FSLIST, fsargs); + e = errno; + if (ret == 1) { + /* out of size so reallocate */ + count = fsargs->count; + free(fsargs); + goto again; + } else if (ret < 0) { + printf("ERROR: scan_fsid ioctl failed - %s\n", + strerror(e)); + ret = -e; + goto out; + } + + /* ioctl returns fsid count in count parameter*/ + + *out_count = fsargs->count; + if (*out_count == 0) { + *out_fslist = NULL; + ret = 0; + goto out; + } + + fsargs_saved = fsargs; + fslist = (struct btrfs_ioctl_fslist *) (++fsargs); + + sz = sizeof(*fslist) * *out_count; + *out_fslist = malloc(sz); + if (*out_fslist == NULL) { + ret = -ENOMEM; + goto out; + } + memcpy(*out_fslist, fslist, sz); + ret = 0; +out: + free(fsargs_saved); + close(fd); + return 0; +} diff --git a/utils.h b/utils.h index 6f4b10c..a14a887 100644 --- a/utils.h +++ b/utils.h @@ -94,5 +94,6 @@ int ask_user(char *question); int lookup_ino_rootid(int fd, u64 *rootid); int btrfs_scan_lblkid(int update_kernel); int get_btrfs_mount(const char *dev, char *mp, size_t mp_size); +int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count); #endif