summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-09-01 16:45:30 +0800
committerroot <root@localhost.localdomain>2012-10-04 16:26:32 -0400
commit7cb1cf754229062ea412aa651a0f750ce42c113d (patch)
tree8a06b465224bcc81b9c69be3c96c69a5fa07cef2
parentf0d08f254cf502ffbd69df543b6e938c9e1fe583 (diff)
Btrfs-progs: fix wrong way to check if the root item contains otime and uuid
Now we check if the root item contains otime and uuid or not by comparing ->generation_v2 and ->generation of the btrfs_root_item structure, it is wrong because it is possbile that ->generation may equal to the first variant of the next item. We fix this problem by check the size of btrfs_root_item, if it is larger than the original one, the new btrfs_root_item contains otime and uuid. we needn't worry the case that the new filesystem is mounted on the old kernel. because the otime and uuid are not changed on the old kernel, we can get the correct result even on the kernel. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
-rw-r--r--btrfs-list.c9
-rw-r--r--ctree.h15
2 files changed, 21 insertions, 3 deletions
diff --git a/btrfs-list.c b/btrfs-list.c
index ef621f03..ed280210 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -737,7 +737,8 @@ again:
} else if (get_gen && sh->type == BTRFS_ROOT_ITEM_KEY) {
ri = (struct btrfs_root_item *)(args.buf + off);
gen = btrfs_root_generation(ri);
- if(ri->generation == ri->generation_v2) {
+ if(sh->len >
+ sizeof(struct btrfs_root_item_v0)) {
t = ri->otime.sec;
memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
} else {
@@ -844,9 +845,11 @@ static int __list_snapshot_search(int fd, struct root_lookup *root_lookup)
off += sizeof(*sh);
if (sh->type == BTRFS_ROOT_ITEM_KEY && sh->offset) {
item = (struct btrfs_root_item *)(args.buf + off);
- if(item->generation == item->generation_v2) {
+ if(sh->len >
+ sizeof(struct btrfs_root_item_v0)) {
t = item->otime.sec;
- memcpy(uuid, item->uuid, BTRFS_UUID_SIZE);
+ memcpy(uuid, item->uuid,
+ BTRFS_UUID_SIZE);
} else {
t = 0;
memset(uuid, 0, BTRFS_UUID_SIZE);
diff --git a/ctree.h b/ctree.h
index 7f552291..c55d0338 100644
--- a/ctree.h
+++ b/ctree.h
@@ -637,6 +637,21 @@ struct btrfs_dir_item {
u8 type;
} __attribute__ ((__packed__));
+struct btrfs_root_item_v0 {
+ struct btrfs_inode_item inode;
+ __le64 generation;
+ __le64 root_dirid;
+ __le64 bytenr;
+ __le64 byte_limit;
+ __le64 bytes_used;
+ __le64 last_snapshot;
+ __le64 flags;
+ __le32 refs;
+ struct btrfs_disk_key drop_progress;
+ u8 drop_level;
+ u8 level;
+} __attribute__ ((__packed__));
+
struct btrfs_root_item {
struct btrfs_inode_item inode;
__le64 generation;