|
@@ -1067,15 +1067,31 @@ again:
|
|
|
|
|
|
map = (struct map_lookup *)em->bdev;
|
|
|
for (i = 0; i < map->num_stripes; i++) {
|
|
|
+ u64 end;
|
|
|
+
|
|
|
if (map->stripes[i].dev != device)
|
|
|
continue;
|
|
|
if (map->stripes[i].physical >= physical_start + len ||
|
|
|
map->stripes[i].physical + em->orig_block_len <=
|
|
|
physical_start)
|
|
|
continue;
|
|
|
- *start = map->stripes[i].physical +
|
|
|
- em->orig_block_len;
|
|
|
- ret = 1;
|
|
|
+ /*
|
|
|
+ * Make sure that while processing the pinned list we do
|
|
|
+ * not override our *start with a lower value, because
|
|
|
+ * we can have pinned chunks that fall within this
|
|
|
+ * device hole and that have lower physical addresses
|
|
|
+ * than the pending chunks we processed before. If we
|
|
|
+ * do not take this special care we can end up getting
|
|
|
+ * 2 pending chunks that start at the same physical
|
|
|
+ * device offsets because the end offset of a pinned
|
|
|
+ * chunk can be equal to the start offset of some
|
|
|
+ * pending chunk.
|
|
|
+ */
|
|
|
+ end = map->stripes[i].physical + em->orig_block_len;
|
|
|
+ if (end > *start) {
|
|
|
+ *start = end;
|
|
|
+ ret = 1;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
if (search_list == &trans->transaction->pending_chunks) {
|