diff options
author | Anthony Liguori <aliguori@amazon.com> | 2013-12-06 12:59:58 -0800 |
---|---|---|
committer | Anthony Liguori <aliguori@amazon.com> | 2013-12-06 12:59:58 -0800 |
commit | 0a0ee0b93bdd6e1ef628283d00bb979e27655ebb (patch) | |
tree | a8e1d34e3a187afc96d8697dfe121032a0268912 /include | |
parent | 9ed5dacbfa0f3f74238854776385f150b68e78b9 (diff) | |
parent | 981cbf59b5360647e908186e7306ee9013a58c88 (diff) |
Merge remote-tracking branch 'kwolf/tags/for-anthony' into staging
Block patches for 2.0 (flushing block-next)
# gpg: Signature made Fri 29 Nov 2013 08:43:18 AM PST using RSA key ID C88F2FD6
# gpg: Can't check signature: public key not found
# By Peter Lieven (17) and others
# Via Kevin Wolf
* kwolf/tags/for-anthony: (41 commits)
qemu-iotests: Add sample image and test for VMDK version 3
vmdk: Allow read only open of VMDK version 3
qemu-iotests: Filter out 'qemu-io> ' prompt
qemu-iotests: Filter qemu-io output in 025
block: Use BDRV_O_NO_BACKING where appropriate
qemu-iotests: Test snapshot mode
block: Enable BDRV_O_SNAPSHOT with driver-specific options
qemu-iotests: Make test case 030, 040 and 055 deterministic
qemu-iotest: Add pause_drive and resume_drive methods
blkdebug: add "remove_break" command
qemu-iotests: Drop local version of cancel_and_wait from 040
sheepdog: support user-defined redundancy option
sheepdog: refactor do_sd_create()
qdict: Optimise qdict_do_flatten()
qdict: Fix memory leak in qdict_do_flatten()
MAINTAINERS: add sheepdog development mailing list
COW: Extend checking allocated bits to beyond one sector
COW: Speed up writes
qapi: Change BlockDirtyInfo to list
block: per caller dirty bitmap
...
Message-id: 1385743555-27888-1-git-send-email-kwolf@redhat.com
Signed-off-by: Anthony Liguori <aliguori@amazon.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/block/block.h | 48 | ||||
-rw-r--r-- | include/block/block_int.h | 24 |
2 files changed, 64 insertions, 8 deletions
diff --git a/include/block/block.h b/include/block/block.h index 3560deb883..5beccbf1cf 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -18,6 +18,22 @@ typedef struct BlockDriverInfo { /* offset at which the VM state can be saved (0 if not possible) */ int64_t vm_state_offset; bool is_dirty; + /* + * True if unallocated blocks read back as zeroes. This is equivalent + * to the the LBPRZ flag in the SCSI logical block provisioning page. + */ + bool unallocated_blocks_are_zero; + /* + * True if the driver can optimize writing zeroes by unmapping + * sectors. This is equivalent to the BLKDISCARDZEROES ioctl in Linux + * with the difference that in qemu a discard is allowed to silently + * fail. Therefore we have to use bdrv_write_zeroes with the + * BDRV_REQ_MAY_UNMAP flag for an optimized zero write with unmapping. + * After this call the driver has to guarantee that the contents read + * back as zero. It is additionally required that the block device is + * opened with BDRV_O_UNMAP flag for this to work. + */ + bool can_write_zeroes_with_unmap; } BlockDriverInfo; typedef struct BlockFragInfo { @@ -62,6 +78,18 @@ typedef struct BlockDevOps { void (*resize_cb)(void *opaque); } BlockDevOps; +typedef enum { + BDRV_REQ_COPY_ON_READ = 0x1, + BDRV_REQ_ZERO_WRITE = 0x2, + /* The BDRV_REQ_MAY_UNMAP flag is used to indicate that the block driver + * is allowed to optimize a write zeroes request by unmapping (discarding) + * blocks if it is guaranteed that the result will read back as + * zeroes. The flag is only passed to the driver if the block device is + * opened with BDRV_O_UNMAP. + */ + BDRV_REQ_MAY_UNMAP = 0x4, +} BdrvRequestFlags; + #define BDRV_O_RDWR 0x0002 #define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */ #define BDRV_O_NOCACHE 0x0020 /* do not use the host page cache */ @@ -187,7 +215,8 @@ int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num, int bdrv_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors); + int nb_sectors, BdrvRequestFlags flags); +int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags); int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov); int bdrv_pread(BlockDriverState *bs, int64_t offset, void *buf, int count); @@ -209,7 +238,7 @@ int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, * because it may allocate memory for the entire region. */ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors); + int nb_sectors, BdrvRequestFlags flags); BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_get_backing_file_depth(BlockDriverState *bs); @@ -316,6 +345,8 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int bdrv_has_zero_init_1(BlockDriverState *bs); int bdrv_has_zero_init(BlockDriverState *bs); +bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs); +bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, @@ -388,12 +419,16 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size); bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov); struct HBitmapIter; -void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity); -int bdrv_get_dirty(BlockDriverState *bs, int64_t sector); +typedef struct BdrvDirtyBitmap BdrvDirtyBitmap; +BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity); +void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); +int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector); void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); -void bdrv_dirty_iter_init(BlockDriverState *bs, struct HBitmapIter *hbi); -int64_t bdrv_get_dirty_count(BlockDriverState *bs); +void bdrv_dirty_iter_init(BlockDriverState *bs, + BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi); +int64_t bdrv_get_dirty_count(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_enable_copy_on_read(BlockDriverState *bs); void bdrv_disable_copy_on_read(BlockDriverState *bs); @@ -484,6 +519,7 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event); int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, const char *tag); +int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag); int bdrv_debug_resume(BlockDriverState *bs, const char *tag); bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); diff --git a/include/block/block_int.h b/include/block/block_int.h index 166606615c..773899b500 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -53,6 +53,7 @@ #define BLOCK_OPT_COMPAT_LEVEL "compat" #define BLOCK_OPT_LAZY_REFCOUNTS "lazy_refcounts" #define BLOCK_OPT_ADAPTER_TYPE "adapter_type" +#define BLOCK_OPT_REDUNDANCY "redundancy" typedef struct BdrvTrackedRequest { BlockDriverState *bs; @@ -130,7 +131,7 @@ struct BlockDriver { * instead. */ int coroutine_fn (*bdrv_co_write_zeroes)(BlockDriverState *bs, - int64_t sector_num, int nb_sectors); + int64_t sector_num, int nb_sectors, BdrvRequestFlags flags); int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs, @@ -218,6 +219,8 @@ struct BlockDriver { /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */ int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event, const char *tag); + int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs, + const char *tag); int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag); bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag); @@ -230,6 +233,20 @@ struct BlockDriver { QLIST_ENTRY(BlockDriver) list; }; +typedef struct BlockLimits { + /* maximum number of sectors that can be discarded at once */ + int max_discard; + + /* optimal alignment for discard requests in sectors */ + int64_t discard_alignment; + + /* maximum number of sectors that can zeroized at once */ + int max_write_zeroes; + + /* optimal alignment for write zeroes requests in sectors */ + int64_t write_zeroes_alignment; +} BlockLimits; + /* * Note: the function bdrv_append() copies and swaps contents of * BlockDriverStates, so if you add new fields to this struct, please @@ -283,6 +300,9 @@ struct BlockDriverState { uint64_t total_time_ns[BDRV_MAX_IOTYPE]; uint64_t wr_highest_sector; + /* I/O Limits */ + BlockLimits bl; + /* Whether the disk can expand beyond total_sectors */ int growable; @@ -301,7 +321,7 @@ struct BlockDriverState { bool iostatus_enabled; BlockDeviceIoStatus iostatus; char device_name[32]; - HBitmap *dirty_bitmap; + QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps; int refcnt; int in_use; /* users other than guest access, eg. block migration */ QTAILQ_ENTRY(BlockDriverState) list; |