|
@@ -328,22 +328,39 @@ static void coroutine_fn GRAPH_RDLOCK
|
|
|
blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
|
|
|
{
|
|
|
BDRVBlkLogWritesState *s = lr->bs->opaque;
|
|
|
- uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
|
|
|
|
|
|
- s->nr_entries++;
|
|
|
- s->cur_log_sector +=
|
|
|
- ROUND_UP(lr->qiov->size, s->sectorsize) >> s->sectorbits;
|
|
|
+ /*
|
|
|
+ * Determine the offsets and sizes of different parts of the entry, and
|
|
|
+ * update the state of the driver.
|
|
|
+ *
|
|
|
+ * This needs to be done in one go, before any actual I/O is done, as the
|
|
|
+ * log entry may have to be written in two parts, and the state of the
|
|
|
+ * driver may be modified by other driver operations while waiting for the
|
|
|
+ * I/O to complete.
|
|
|
+ */
|
|
|
+ const uint64_t entry_start_sector = s->cur_log_sector;
|
|
|
+ const uint64_t entry_offset = entry_start_sector << s->sectorbits;
|
|
|
+ const uint64_t qiov_aligned_size = ROUND_UP(lr->qiov->size, s->sectorsize);
|
|
|
+ const uint64_t entry_aligned_size = qiov_aligned_size +
|
|
|
+ ROUND_UP(lr->zero_size, s->sectorsize);
|
|
|
+ const uint64_t entry_nr_sectors = entry_aligned_size >> s->sectorbits;
|
|
|
|
|
|
- lr->log_ret = bdrv_co_pwritev(s->log_file, cur_log_offset, lr->qiov->size,
|
|
|
+ s->nr_entries++;
|
|
|
+ s->cur_log_sector += entry_nr_sectors;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Write the log entry. Note that if this is a "write zeroes" operation,
|
|
|
+ * only the entry header is written here, with the zeroing being done
|
|
|
+ * separately below.
|
|
|
+ */
|
|
|
+ lr->log_ret = bdrv_co_pwritev(s->log_file, entry_offset, lr->qiov->size,
|
|
|
lr->qiov, 0);
|
|
|
|
|
|
/* Logging for the "write zeroes" operation */
|
|
|
if (lr->log_ret == 0 && lr->zero_size) {
|
|
|
- cur_log_offset = s->cur_log_sector << s->sectorbits;
|
|
|
- s->cur_log_sector +=
|
|
|
- ROUND_UP(lr->zero_size, s->sectorsize) >> s->sectorbits;
|
|
|
+ const uint64_t zeroes_offset = entry_offset + qiov_aligned_size;
|
|
|
|
|
|
- lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, cur_log_offset,
|
|
|
+ lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, zeroes_offset,
|
|
|
lr->zero_size, 0);
|
|
|
}
|
|
|
|