Lines Matching +full:- +full:- +full:disable +full:- +full:live +full:- +full:block +full:- +full:migration
2 * Block driver for Parallels disk image format
32 #include "qemu/error-report.h"
34 #include "block/block_int.h"
35 #include "block/qdict.h"
36 #include "system/block-backend.h"
40 #include "qapi/qobject-input-visitor.h"
41 #include "qapi/qapi-visit-block-core.h"
45 #include "migration/blocker.h"
64 #define PARALLELS_OPT_PREALLOC_MODE "prealloc-mode"
65 #define PARALLELS_OPT_PREALLOC_SIZE "prealloc-size"
89 .name = "parallels-create-opts",
110 return (uint64_t)le32_to_cpu(s->bat_bitmap[idx]) * s->off_multiplier; in bat2sect()
122 index = sector_num / s->tracks; in seek_to_sector()
123 offset = sector_num % s->tracks; in seek_to_sector()
126 if ((index >= s->bat_size) || (s->bat_bitmap[index] == 0)) { in seek_to_sector()
127 return -1; in seek_to_sector()
135 int ret = s->tracks - sector_num % s->tracks; in cluster_remainder()
141 off -= s->data_start << BDRV_SECTOR_BITS; in host_cluster_index()
142 return off / s->cluster_size; in host_cluster_index()
148 int64_t start_off = -2, prev_end_off = -2; in block_status()
151 while (nb_sectors > 0 || start_off == -2) { in block_status()
155 if (start_off == -2) { in block_status()
163 nb_sectors -= to_end; in block_status()
177 s->bat_bitmap[index] = cpu_to_le32(offset); in parallels_set_bat_entry()
178 bitmap_set(s->bat_dirty_bmap, bat_entry_off(index) / s->bat_dirty_block, 1); in parallels_set_bat_entry()
184 BDRVParallelsState *s = bs->opaque; in mark_used()
188 return -E2BIG; in mark_used()
192 return -EBUSY; in mark_used()
205 BDRVParallelsState *s = bs->opaque; in parallels_fill_used_bitmap()
210 payload_bytes = bdrv_getlength(bs->file->bs); in parallels_fill_used_bitmap()
214 payload_bytes -= s->data_start * BDRV_SECTOR_SIZE; in parallels_fill_used_bitmap()
216 return -EINVAL; in parallels_fill_used_bitmap()
219 s->used_bmap_size = DIV_ROUND_UP(payload_bytes, s->cluster_size); in parallels_fill_used_bitmap()
220 if (s->used_bmap_size == 0) { in parallels_fill_used_bitmap()
223 s->used_bmap = bitmap_try_new(s->used_bmap_size); in parallels_fill_used_bitmap()
224 if (s->used_bmap == NULL) { in parallels_fill_used_bitmap()
225 return -ENOMEM; in parallels_fill_used_bitmap()
228 for (i = 0; i < s->bat_size; i++) { in parallels_fill_used_bitmap()
235 err2 = mark_used(bs, s->used_bmap, s->used_bmap_size, host_off, 1); in parallels_fill_used_bitmap()
245 BDRVParallelsState *s = bs->opaque; in parallels_free_used_bitmap()
246 s->used_bmap_size = 0; in parallels_free_used_bitmap()
247 g_free(s->used_bmap); in parallels_free_used_bitmap()
255 BDRVParallelsState *s = bs->opaque; in allocate_clusters()
263 idx = sector_num / s->tracks; in allocate_clusters()
264 to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx; in allocate_clusters()
268 * pass a sector_num at or beyond the end of the image (because the block in allocate_clusters()
270 * is always below s->bat_size. in allocate_clusters()
273 * s->bat_size. in allocate_clusters()
274 * Note that s->bat_size is an unsigned int, therefore idx + to_allocate in allocate_clusters()
277 assert(idx < s->bat_size && idx + to_allocate <= s->bat_size); in allocate_clusters()
279 first_free = find_first_zero_bit(s->used_bmap, s->used_bmap_size); in allocate_clusters()
280 if (first_free == s->used_bmap_size) { in allocate_clusters()
282 int64_t bytes = to_allocate * s->cluster_size; in allocate_clusters()
283 bytes += s->prealloc_size * BDRV_SECTOR_SIZE; in allocate_clusters()
285 host_off = s->data_end * BDRV_SECTOR_SIZE; in allocate_clusters()
290 * force the safer-but-slower fallocate. in allocate_clusters()
292 if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) { in allocate_clusters()
293 ret = bdrv_co_truncate(bs->file, host_off + bytes, in allocate_clusters()
296 if (ret == -ENOTSUP) { in allocate_clusters()
297 s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE; in allocate_clusters()
300 if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { in allocate_clusters()
301 ret = bdrv_co_pwrite_zeroes(bs->file, host_off, bytes, 0); in allocate_clusters()
307 new_usedsize = s->used_bmap_size + bytes / s->cluster_size; in allocate_clusters()
308 s->used_bmap = bitmap_zero_extend(s->used_bmap, s->used_bmap_size, in allocate_clusters()
310 s->used_bmap_size = new_usedsize; in allocate_clusters()
313 next_used = find_next_bit(s->used_bmap, s->used_bmap_size, first_free); in allocate_clusters()
316 if (next_used - first_free < to_allocate) { in allocate_clusters()
317 to_allocate = next_used - first_free; in allocate_clusters()
318 *pnum = (idx + to_allocate) * s->tracks - sector_num; in allocate_clusters()
321 host_off = s->data_start * BDRV_SECTOR_SIZE; in allocate_clusters()
322 host_off += first_free * s->cluster_size; in allocate_clusters()
326 * branch. In the other case we are likely re-using hole. Preallocate in allocate_clusters()
329 if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE && in allocate_clusters()
330 host_off < s->data_end * BDRV_SECTOR_SIZE) { in allocate_clusters()
331 ret = bdrv_co_pwrite_zeroes(bs->file, host_off, in allocate_clusters()
332 s->cluster_size * to_allocate, 0); in allocate_clusters()
343 * parallels_co_writev. On aligned-to-cluster write we do not need in allocate_clusters()
348 if (bs->backing) { in allocate_clusters()
349 int64_t nb_cow_sectors = to_allocate * s->tracks; in allocate_clusters()
353 ret = bdrv_co_pread(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE, in allocate_clusters()
360 ret = bdrv_co_pwrite(bs->file, s->data_end * BDRV_SECTOR_SIZE, in allocate_clusters()
368 ret = mark_used(bs, s->used_bmap, s->used_bmap_size, host_off, to_allocate); in allocate_clusters()
375 host_off / BDRV_SECTOR_SIZE / s->off_multiplier); in allocate_clusters()
376 host_off += s->cluster_size; in allocate_clusters()
378 if (host_off > s->data_end * BDRV_SECTOR_SIZE) { in allocate_clusters()
379 s->data_end = host_off / BDRV_SECTOR_SIZE; in allocate_clusters()
382 return bat2sect(s, idx) + sector_num % s->tracks; in allocate_clusters()
389 BDRVParallelsState *s = bs->opaque; in parallels_co_flush_to_os()
390 unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block); in parallels_co_flush_to_os()
393 qemu_co_mutex_lock(&s->lock); in parallels_co_flush_to_os()
395 bit = find_first_bit(s->bat_dirty_bmap, size); in parallels_co_flush_to_os()
397 uint32_t off = bit * s->bat_dirty_block; in parallels_co_flush_to_os()
398 uint32_t to_write = s->bat_dirty_block; in parallels_co_flush_to_os()
401 if (off + to_write > s->header_size) { in parallels_co_flush_to_os()
402 to_write = s->header_size - off; in parallels_co_flush_to_os()
404 ret = bdrv_co_pwrite(bs->file, off, to_write, in parallels_co_flush_to_os()
405 (uint8_t *)s->header + off, 0); in parallels_co_flush_to_os()
407 qemu_co_mutex_unlock(&s->lock); in parallels_co_flush_to_os()
410 bit = find_next_bit(s->bat_dirty_bmap, size, bit + 1); in parallels_co_flush_to_os()
412 bitmap_zero(s->bat_dirty_bmap, size); in parallels_co_flush_to_os()
414 qemu_co_mutex_unlock(&s->lock); in parallels_co_flush_to_os()
423 BDRVParallelsState *s = bs->opaque; in parallels_co_block_status()
427 qemu_co_mutex_lock(&s->lock); in parallels_co_block_status()
430 qemu_co_mutex_unlock(&s->lock); in parallels_co_block_status()
438 *file = bs->file->bs; in parallels_co_block_status()
446 BDRVParallelsState *s = bs->opaque; in parallels_co_writev()
451 qemu_iovec_init(&hd_qiov, qiov->niov); in parallels_co_writev()
457 qemu_co_mutex_lock(&s->lock); in parallels_co_writev()
459 qemu_co_mutex_unlock(&s->lock); in parallels_co_writev()
470 ret = bdrv_co_pwritev(bs->file, position * BDRV_SECTOR_SIZE, nbytes, in parallels_co_writev()
476 nb_sectors -= n; in parallels_co_writev()
489 BDRVParallelsState *s = bs->opaque; in parallels_co_readv()
494 qemu_iovec_init(&hd_qiov, qiov->niov); in parallels_co_readv()
500 qemu_co_mutex_lock(&s->lock); in parallels_co_readv()
502 qemu_co_mutex_unlock(&s->lock); in parallels_co_readv()
510 if (bs->backing) { in parallels_co_readv()
511 ret = bdrv_co_preadv(bs->backing, sector_num * BDRV_SECTOR_SIZE, in parallels_co_readv()
520 ret = bdrv_co_preadv(bs->file, position * BDRV_SECTOR_SIZE, nbytes, in parallels_co_readv()
527 nb_sectors -= n; in parallels_co_readv()
542 BDRVParallelsState *s = bs->opaque; in parallels_co_pdiscard()
548 if (bs->backing) { in parallels_co_pdiscard()
549 return -ENOTSUP; in parallels_co_pdiscard()
552 if (!QEMU_IS_ALIGNED(offset, s->cluster_size)) { in parallels_co_pdiscard()
553 return -ENOTSUP; in parallels_co_pdiscard()
554 } else if (!QEMU_IS_ALIGNED(bytes, s->cluster_size)) { in parallels_co_pdiscard()
555 return -ENOTSUP; in parallels_co_pdiscard()
558 cluster = offset / s->cluster_size; in parallels_co_pdiscard()
559 count = bytes / s->cluster_size; in parallels_co_pdiscard()
561 qemu_co_mutex_lock(&s->lock); in parallels_co_pdiscard()
562 for (; count > 0; cluster++, count--) { in parallels_co_pdiscard()
568 ret = bdrv_co_pdiscard(bs->file, host_off, s->cluster_size); in parallels_co_pdiscard()
574 bitmap_clear(s->used_bmap, host_cluster_index(s, host_off), 1); in parallels_co_pdiscard()
577 qemu_co_mutex_unlock(&s->lock); in parallels_co_pdiscard()
598 BDRVParallelsState *s = bs->opaque; in parallels_check_unclean()
600 if (!s->header_unclean) { in parallels_check_unclean()
606 res->corruptions++; in parallels_check_unclean()
609 res->corruptions_fixed++; in parallels_check_unclean()
610 s->header_unclean = false; in parallels_check_unclean()
632 old_magic = !memcmp(s->header->magic, HEADER_MAGIC, 16); in parallels_test_data_off()
634 min_off = DIV_ROUND_UP(bat_entry_off(s->bat_size), BDRV_SECTOR_SIZE); in parallels_test_data_off()
636 min_off = ROUND_UP(min_off, s->cluster_size / BDRV_SECTOR_SIZE); in parallels_test_data_off()
643 data_off = le32_to_cpu(s->header->data_off); in parallels_test_data_off()
663 BDRVParallelsState *s = bs->opaque; in parallels_check_data_off()
667 file_size = bdrv_co_nb_sectors(bs->file->bs); in parallels_check_data_off()
669 res->check_errors++; in parallels_check_data_off()
677 res->corruptions++; in parallels_check_data_off()
680 s->header->data_off = cpu_to_le32(data_off); in parallels_check_data_off()
681 s->data_start = data_off; in parallels_check_data_off()
685 if (err == -ENOMEM) { in parallels_check_data_off()
686 res->check_errors++; in parallels_check_data_off()
690 res->corruptions_fixed++; in parallels_check_data_off()
703 BDRVParallelsState *s = bs->opaque; in parallels_check_outside_image()
707 size = bdrv_co_getlength(bs->file->bs); in parallels_check_outside_image()
709 res->check_errors++; in parallels_check_outside_image()
714 for (i = 0; i < s->bat_size; i++) { in parallels_check_outside_image()
716 if (off + s->cluster_size > size) { in parallels_check_outside_image()
719 res->corruptions++; in parallels_check_outside_image()
722 res->corruptions_fixed++; in parallels_check_outside_image()
732 res->image_end_offset = s->data_end << BDRV_SECTOR_BITS; in parallels_check_outside_image()
734 res->image_end_offset = high_off + s->cluster_size; in parallels_check_outside_image()
735 s->data_end = res->image_end_offset >> BDRV_SECTOR_BITS; in parallels_check_outside_image()
745 BDRVParallelsState *s = bs->opaque; in parallels_check_leak()
749 size = bdrv_co_getlength(bs->file->bs); in parallels_check_leak()
751 res->check_errors++; in parallels_check_leak()
755 if (size > res->image_end_offset) { in parallels_check_leak()
757 count = DIV_ROUND_UP(size - res->image_end_offset, s->cluster_size); in parallels_check_leak()
762 size - res->image_end_offset); in parallels_check_leak()
763 res->leaks += count; in parallels_check_leak()
772 ret = bdrv_co_truncate(bs->file, res->image_end_offset, true, in parallels_check_leak()
776 res->check_errors++; in parallels_check_leak()
780 res->leaks_fixed += count; in parallels_check_leak()
792 BDRVParallelsState *s = bs->opaque; in parallels_check_duplicate()
810 bitmap_size = host_cluster_index(s, res->image_end_offset); in parallels_check_duplicate()
814 if (res->image_end_offset % s->cluster_size) { in parallels_check_duplicate()
821 buf = qemu_blockalign(bs, s->cluster_size); in parallels_check_duplicate()
823 for (i = 0; i < s->bat_size; i++) { in parallels_check_duplicate()
830 assert(ret != -E2BIG); in parallels_check_duplicate()
839 res->corruptions++; in parallels_check_duplicate()
853 bat_entry = s->bat_bitmap[i]; in parallels_check_duplicate()
856 ret = bdrv_co_pread(bs->file, host_off, s->cluster_size, buf, 0); in parallels_check_duplicate()
858 res->check_errors++; in parallels_check_duplicate()
862 guest_sector = (i * (int64_t)s->cluster_size) >> BDRV_SECTOR_BITS; in parallels_check_duplicate()
863 host_sector = allocate_clusters(bs, guest_sector, s->tracks, &n); in parallels_check_duplicate()
865 res->check_errors++; in parallels_check_duplicate()
870 ret = bdrv_co_pwrite(bs->file, host_off, s->cluster_size, buf, 0); in parallels_check_duplicate()
872 res->check_errors++; in parallels_check_duplicate()
876 if (host_off + s->cluster_size > res->image_end_offset) { in parallels_check_duplicate()
877 res->image_end_offset = host_off + s->cluster_size; in parallels_check_duplicate()
887 * means that -E2BIG is OK. in parallels_check_duplicate()
890 if (ret == -EBUSY) { in parallels_check_duplicate()
891 res->check_errors++; in parallels_check_duplicate()
896 res->corruptions_fixed++; in parallels_check_duplicate()
918 s->bat_bitmap[i] = bat_entry; in parallels_check_duplicate()
926 BDRVParallelsState *s = bs->opaque; in parallels_collect_statistics()
930 res->bfi.total_clusters = s->bat_size; in parallels_collect_statistics()
931 res->bfi.compressed_clusters = 0; /* compression is not supported */ in parallels_collect_statistics()
934 for (i = 0; i < s->bat_size; i++) { in parallels_collect_statistics()
937 * If BDRV_FIX_ERRORS is not set, out-of-image BAT entries were not in parallels_collect_statistics()
938 * fixed. Skip not allocated and out-of-image BAT entries. in parallels_collect_statistics()
940 if (off == 0 || off + s->cluster_size > res->image_end_offset) { in parallels_collect_statistics()
945 if (prev_off != 0 && (prev_off + s->cluster_size) != off) { in parallels_collect_statistics()
946 res->bfi.fragmented_clusters++; in parallels_collect_statistics()
949 res->bfi.allocated_clusters++; in parallels_collect_statistics()
957 BDRVParallelsState *s = bs->opaque; in parallels_co_check()
960 WITH_QEMU_LOCK_GUARD(&s->lock) { in parallels_co_check()
988 res->check_errors++; in parallels_co_check()
1007 assert(opts->driver == BLOCKDEV_DRIVER_PARALLELS); in parallels_co_create()
1008 parallels_opts = &opts->u.parallels; in parallels_co_create()
1011 total_size = parallels_opts->size; in parallels_co_create()
1013 if (parallels_opts->has_cluster_size) { in parallels_co_create()
1014 cl_size = parallels_opts->cluster_size; in parallels_co_create()
1022 return -EINVAL; in parallels_co_create()
1026 return -E2BIG; in parallels_co_create()
1031 return -EINVAL; in parallels_co_create()
1036 return -EINVAL; in parallels_co_create()
1040 bs = bdrv_co_open_blockdev_ref(parallels_opts->file, errp); in parallels_co_create()
1042 return -EIO; in parallels_co_create()
1048 ret = -EPERM; in parallels_co_create()
1079 (bat_sectors - 1) << BDRV_SECTOR_BITS, 0); in parallels_co_create()
1091 error_setg_errno(errp, -ret, "Failed to create Parallels image"); in parallels_co_create()
1106 { BLOCK_OPT_CLUSTER_SIZE, "cluster-size" }, in parallels_co_create_opts()
1115 ret = -EINVAL; in parallels_co_create_opts()
1128 ret = -EIO; in parallels_co_create_opts()
1134 qdict_put_str(qdict, "file", bs->node_name); in parallels_co_create_opts()
1138 ret = -EINVAL; in parallels_co_create_opts()
1145 ret = -EINVAL; in parallels_co_create_opts()
1150 create_options->u.parallels.size = in parallels_co_create_opts()
1151 ROUND_UP(create_options->u.parallels.size, BDRV_SECTOR_SIZE); in parallels_co_create_opts()
1152 create_options->u.parallels.cluster_size = in parallels_co_create_opts()
1153 ROUND_UP(create_options->u.parallels.cluster_size, BDRV_SECTOR_SIZE); in parallels_co_create_opts()
1179 if ((!memcmp(ph->magic, HEADER_MAGIC, 16) || in parallels_probe()
1180 !memcmp(ph->magic, HEADER_MAGIC2, 16)) && in parallels_probe()
1181 (le32_to_cpu(ph->version) == HEADER_VERSION)) { in parallels_probe()
1190 BDRVParallelsState *s = bs->opaque; in parallels_update_header()
1191 unsigned size = MAX(bdrv_opt_mem_align(bs->file->bs), in parallels_update_header()
1194 if (size > s->header_size) { in parallels_update_header()
1195 size = s->header_size; in parallels_update_header()
1197 return bdrv_pwrite_sync(bs->file, 0, size, s->header, 0); in parallels_update_header()
1207 BDRVParallelsState *s = bs->opaque; in parallels_opts_prealloc()
1211 return -ENOMEM; in parallels_opts_prealloc()
1214 err = -EINVAL; in parallels_opts_prealloc()
1220 s->prealloc_size = bytes >> BDRV_SECTOR_BITS; in parallels_opts_prealloc()
1223 s->prealloc_mode = qapi_enum_parse(&prealloc_mode_lookup, buf, in parallels_opts_prealloc()
1241 BDRVParallelsState *s = bs->opaque; in parallels_open()
1260 file_nb_sectors = bdrv_nb_sectors(bs->file->bs); in parallels_open()
1262 return -EINVAL; in parallels_open()
1265 ret = bdrv_pread(bs->file, 0, sizeof(ph), &ph, 0); in parallels_open()
1270 bs->total_sectors = le64_to_cpu(ph.nb_sectors); in parallels_open()
1276 s->off_multiplier = 1; in parallels_open()
1277 bs->total_sectors = 0xffffffff & bs->total_sectors; in parallels_open()
1279 s->off_multiplier = le32_to_cpu(ph.tracks); in parallels_open()
1284 s->tracks = le32_to_cpu(ph.tracks); in parallels_open()
1285 if (s->tracks == 0) { in parallels_open()
1287 return -EINVAL; in parallels_open()
1289 if (s->tracks > INT32_MAX/513) { in parallels_open()
1291 return -EFBIG; in parallels_open()
1293 s->prealloc_size = MAX(s->tracks, s->prealloc_size); in parallels_open()
1294 s->cluster_size = s->tracks << BDRV_SECTOR_BITS; in parallels_open()
1296 s->bat_size = le32_to_cpu(ph.bat_entries); in parallels_open()
1297 if (s->bat_size > INT_MAX / sizeof(uint32_t)) { in parallels_open()
1299 return -EFBIG; in parallels_open()
1303 return -EFBIG; in parallels_open()
1306 size = bat_entry_off(s->bat_size); in parallels_open()
1307 s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file->bs)); in parallels_open()
1308 s->header = qemu_try_blockalign(bs->file->bs, s->header_size); in parallels_open()
1309 if (s->header == NULL) { in parallels_open()
1310 return -ENOMEM; in parallels_open()
1313 ret = bdrv_pread(bs->file, 0, s->header_size, s->header, 0); in parallels_open()
1317 s->bat_bitmap = (uint32_t *)(s->header + 1); in parallels_open()
1320 need_check = s->header_unclean = true; in parallels_open()
1328 s->data_start = data_start; in parallels_open()
1329 s->data_end = s->data_start; in parallels_open()
1330 if (s->data_end < (s->header_size >> BDRV_SECTOR_BITS)) { in parallels_open()
1332 * There is not enough unused space to fit to block align between BAT in parallels_open()
1333 * and actual data. We can't avoid read-modify-write... in parallels_open()
1335 s->header_size = size; in parallels_open()
1356 s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC); in parallels_open()
1363 s->bat_dirty_block = 4 * qemu_real_host_page_size(); in parallels_open()
1364 s->bat_dirty_bmap = in parallels_open()
1365 bitmap_new(DIV_ROUND_UP(s->header_size, s->bat_dirty_block)); in parallels_open()
1367 /* Disable migration until bdrv_activate method is added */ in parallels_open()
1368 error_setg(&s->migration_blocker, "The Parallels format used by node '%s' " in parallels_open()
1369 "does not support live migration", in parallels_open()
1372 ret = migrate_add_blocker_normal(&s->migration_blocker, errp); in parallels_open()
1376 qemu_co_mutex_init(&s->lock); in parallels_open()
1378 for (i = 0; i < s->bat_size; i++) { in parallels_open()
1380 if (sector + s->tracks > s->data_end) { in parallels_open()
1381 s->data_end = sector + s->tracks; in parallels_open()
1384 need_check = need_check || s->data_end > file_nb_sectors; in parallels_open()
1388 if (ret == -ENOMEM) { in parallels_open()
1407 error_setg_errno(errp, -ret, "Could not repair corrupted image"); in parallels_open()
1408 migrate_del_blocker(&s->migration_blocker); in parallels_open()
1416 return -EINVAL; in parallels_open()
1425 g_free(s->bat_dirty_bmap); in parallels_open()
1426 qemu_vfree(s->header); in parallels_open()
1433 BDRVParallelsState *s = bs->opaque; in parallels_close()
1437 if ((bs->open_flags & BDRV_O_RDWR) && !(bs->open_flags & BDRV_O_INACTIVE)) { in parallels_close()
1438 s->header->inuse = 0; in parallels_close()
1442 bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true, in parallels_close()
1448 g_free(s->bat_dirty_bmap); in parallels_close()
1449 qemu_vfree(s->header); in parallels_close()
1451 migrate_del_blocker(&s->migration_blocker); in parallels_close()