|
@@ -219,13 +219,24 @@ static int __shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
|
|
|
if (r < 0)
|
|
|
return r;
|
|
|
|
|
|
- r = dm_bm_unlock_move(orig_block, new);
|
|
|
- if (r < 0) {
|
|
|
+ /*
|
|
|
+ * It would be tempting to use dm_bm_unlock_move here, but some
|
|
|
+ * code, such as the space maps, keeps using the old data structures
|
|
|
+ * secure in the knowledge they won't be changed until the next
|
|
|
+ * transaction. Using unlock_move would force a synchronous read
|
|
|
+ * since the old block would no longer be in the cache.
|
|
|
+ */
|
|
|
+ r = dm_bm_write_lock_zero(tm->bm, new, v, result);
|
|
|
+ if (r) {
|
|
|
dm_bm_unlock(orig_block);
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- return dm_bm_write_lock(tm->bm, new, v, result);
|
|
|
+ memcpy(dm_block_data(*result), dm_block_data(orig_block),
|
|
|
+ dm_bm_block_size(tm->bm));
|
|
|
+
|
|
|
+ dm_bm_unlock(orig_block);
|
|
|
+ return r;
|
|
|
}
|
|
|
|
|
|
int dm_tm_shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
|