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);
        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) {
        }
 
        header_trans = btrfs_header_generation(buf);
-       if (header_trans == trans->transid) {
+       spin_lock(&root->fs_info->hash_lock);
+       if (header_trans == trans->transid &&
+           !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) {
                *cow_ret = buf;
+               spin_unlock(&root->fs_info->hash_lock);
                return 0;
        }
-
+       spin_unlock(&root->fs_info->hash_lock);
        search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1);
        ret = __btrfs_cow_block(trans, root, buf, parent,
                                 parent_slot, cow_ret, search_start, 0);
        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);
 
 }
 
 #define BTRFS_FSID_SIZE 16
+#define BTRFS_HEADER_FLAG_WRITTEN (1 << 0)
+
 /*
  * every tree block (leaf or node) starts with this 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__));
 
  */
 struct btrfs_super_block {
        u8 csum[BTRFS_CSUM_SIZE];
-       /* the first 3 fields must match struct btrfs_header */
+       /* the first 4 fields must match struct btrfs_header */
        u8 fsid[16];    /* FS specific uuid */
        __le64 bytenr; /* this block number */
+       __le64 flags;
        __le64 magic;
        __le64 generation;
        __le64 root;
                          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);
 
                        from_this_trans = 1;
 
                /* FIXME, this is not good */
-               if (from_this_trans == 0 &&
-                   memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) {
+               if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) {
                        u32 val;
                        u32 found = 0;
                        memcpy(&found, result, BTRFS_CRC32_SIZE);
 
                        read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE);
+                       WARN_ON(1);
                        printk("btrfs: %s checksum verify failed on %llu "
-                              "wanted %X found %X from_this_trans %d\n",
+                              "wanted %X found %X from_this_trans %d "
+                              "level %d\n",
                               root->fs_info->sb->s_id,
-                              buf->start, val, found, from_this_trans);
+                              buf->start, val, found, from_this_trans,
+                              btrfs_header_level(buf));
                        return 1;
                }
        } else {
                goto err;
        }
        found_level = btrfs_header_level(eb);
+       spin_lock(&root->fs_info->hash_lock);
+       btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
+       spin_unlock(&root->fs_info->hash_lock);
        csum_tree_block(root, eb, 0);
 err:
        free_extent_buffer(eb);