+ u64 cur_offset = 0;
+ u64 cur_len;
+ int ret = 0;
+
+ while (cur_offset < len) {
+ struct btrfs_device *device;
+ int i;
+
+ cur_len = len - cur_offset;
+ ret = btrfs_map_block(fs_info, READ, logical + cur_offset,
+ &cur_len, &multi, mirror_num, NULL);
+ if (ret) {
+ fprintf(info_file,
+ "Error: fails to map mirror%d logical %llu: %s\n",
+ mirror_num, logical, strerror(-ret));
+ return ret;
+ }
+ for (i = 0; i < multi->num_stripes; i++) {
+ device = multi->stripes[i].dev;
+ fprintf(info_file,
+ "mirror %d logical %Lu physical %Lu device %s\n",
+ mirror_num, logical + cur_offset,
+ multi->stripes[0].physical,
+ device->name);
+ }
+ free(multi);
+ multi = NULL;
+ cur_offset += cur_len;
+ }
+ return ret;
+}
+
+/*
+ * Logical and len is the exact value of a extent.
+ * And offset is the offset inside the extent. It's only used for case
+ * where user only want to print part of the extent.
+ *
+ * Caller *MUST* ensure the range [logical,logical+len) are in one extent.
+ * Or we can encounter the following case, causing a -ENOENT error:
+ * |<-----given parameter------>|
+ * |<------ Extent A ----->|
+ */
+static int print_mapping_info(struct btrfs_fs_info *fs_info, u64 logical,
+ u64 len)
+{