From patchwork Mon Nov 4 03:45:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anand Jain X-Patchwork-Id: 3134541 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AD32F9F3C4 for ; Mon, 4 Nov 2013 03:37:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 85FEC201F7 for ; Mon, 4 Nov 2013 03:37:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EC5D32039C for ; Mon, 4 Nov 2013 03:37:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752729Ab3KDDhc (ORCPT ); Sun, 3 Nov 2013 22:37:32 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:38147 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752609Ab3KDDh1 (ORCPT ); Sun, 3 Nov 2013 22:37:27 -0500 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id rA43bM7v021011 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 4 Nov 2013 03:37:22 GMT Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rA43bLi5013502 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 4 Nov 2013 03:37:21 GMT Received: from abhmt104.oracle.com (abhmt104.oracle.com [141.146.116.56]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rA43bLTv003532; Mon, 4 Nov 2013 03:37:21 GMT Received: from wish.sg.oracle.com (/10.186.101.18) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 03 Nov 2013 19:37:20 -0800 From: Anand Jain To: linux-btrfs@vger.kernel.org Cc: jbacik@fusionio.com, zab@redhat.com, dsterba@suse.cz Subject: [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted Date: Mon, 4 Nov 2013 11:45:44 +0800 Message-Id: <1383536745-4635-3-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: acsinet21.oracle.com [141.146.126.237] 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 as of now with out this patch user would see fsinfo per btrfs mount path but which mean multiple entry if more than one subvol is mounted of the same fsid. so this patch will handle that nicely. v2: accepts Zach suggested Signed-off-by: Anand Jain --- cmds-filesystem.c | 90 +++++++++++++++++++++++++++++++++-------------------- utils.c | 88 ++++++++++++++++++++++++++++++++++++++++++--------- utils.h | 3 +- 3 files changed, 130 insertions(+), 51 deletions(-) diff --git a/cmds-filesystem.c b/cmds-filesystem.c index d2cad81..f8e8475 100644 --- a/cmds-filesystem.c +++ b/cmds-filesystem.c @@ -317,6 +317,29 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info, return 0; } +static void handle_print(char *mnt, char *label) +{ + int fd; + struct btrfs_ioctl_fs_info_args fs_info_arg; + struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL; + struct btrfs_ioctl_space_args *space_info_arg; + + if (get_fs_info(mnt, &fs_info_arg, &dev_info_arg)) { + fprintf(stdout, "ERROR: get_fs_info failed\n"); + return; + } + + fd = open(mnt, O_RDONLY); + if (fd > 0 && !get_df(fd, &space_info_arg)) { + print_one_fs(&fs_info_arg, dev_info_arg, + space_info_arg, label, mnt); + kfree(space_info_arg); + } + if (fd > 0) + close(fd); + kfree(dev_info_arg); +} + /* This function checks if the given input parameter is * an uuid or a path * return -1: some error in the given input @@ -350,47 +373,39 @@ static int check_arg_type(char *input) static int btrfs_scan_kernel(void *search) { - int ret = 0, fd; - FILE *f; - struct mntent *mnt; - struct btrfs_ioctl_fs_info_args fs_info_arg; - struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL; - struct btrfs_ioctl_space_args *space_info_arg; + int ret = 0; char label[BTRFS_LABEL_SIZE]; - - f = setmntent("/proc/self/mounts", "r"); - if (f == NULL) - return 1; - - memset(label, 0, sizeof(label)); - while ((mnt = getmntent(f)) != NULL) { - if (strcmp(mnt->mnt_type, "btrfs")) + char mnt[BTRFS_PATH_NAME_MAX + 1]; + struct btrfs_ioctl_fslist *fslist; + struct btrfs_ioctl_fslist *fslist_saved; + u64 cnt_fs; + int cnt_mnt; + __u8 *fsid; + __u64 flags; + + ret = get_fslist(&fslist, &cnt_fs); + if (ret) + return ret; + fslist_saved = fslist; + while (cnt_fs--) { + fsid = fslist->fsid; + flags = fslist->flags; + fslist++; + if (!(flags & BTRFS_FS_MOUNTED)) continue; - ret = get_fs_info(mnt->mnt_dir, &fs_info_arg, - &dev_info_arg); + memset(mnt, 0, BTRFS_PATH_NAME_MAX + 1); + memset(label, 0, sizeof(label)); + ret = fsid_to_mntpt(fsid, mnt, &cnt_mnt); if (ret) return ret; - - if (get_label_mounted(mnt->mnt_dir, label)) { - kfree(dev_info_arg); + if (get_label_mounted(mnt, label)) return 1; - } - if (search && !match_search_item_kernel(fs_info_arg.fsid, - mnt->mnt_dir, label, search)) { - kfree(dev_info_arg); + + if (search && !match_search_item_kernel(fsid, + mnt, label, search)) continue; - } - fd = open(mnt->mnt_dir, O_RDONLY); - if (fd > 0 && !get_df(fd, &space_info_arg)) { - print_one_fs(&fs_info_arg, dev_info_arg, - space_info_arg, label, mnt->mnt_dir); - kfree(space_info_arg); - memset(label, 0, sizeof(label)); - } - if (fd > 0) - close(fd); - kfree(dev_info_arg); + handle_print(mnt, label); if (search) return 0; } @@ -469,6 +484,13 @@ static int cmd_show(int argc, char **argv) goto devs_only; } } + if (type == BTRFS_ARG_MNTPOINT) { + char label[BTRFS_LABEL_SIZE]; + if (get_label_mounted(search, label)) + return 1; + handle_print(search, label); + return 0; + } } if (where == BTRFS_SCAN_DEV) diff --git a/utils.c b/utils.c index 1798a7c..d466ffa 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) @@ -2091,12 +2092,12 @@ int lookup_ino_rootid(int fd, u64 *rootid) /* scans for fsid(s) in the kernel using the btrfs-control * interface. */ -int get_fslist(struct btrfs_ioctl_fslist **out_fslist, int *out_count) +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; - struct btrfs_ioctl_fslist *fslist_tmp; u64 sz; int count; @@ -2139,31 +2140,86 @@ again: /* ioctl returns fsid count in count parameter*/ - *out_count = count = fsargs->count; - if (count == 0) { + *out_count = fsargs->count; + if (*out_count == 0) { *out_fslist = NULL; ret = 0; goto out; } - fslist = (struct btrfs_ioctl_fslist *) (fsargs + - sizeof(*fsargs)); + fsargs_saved = fsargs; + fslist = (struct btrfs_ioctl_fslist *) (++fsargs); - fslist_tmp = *out_fslist = (struct btrfs_ioctl_fslist *) - malloc(sizeof(*fslist) * count); - if (!fslist_tmp) { + sz = sizeof(*fslist) * *out_count; + *out_fslist = (struct btrfs_ioctl_fslist *) malloc(sz); + if (*out_fslist == NULL) { ret = -ENOMEM; goto out; } - - while (count--) { - memcpy(fslist_tmp, fslist, sizeof(*fslist)); - fslist_tmp = fslist_tmp + sizeof(*fslist_tmp); - fslist = fslist + sizeof(*fslist); - } + memcpy(*out_fslist, fslist, sz); ret = 0; out: - free(fsargs); + free(fsargs_saved); close(fd); return 0; } + +/* This finds the mount point for a given fsid, + * subvols of the same fs/fsid can be mounted + * so here this picks and lowest subvol id + * and returns the mount point +*/ +int fsid_to_mntpt(__u8 *fsid, char *mntpt, int *mnt_cnt) +{ + int fd = -1, ret = 0; + DIR *dirstream = NULL; + FILE *f; + struct btrfs_ioctl_fs_info_args fi_args; + u64 svid, saved_svid = (u64)-1; + struct mntent *mnt; + int mcnt = 0; + + *mnt_cnt = 0; + f = setmntent("/proc/self/mounts", "r"); + if (f == NULL) + return 1; + + while ((mnt = getmntent(f)) != NULL) { + if (strcmp(mnt->mnt_type, "btrfs")) + continue; + fd = open_file_or_dir(mnt->mnt_dir, &dirstream); + if (fd < 0) { + ret = -errno; + return ret; + } + ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args); + if (ret < 0) { + ret = -errno; + close_file_or_dir(fd, dirstream); + break; + } + if (uuid_compare(fsid, fi_args.fsid)) { + close_file_or_dir(fd, dirstream); + continue; + } + + /* found */ + mcnt++; + ret = btrfs_list_get_path_rootid(fd, &svid); + if (ret) { + /* error so just copy and return*/ + strcpy(mntpt, mnt->mnt_dir); + close_file_or_dir(fd, dirstream); + break; + } + if (svid < saved_svid) { + strcpy(mntpt, mnt->mnt_dir); + saved_svid = svid; + } + } + endmntent(f); + if (mcnt) + *mnt_cnt = mcnt; + + return ret; +} diff --git a/utils.h b/utils.h index e20ad74..8c64575 100644 --- a/utils.h +++ b/utils.h @@ -94,6 +94,7 @@ 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, int *out_count); +int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count); +int fsid_to_mntpt(__u8 *fsid, char *mnt, int *mnt_cnt); #endif