Update struct btrfs_header flags, and use it to indicate buffers are written
authorChris Mason <chris.mason@oracle.com>
Tue, 1 Apr 2008 14:20:06 +0000 (10:20 -0400)
committerDavid Woodhouse <dwmw2@hera.kernel.org>
Tue, 1 Apr 2008 14:20:06 +0000 (10:20 -0400)
ctree.c
ctree.h
disk-io.c

diff --git a/ctree.c b/ctree.c
index 88ebd9e..d172875 100644 (file)
--- a/ctree.c
+++ b/ctree.c
@@ -122,6 +122,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
        btrfs_set_header_bytenr(cow, cow->start);
        btrfs_set_header_generation(cow, trans->transid);
        btrfs_set_header_owner(cow, new_root_objectid);
+       btrfs_clear_header_flag(cow, BTRFS_HEADER_FLAG_WRITTEN);
 
        WARN_ON(btrfs_header_generation(buf) > trans->transid);
        ret = btrfs_inc_ref(trans, new_root, buf);
@@ -181,6 +182,7 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans,
        btrfs_set_header_bytenr(cow, cow->start);
        btrfs_set_header_generation(cow, trans->transid);
        btrfs_set_header_owner(cow, root->root_key.objectid);
+       btrfs_clear_header_flag(cow, BTRFS_HEADER_FLAG_WRITTEN);
 
        WARN_ON(btrfs_header_generation(buf) > trans->transid);
        if (btrfs_header_generation(buf) != trans->transid) {
@@ -242,6 +244,10 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
                WARN_ON(1);
        }
        if (btrfs_header_generation(buf) == trans->transid) {
+#if 0
+               &&
+           !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) {
+#endif
                *cow_ret = buf;
                return 0;
        }
@@ -1463,6 +1469,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
        btrfs_set_header_bytenr(split, split->start);
        btrfs_set_header_generation(split, trans->transid);
        btrfs_set_header_owner(split, root->root_key.objectid);
+       btrfs_set_header_flags(split, 0);
        write_extent_buffer(split, root->fs_info->fsid,
                            (unsigned long)btrfs_header_fsid(split),
                            BTRFS_FSID_SIZE);
diff --git a/ctree.h b/ctree.h
index 80397fb..1e4c84a 100644 (file)
--- a/ctree.h
+++ b/ctree.h
@@ -182,6 +182,8 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
 }
 
 #define BTRFS_FSID_SIZE 16
+#define BTRFS_HEADER_FLAG_WRITTEN (1 << 0)
+
 /*
  * every tree block (leaf or node) starts with this header.
  */
@@ -189,10 +191,10 @@ struct btrfs_header {
        u8 csum[BTRFS_CSUM_SIZE];
        u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
        __le64 bytenr; /* which block this node is supposed to live in */
+       __le64 flags;
        __le64 generation;
        __le64 owner;
        __le32 nritems;
-       __le16 flags;
        u8 level;
 } __attribute__ ((__packed__));
 
@@ -220,6 +222,7 @@ struct btrfs_super_block {
        /* the first 3 fields must match struct btrfs_header */
        u8 fsid[BTRFS_FSID_SIZE];    /* FS specific uuid */
        __le64 bytenr; /* this block number */
+       __le64 flags;
        __le64 magic;
        __le64 generation;
        __le64 root;
@@ -1027,9 +1030,28 @@ BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header,
                          generation, 64);
 BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64);
 BTRFS_SETGET_HEADER_FUNCS(header_nritems, struct btrfs_header, nritems, 32);
-BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 16);
+BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 64);
 BTRFS_SETGET_HEADER_FUNCS(header_level, struct btrfs_header, level, 8);
 
+static inline int btrfs_header_flag(struct extent_buffer *eb, u64 flag)
+{
+       return (btrfs_header_flags(eb) & flag) == flag;
+}
+
+static inline int btrfs_set_header_flag(struct extent_buffer *eb, u64 flag)
+{
+       u64 flags = btrfs_header_flags(eb);
+       btrfs_set_header_flags(eb, flags | flag);
+       return (flags & flag) == flag;
+}
+
+static inline int btrfs_clear_header_flag(struct extent_buffer *eb, u64 flag)
+{
+       u64 flags = btrfs_header_flags(eb);
+       btrfs_set_header_flags(eb, flags & ~flag);
+       return (flags & flag) == flag;
+}
+
 static inline u8 *btrfs_header_fsid(struct extent_buffer *eb)
 {
        unsigned long ptr = offsetof(struct btrfs_header, fsid);
index 1afe5a6..0636404 100644 (file)
--- a/disk-io.c
+++ b/disk-io.c
@@ -140,6 +140,8 @@ int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                BUG();
        if (!btrfs_buffer_uptodate(eb))
                BUG();
+
+       btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
        btrfs_map_bh_to_logical(root, eb, eb->start);
        csum_tree_block(root, eb, 0);
        return write_extent_to_disk(eb);