#define BTRFS_INODE_DIRSYNC            (1 << 10)
 #define BTRFS_INODE_COMPRESS           (1 << 11)
 
+#define BTRFS_INODE_ROOT_ITEM_INIT     (1 << 31)
+
 /* some macros to generate set/get funcs for the struct fields.  This
  * assumes there is a lefoo_to_cpu for every type, so lets make a simple
  * one for u8:
 int btrfs_find_orphan_roots(struct btrfs_root *tree_root);
 int btrfs_set_root_node(struct btrfs_root_item *item,
                        struct extent_buffer *node);
+void btrfs_check_and_init_root_item(struct btrfs_root_item *item);
+
 /* dir-item.c */
 int btrfs_insert_dir_item(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root, const char *name,
 
        root->commit_root = btrfs_root_node(root);
        BUG_ON(!root->node);
 out:
-       if (location->objectid != BTRFS_TREE_LOG_OBJECTID)
+       if (location->objectid != BTRFS_TREE_LOG_OBJECTID) {
                root->ref_cows = 1;
+               btrfs_check_and_init_root_item(&root->root_item);
+       }
 
        return root;
 }
 
        inode_item->nbytes = cpu_to_le64(root->leafsize);
        inode_item->mode = cpu_to_le32(S_IFDIR | 0755);
 
+       root_item.flags = 0;
+       root_item.byte_limit = 0;
+       inode_item->flags = cpu_to_le64(BTRFS_INODE_ROOT_ITEM_INIT);
+
        btrfs_set_root_bytenr(&root_item, leaf->start);
        btrfs_set_root_generation(&root_item, trans->transid);
        btrfs_set_root_level(&root_item, 0);
 
        btrfs_free_path(path);
        return 0;
 }
+
+/*
+ * Old btrfs forgets to init root_item->flags and root_item->byte_limit
+ * for subvolumes. To work around this problem, we steal a bit from
+ * root_item->inode_item->flags, and use it to indicate if those fields
+ * have been properly initialized.
+ */
+void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item)
+{
+       u64 inode_flags = le64_to_cpu(root_item->inode.flags);
+
+       if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) {
+               inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT;
+               root_item->inode.flags = cpu_to_le64(inode_flags);
+               root_item->flags = 0;
+               root_item->byte_limit = 0;
+       }
+}
 
        record_root_in_trans(trans, root);
        btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
        memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
+       btrfs_check_and_init_root_item(new_root_item);
 
        root_flags = btrfs_root_flags(new_root_item);
        if (pending->readonly)