int slot)
 {
        struct btrfs_fs_info *fs_info = leaf->fs_info;
-       struct btrfs_root_item ri;
+       struct btrfs_root_item ri = { 0 };
        const u64 valid_root_flags = BTRFS_ROOT_SUBVOL_RDONLY |
                                     BTRFS_ROOT_SUBVOL_DEAD;
        int ret;
        if (ret < 0)
                return ret;
 
-       if (btrfs_item_size_nr(leaf, slot) != sizeof(ri)) {
+       if (btrfs_item_size_nr(leaf, slot) != sizeof(ri) &&
+           btrfs_item_size_nr(leaf, slot) != btrfs_legacy_root_item_size()) {
                generic_err(leaf, slot,
-                           "invalid root item size, have %u expect %zu",
-                           btrfs_item_size_nr(leaf, slot), sizeof(ri));
+                           "invalid root item size, have %u expect %zu or %u",
+                           btrfs_item_size_nr(leaf, slot), sizeof(ri),
+                           btrfs_legacy_root_item_size());
        }
 
+       /*
+        * For legacy root item, the members starting at generation_v2 will be
+        * all filled with 0.
+        * And since we allow geneartion_v2 as 0, it will still pass the check.
+        */
        read_extent_buffer(leaf, &ri, btrfs_item_ptr_offset(leaf, slot),
-                          sizeof(ri));
+                          btrfs_item_size_nr(leaf, slot));
 
        /* Generation related */
        if (btrfs_root_generation(&ri) >
 
 
 #include <linux/btrfs.h>
 #include <linux/types.h>
+#ifdef __KERNEL__
+#include <linux/stddef.h>
+#else
+#include <stddef.h>
+#endif
 
 /*
  * This header contains the structure definitions and constants used
        __le64 reserved[8]; /* for future */
 } __attribute__ ((__packed__));
 
+/*
+ * Btrfs root item used to be smaller than current size.  The old format ends
+ * at where member generation_v2 is.
+ */
+static inline __u32 btrfs_legacy_root_item_size(void)
+{
+       return offsetof(struct btrfs_root_item, generation_v2);
+}
+
 /*
  * this is used for both forward and backward root refs
  */