From patchwork Fri Aug 3 09:48:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anand Jain X-Patchwork-Id: 1270171 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 97B07DF280 for ; Fri, 3 Aug 2012 09:51:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753225Ab2HCJvr (ORCPT ); Fri, 3 Aug 2012 05:51:47 -0400 Received: from acsinet15.oracle.com ([141.146.126.227]:44931 "EHLO acsinet15.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753099Ab2HCJvm (ORCPT ); Fri, 3 Aug 2012 05:51:42 -0400 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by acsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q739paW8032381 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 3 Aug 2012 09:51:37 GMT Received: from acsmt357.oracle.com (acsmt357.oracle.com [141.146.40.157]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q739paqj023727 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 3 Aug 2012 09:51:36 GMT Received: from abhmt119.oracle.com (abhmt119.oracle.com [141.146.116.71]) by acsmt357.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q739paP8018728; Fri, 3 Aug 2012 04:51:36 -0500 Received: from localhost.localdomain (/10.186.101.18) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 03 Aug 2012 02:51:35 -0700 From: Anand jain To: linux-btrfs@vger.kernel.org Cc: Liu Bo Subject: [PATCH 6/9] Btrfs-progs: show generation in command btrfs subvol list Date: Fri, 3 Aug 2012 17:48:55 +0800 Message-Id: <1343987338-10612-8-git-send-email-Anand.Jain@oracle.com> X-Mailer: git-send-email 1.7.7 In-Reply-To: <1343987338-10612-1-git-send-email-Anand.Jain@oracle.com> References: <1343822481-26707-1-git-send-email-Anand.Jain@oracle.com> <1343987338-10612-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 From: Liu Bo This adds the ability to show root's modification generation when we use btrfs subvol list. NOTE: Like file's atime and ctime, root's generation also has 'creation generation' and 'modification generation'. The generation that we're going to show is 'modification generation', and the next patch is going to show 'creation generation'. Signed-off-by: Liu Bo --- btrfs-list.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 55 insertions(+), 6 deletions(-) diff --git a/btrfs-list.c b/btrfs-list.c index f2a6e19..0592055 100644 --- a/btrfs-list.c +++ b/btrfs-list.c @@ -57,6 +57,9 @@ struct root_info { /* the dir id we're in from ref_tree */ u64 dir_id; + /* generation when the root is created or last updated */ + u64 gen; + /* path from the subvol we live in to this root, including the * root's name. This is null until we do the extra lookup ioctl. */ @@ -194,6 +197,19 @@ static int add_root(struct root_lookup *root_lookup, return 0; } +static int update_root(struct root_lookup *root_lookup, u64 root_id, u64 gen) +{ + struct root_info *ri; + + ri = tree_search(&root_lookup->root, root_id); + if (!ri || ri->root_id != root_id) { + fprintf(stderr, "could not find subvol %llu\n", root_id); + return -ENOENT; + } + ri->gen = gen; + return 0; +} + /* * for a given root_info, search through the root_lookup tree to construct * the full path name to it. @@ -615,11 +631,15 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup) struct btrfs_ioctl_search_key *sk = &args.key; struct btrfs_ioctl_search_header *sh; struct btrfs_root_ref *ref; + struct btrfs_root_item *ri; unsigned long off = 0; int name_len; char *name; u64 dir_id; + u8 type; + u64 gen = 0; int i; + int get_gen = 0; root_lookup_init(root_lookup); memset(&args, 0, sizeof(args)); @@ -644,6 +664,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup) sk->max_offset = (u64)-1; sk->max_transid = (u64)-1; +again: /* just a big number, doesn't matter much */ sk->nr_items = 4096; @@ -665,7 +686,7 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup) sh = (struct btrfs_ioctl_search_header *)(args.buf + off); off += sizeof(*sh); - if (sh->type == BTRFS_ROOT_BACKREF_KEY) { + if (!get_gen && sh->type == BTRFS_ROOT_BACKREF_KEY) { ref = (struct btrfs_root_ref *)(args.buf + off); name_len = btrfs_stack_root_ref_name_len(ref); name = (char *)(ref + 1); @@ -673,6 +694,11 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup) add_root(root_lookup, sh->objectid, sh->offset, dir_id, name, name_len); + } else if (get_gen && sh->type == BTRFS_ROOT_ITEM_KEY) { + ri = (struct btrfs_root_item *)(args.buf + off); + gen = btrfs_root_generation(ri); + + update_root(root_lookup, sh->objectid, gen); } off += sh->len; @@ -689,17 +715,38 @@ static int __list_subvol_search(int fd, struct root_lookup *root_lookup) /* this iteration is done, step forward one root for the next * ioctl */ - if (sk->min_type < BTRFS_ROOT_BACKREF_KEY) { - sk->min_type = BTRFS_ROOT_BACKREF_KEY; + if (get_gen) + type = BTRFS_ROOT_ITEM_KEY; + else + type = BTRFS_ROOT_BACKREF_KEY; + + if (sk->min_type < type) { + sk->min_type = type; sk->min_offset = 0; } else if (sk->min_objectid < BTRFS_LAST_FREE_OBJECTID) { sk->min_objectid++; - sk->min_type = BTRFS_ROOT_BACKREF_KEY; + sk->min_type = type; sk->min_offset = 0; } else break; } + if (!get_gen) { + memset(&args, 0, sizeof(args)); + + sk->tree_id = 1; + sk->max_type = BTRFS_ROOT_ITEM_KEY; + sk->min_type = BTRFS_ROOT_ITEM_KEY; + + sk->min_objectid = BTRFS_FIRST_FREE_OBJECTID; + + sk->max_objectid = BTRFS_LAST_FREE_OBJECTID; + sk->max_offset = (u64)-1; + sk->max_transid = (u64)-1; + + get_gen = 1; + goto again; + } return 0; } @@ -781,13 +828,15 @@ int list_subvols(int fd, int print_parent, int get_default) resolve_root(&root_lookup, entry, &parent_id, &level, &path); if (print_parent) { - printf("ID %llu parent %llu top level %llu path %s\n", + printf("ID %llu gen %llu parent %llu top level %llu path %s\n", (unsigned long long)entry->root_id, + (unsigned long long)entry->gen, (unsigned long long)parent_id, (unsigned long long)level, path); } else { - printf("ID %llu top level %llu path %s\n", + printf("ID %llu gen %llu top level %llu path %s\n", (unsigned long long)entry->root_id, + (unsigned long long)entry->gen, (unsigned long long)level, path); }