From patchwork Wed Jul 4 13:39:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Block X-Patchwork-Id: 1156181 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 6D4EDDFFF7 for ; Wed, 4 Jul 2012 13:40:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752932Ab2GDNkQ (ORCPT ); Wed, 4 Jul 2012 09:40:16 -0400 Received: from mail-bk0-f46.google.com ([209.85.214.46]:64940 "EHLO mail-bk0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750797Ab2GDNkN (ORCPT ); Wed, 4 Jul 2012 09:40:13 -0400 Received: by mail-bk0-f46.google.com with SMTP id j10so2633951bkw.19 for ; Wed, 04 Jul 2012 06:40:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=Kyb9OXQsm4hibkFuCIedNWz04p+NjmeTXzdFejc0jyo=; b=pObFgYNUX7cwCNJJ7fMDrDMnLCMEnKn0sM7DhSIKi3duKpqabvqC1W9/8YpcvXjky0 urKxXBRq3Y7dAAI6oso8U580zUlkmKjfA9nidbgfmzxhpI/FOvmrbwETPn97fZaJzbSh X+pq+19lzeVIIPDOdnbhyIQ1kt3xPCbrVU/b9Lt81S6HpCQ4DEwoYzKtckjpwvA5woVJ ZQyCkkLOeVxtQEAWeVEo+UPXp1eSRP4AFYK004zByircPyZlm5ez6nym6CWZB5WNdWIg Oo36Ib26c6eauCjPnOxBdYLkFDKEZ+RDeMWRL8go4Pm6J1E8yV2gqyD2+PhNxP1SqURx vTFQ== Received: by 10.204.9.199 with SMTP id m7mr11661316bkm.66.1341409212147; Wed, 04 Jul 2012 06:40:12 -0700 (PDT) Received: from localhost.localdomain (p4FEF4B20.dip.t-dialin.net. [79.239.75.32]) by mx.google.com with ESMTPS id h18sm19032244bkh.8.2012.07.04.06.40.10 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 04 Jul 2012 06:40:11 -0700 (PDT) From: Alexander Block To: linux-btrfs@vger.kernel.org Cc: Alexander Block Subject: [RFC PATCH 4/6] Btrfs-progs: update btrfs-progs for subvol uuid+times support Date: Wed, 4 Jul 2012 15:39:32 +0200 Message-Id: <1341409174-13619-5-git-send-email-ablock84@googlemail.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1341409174-13619-1-git-send-email-ablock84@googlemail.com> References: <1341409174-13619-1-git-send-email-ablock84@googlemail.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Update ctree.h and ioctl.h for the new uuid+times for subvolumes. Signed-off-by: Alexander Block --- ctree.h | 40 ++++++++++++++++++++++++++++- ioctl.h | 12 +++++++++ print-tree.c | 79 +++++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 112 insertions(+), 19 deletions(-) diff --git a/ctree.h b/ctree.h index 254fb0b..07691c7 100644 --- a/ctree.h +++ b/ctree.h @@ -642,6 +642,35 @@ struct btrfs_root_item { struct btrfs_disk_key drop_progress; u8 drop_level; u8 level; + + /* + * The following fields appear after subvol_uuids+subvol_times + * were introduced. + */ + + /* + * This generation number is used to test if the new fields are valid + * and up to date while reading the root item. Everytime the root item + * is written out, the "generation" field is copied into this field. If + * anyone ever mounted the fs with an older kernel, we will have + * mismatching generation values here and thus must invalidate the + * new fields. See btrfs_update_root and btrfs_find_last_root for + * details. + * the offset of generation_v2 is also used as the start for the memset + * when invalidating the fields. + */ + __le64 generation_v2; + u8 uuid[BTRFS_UUID_SIZE]; + u8 parent_uuid[BTRFS_UUID_SIZE]; + u8 received_uuid[BTRFS_UUID_SIZE]; + __le64 ctransid; /* updated when an inode changes */ + __le64 otransid; /* trans when created */ + __le64 stransid; /* trans when sent. non-zero for received subvol */ + __le64 rtransid; /* trans when received. non-zero for received subvol */ + struct btrfs_timespec ctime; + struct btrfs_timespec otime; + struct btrfs_timespec stime; + struct btrfs_timespec rtime; } __attribute__ ((__packed__)); /* @@ -1607,7 +1636,16 @@ BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, bytes_used, 64); BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64); BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, last_snapshot, 64); - +BTRFS_SETGET_STACK_FUNCS(root_generation_v2, struct btrfs_root_item, + generation_v2, 64); +BTRFS_SETGET_STACK_FUNCS(root_ctransid, struct btrfs_root_item, + ctransid, 64); +BTRFS_SETGET_STACK_FUNCS(root_otransid, struct btrfs_root_item, + otransid, 64); +BTRFS_SETGET_STACK_FUNCS(root_stransid, struct btrfs_root_item, + stransid, 64); +BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item, + rtransid, 64); /* struct btrfs_root_backup */ BTRFS_SETGET_STACK_FUNCS(backup_tree_root, struct btrfs_root_backup, diff --git a/ioctl.h b/ioctl.h index 023ca4c..77503e6 100644 --- a/ioctl.h +++ b/ioctl.h @@ -20,6 +20,7 @@ #define __IOCTL_ #include #include +#include #define BTRFS_IOCTL_MAGIC 0x94 #define BTRFS_VOL_NAME_MAX 255 @@ -272,6 +273,15 @@ struct btrfs_ioctl_logical_ino_args { __u64 inodes; }; +struct btrfs_ioctl_received_subvol_args { + char uuid[BTRFS_UUID_SIZE]; /* in */ + __u64 stransid; /* in */ + __u64 rtransid; /* out */ + struct timespec stime; /* in */ + struct timespec rtime; /* out */ + __u64 reserved[16]; +}; + /* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */ #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) @@ -341,4 +351,6 @@ struct btrfs_ioctl_clone_range_args { #define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \ struct btrfs_ioctl_ino_path_args) +#define BTRFS_IOC_SET_RECEIVED_SUBVOL _IOWR(BTRFS_IOCTL_MAGIC, 37, \ + struct btrfs_ioctl_received_subvol_args) #endif diff --git a/print-tree.c b/print-tree.c index 1377732..d9f669a 100644 --- a/print-tree.c +++ b/print-tree.c @@ -282,6 +282,66 @@ static void print_root_ref(struct extent_buffer *leaf, int slot, char *tag) namelen, namebuf); } +static int count_bytes(void *buf, int len, char b) +{ + int cnt = 0; + int i; + for (i = 0; i < len; i++) { + if (((char*)buf)[i] == b) + cnt++; + } + return cnt; +} + +static void print_root(struct extent_buffer *leaf, int slot) +{ + struct btrfs_root_item *ri; + struct btrfs_root_item root_item; + int len; + char uuid_str[128]; + + ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item); + len = btrfs_item_size_nr(leaf, slot); + + memset(&root_item, 0, sizeof(root_item)); + read_extent_buffer(leaf, &root_item, (unsigned long)ri, len); + + printf("\t\troot data bytenr %llu level %d dirid %llu refs %u gen %llu\n", + (unsigned long long)btrfs_root_bytenr(&root_item), + btrfs_root_level(&root_item), + (unsigned long long)btrfs_root_dirid(&root_item), + btrfs_root_refs(&root_item), + (unsigned long long)btrfs_root_generation(&root_item)); + + if (root_item.generation == root_item.generation_v2) { + uuid_unparse(root_item.uuid, uuid_str); + printf("\t\tuuid %s\n", uuid_str); + if (count_bytes(root_item.parent_uuid, BTRFS_UUID_SIZE, 0) != BTRFS_UUID_SIZE) { + uuid_unparse(root_item.parent_uuid, uuid_str); + printf("\t\tparent_uuid %s\n", uuid_str); + } + if (count_bytes(root_item.received_uuid, BTRFS_UUID_SIZE, 0) != BTRFS_UUID_SIZE) { + uuid_unparse(root_item.received_uuid, uuid_str); + printf("\t\treceived_uuid %s\n", uuid_str); + } + if (root_item.ctransid) { + printf("\t\tctransid %llu otransid %llu stransid %llu rtransid %llu\n", + btrfs_root_ctransid(&root_item), + btrfs_root_otransid(&root_item), + btrfs_root_stransid(&root_item), + btrfs_root_rtransid(&root_item)); + } + } + if (btrfs_root_refs(&root_item) == 0) { + struct btrfs_key drop_key; + btrfs_disk_key_to_cpu(&drop_key, + &root_item.drop_progress); + printf("\t\tdrop "); + btrfs_print_key(&root_item.drop_progress); + printf(" level %d\n", root_item.drop_level); + } +} + static void print_key_type(u8 type) { switch (type) { @@ -452,7 +512,6 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) int i; char *str; struct btrfs_item *item; - struct btrfs_root_item *ri; struct btrfs_dir_item *di; struct btrfs_inode_item *ii; struct btrfs_file_extent_item *fi; @@ -462,7 +521,6 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) struct btrfs_inode_ref *iref; struct btrfs_dev_extent *dev_extent; struct btrfs_disk_key disk_key; - struct btrfs_root_item root_item; struct btrfs_block_group_item bg_item; struct btrfs_dir_log_item *dlog; u32 nr = btrfs_header_nritems(l); @@ -515,22 +573,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) printf("\t\torphan item\n"); break; case BTRFS_ROOT_ITEM_KEY: - ri = btrfs_item_ptr(l, i, struct btrfs_root_item); - read_extent_buffer(l, &root_item, (unsigned long)ri, sizeof(root_item)); - printf("\t\troot data bytenr %llu level %d dirid %llu refs %u gen %llu\n", - (unsigned long long)btrfs_root_bytenr(&root_item), - btrfs_root_level(&root_item), - (unsigned long long)btrfs_root_dirid(&root_item), - btrfs_root_refs(&root_item), - (unsigned long long)btrfs_root_generation(&root_item)); - if (btrfs_root_refs(&root_item) == 0) { - struct btrfs_key drop_key; - btrfs_disk_key_to_cpu(&drop_key, - &root_item.drop_progress); - printf("\t\tdrop "); - btrfs_print_key(&root_item.drop_progress); - printf(" level %d\n", root_item.drop_level); - } + print_root(l, i); break; case BTRFS_ROOT_REF_KEY: print_root_ref(l, i, "ref");