*generation_ret = btrfs_extent_generation(path->nodes[0], ei);
 }
 
+static bool does_range_cross_boundary(u64 extent_start, u64 extent_len,
+                                     u64 boundary_start, u64 boudary_len)
+{
+       return (extent_start < boundary_start &&
+               extent_start + extent_len > boundary_start) ||
+              (extent_start < boundary_start + boudary_len &&
+               extent_start + extent_len > boundary_start + boudary_len);
+}
+
 static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx,
                                                  struct map_lookup *map,
                                                  struct btrfs_device *sdev,
        return ret;
 }
 
-static bool does_range_cross_boundary(u64 extent_start, u64 extent_len,
-                                     u64 boundary_start, u64 boudary_len)
-{
-       return (extent_start < boundary_start &&
-               extent_start + extent_len > boundary_start) ||
-              (extent_start < boundary_start + boudary_len &&
-               extent_start + extent_len > boundary_start + boudary_len);
-}
-
 /*
  * Scrub one range which can only has simple mirror based profile.
  * (Including all range in SINGLE/DUP/RAID1/RAID1C*, and each stripe in
        return ret;
 }
 
+/* Calculate the full stripe length for simple stripe based profiles */
+static u64 simple_stripe_full_stripe_len(const struct map_lookup *map)
+{
+       ASSERT(map->type & (BTRFS_BLOCK_GROUP_RAID0 |
+                           BTRFS_BLOCK_GROUP_RAID10));
+
+       return map->num_stripes / map->sub_stripes * map->stripe_len;
+}
+
+/* Get the logical bytenr for the stripe */
+static u64 simple_stripe_get_logical(struct map_lookup *map,
+                                    struct btrfs_block_group *bg,
+                                    int stripe_index)
+{
+       ASSERT(map->type & (BTRFS_BLOCK_GROUP_RAID0 |
+                           BTRFS_BLOCK_GROUP_RAID10));
+       ASSERT(stripe_index < map->num_stripes);
+
+       /*
+        * (stripe_index / sub_stripes) gives how many data stripes we need to
+        * skip.
+        */
+       return (stripe_index / map->sub_stripes) * map->stripe_len + bg->start;
+}
+
+/* Get the mirror number for the stripe */
+static int simple_stripe_mirror_num(struct map_lookup *map, int stripe_index)
+{
+       ASSERT(map->type & (BTRFS_BLOCK_GROUP_RAID0 |
+                           BTRFS_BLOCK_GROUP_RAID10));
+       ASSERT(stripe_index < map->num_stripes);
+
+       /* For RAID0, it's fixed to 1, for RAID10 it's 0,1,0,1... */
+       return stripe_index % map->sub_stripes + 1;
+}
+
+static int scrub_simple_stripe(struct scrub_ctx *sctx,
+                              struct btrfs_root *extent_root,
+                              struct btrfs_root *csum_root,
+                              struct btrfs_block_group *bg,
+                              struct map_lookup *map,
+                              struct btrfs_device *device,
+                              int stripe_index)
+{
+       const u64 logical_increment = simple_stripe_full_stripe_len(map);
+       const u64 orig_logical = simple_stripe_get_logical(map, bg, stripe_index);
+       const u64 orig_physical = map->stripes[stripe_index].physical;
+       const int mirror_num = simple_stripe_mirror_num(map, stripe_index);
+       u64 cur_logical = orig_logical;
+       u64 cur_physical = orig_physical;
+       int ret = 0;
+
+       while (cur_logical < bg->start + bg->length) {
+               /*
+                * Inside each stripe, RAID0 is just SINGLE, and RAID10 is
+                * just RAID1, so we can reuse scrub_simple_mirror() to scrub
+                * this stripe.
+                */
+               ret = scrub_simple_mirror(sctx, extent_root, csum_root, bg, map,
+                                         cur_logical, map->stripe_len, device,
+                                         cur_physical, mirror_num);
+               if (ret)
+                       return ret;
+               /* Skip to next stripe which belongs to the target device */
+               cur_logical += logical_increment;
+               /* For physical offset, we just go to next stripe */
+               cur_physical += map->stripe_len;
+       }
+       return ret;
+}
+
 static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
                                           struct btrfs_block_group *bg,
                                           struct map_lookup *map,
                                stripe_index + 1);
                goto out;
        }
-       /*
-        * now find all extents for each stripe and scrub them
-        */
+       if (profile & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) {
+               ret = scrub_simple_stripe(sctx, root, csum_root, bg, map,
+                                         scrub_dev, stripe_index);
+               goto out;
+       }
+
+       /* Only RAID56 goes through the old code */
+       ASSERT(map->type & BTRFS_BLOCK_GROUP_RAID56_MASK);
        ret = 0;
        while (physical < physical_end) {
                /*