Block layer patches

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJWKmeMAAoJEH8JsnLIjy/WUYYP/0hrpnuE14QBAW+RjV/40+fh
 II3+RBX2Avz8ERWD29aAftqmNIigxPhdvzEdOP1/IRBnYNzBMUw6BTsqrV3IgA1X
 ODIRFht3horyL6w5rfJLLbAVOyRPWTGHZNgxBN+GGy3Z/jLK+VH+1dK26rSd6p7o
 QqsmBUPi5UQvSd89r+X1tVwFjT5Miw7CyFaijXdnVzs1LNpbtg49t4YpQH1eG5bf
 aP4GXWn4g5/Ht8LSByuViDG3CpLjysSYSFPn/4HIP41BU6u3P6yD++g6nbdkvIsn
 yDezoVpCEvKoYXfc1xGY3Q7+lwzV8wa5mzdtpy6eg2889dHoJuUePI6Yfza9TNJI
 XzBJmYaBZx+289nxeAX2K3dRe0ilCEdWyujlhoonDuYOS9xbDiaouWcVZEw/0ky5
 SUsRZYTZGGc1BOoFeBE4JpopFCPZ4a//bzi5GrlyEiwl7kpKPTMxFWvjSQpQ/Gzz
 sPLxnn1y1AA4jAqgQNLFpCciJ1sH1WNmb00WjQkoEomIdpuvLvK1GUKfcwEERTWb
 Ae8wlCbofkIJgQOwa9DTS/yDPfl3pUc/NgmRc+Qz/0snrtvmmsS+huJQQfCH1JDQ
 p3jvurvQ7G5RkTzdOIbSkzfKaW8ZHq6ENWRP5HY/y8LontAVdYzT+DRLeyTpGfKL
 ncgMgK6fT3rE+3lA8Acz
 =xcrS
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block layer patches

# gpg: Signature made Fri 23 Oct 2015 17:59:56 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (37 commits)
  tests: Add test case for aio_disable_external
  block: Add "drained begin/end" for internal snapshot
  block: Add "drained begin/end" for transactional blockdev-backup
  block: Add "drained begin/end" for transactional backup
  block: Add "drained begin/end" for transactional external snapshot
  block: Introduce "drained begin/end" API
  aio: introduce aio_{disable,enable}_external
  dataplane: Mark host notifiers' client type as "external"
  nbd: Mark fd handlers client type as "external"
  aio: Add "is_external" flag for event handlers
  throttle: Remove throttle_group_lock/unlock()
  blockdev: Allow more options for BB-less BDS tree
  blockdev: Pull out blockdev option extraction
  blockdev: Do not create BDS for empty drive
  block: Prepare for NULL BDS
  block: Add blk_insert_bs()
  block: Prepare remaining BB functions for NULL BDS
  block: Fail requests to empty BlockBackend
  block: Make some BB functions fall back to BBRS
  block: Add BlockBackendRootState
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-10-23 18:14:42 +01:00
commit af25e7277d
52 changed files with 1268 additions and 872 deletions

View file

@ -40,7 +40,6 @@ typedef struct BlockAcctStats {
uint64_t nr_ops[BLOCK_MAX_IOTYPE];
uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
uint64_t merged[BLOCK_MAX_IOTYPE];
uint64_t wr_highest_sector;
} BlockAcctStats;
typedef struct BlockAcctCookie {
@ -52,8 +51,6 @@ typedef struct BlockAcctCookie {
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
int64_t bytes, enum BlockAcctType type);
void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
unsigned int nb_sectors);
void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
int num_requests);

View file

@ -122,6 +122,8 @@ struct AioContext {
/* TimerLists for calling timers - one per clock type */
QEMUTimerListGroup tlg;
int external_disable_cnt;
};
/**
@ -299,6 +301,7 @@ bool aio_poll(AioContext *ctx, bool blocking);
*/
void aio_set_fd_handler(AioContext *ctx,
int fd,
bool is_external,
IOHandler *io_read,
IOHandler *io_write,
void *opaque);
@ -312,6 +315,7 @@ void aio_set_fd_handler(AioContext *ctx,
*/
void aio_set_event_notifier(AioContext *ctx,
EventNotifier *notifier,
bool is_external,
EventNotifierHandler *io_read);
/* Return a GSource that lets the main loop poll the file descriptors attached
@ -373,4 +377,40 @@ static inline void aio_timer_init(AioContext *ctx,
*/
int64_t aio_compute_timeout(AioContext *ctx);
/**
* aio_disable_external:
* @ctx: the aio context
*
* Disable the further processing of external clients.
*/
static inline void aio_disable_external(AioContext *ctx)
{
atomic_inc(&ctx->external_disable_cnt);
}
/**
* aio_enable_external:
* @ctx: the aio context
*
* Enable the processing of external clients.
*/
static inline void aio_enable_external(AioContext *ctx)
{
assert(ctx->external_disable_cnt > 0);
atomic_dec(&ctx->external_disable_cnt);
}
/**
* aio_node_check:
* @ctx: the aio context
* @is_external: Whether or not the checked node is an external event source.
*
* Check if the node's is_external flag is okay to be polled by the ctx at this
* moment. True means green light.
*/
static inline bool aio_node_check(AioContext *ctx, bool is_external)
{
return !is_external || !atomic_read(&ctx->external_disable_cnt);
}
#endif

View file

@ -174,11 +174,6 @@ typedef enum BlockOpType {
BLOCK_OP_TYPE_MAX,
} BlockOpType;
void bdrv_iostatus_enable(BlockDriverState *bs);
void bdrv_iostatus_reset(BlockDriverState *bs);
void bdrv_iostatus_disable(BlockDriverState *bs);
bool bdrv_iostatus_is_enabled(const BlockDriverState *bs);
void bdrv_iostatus_set_err(BlockDriverState *bs, int error);
void bdrv_info_print(Monitor *mon, const QObject *data);
void bdrv_info(Monitor *mon, QObject **ret_data);
void bdrv_stats_print(Monitor *mon, const QObject *data);
@ -389,17 +384,11 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
int64_t sector_num, int nb_sectors, int *pnum);
void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error,
BlockdevOnError on_write_error);
BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read);
BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error);
void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
bool is_read, int error);
int bdrv_is_read_only(BlockDriverState *bs);
int bdrv_is_sg(BlockDriverState *bs);
int bdrv_enable_write_cache(BlockDriverState *bs);
void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce);
int bdrv_is_inserted(BlockDriverState *bs);
bool bdrv_is_inserted(BlockDriverState *bs);
int bdrv_media_changed(BlockDriverState *bs);
void bdrv_lock_medium(BlockDriverState *bs, bool locked);
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
@ -466,7 +455,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
size_t bdrv_min_mem_align(BlockDriverState *bs);
/* Returns optimal alignment in bytes for bounce buffer */
size_t bdrv_opt_mem_align(BlockDriverState *bs);
void bdrv_set_guest_block_size(BlockDriverState *bs, int align);
void *qemu_blockalign(BlockDriverState *bs, size_t size);
void *qemu_blockalign0(BlockDriverState *bs, size_t size);
void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
@ -622,6 +610,23 @@ void bdrv_io_plug(BlockDriverState *bs);
void bdrv_io_unplug(BlockDriverState *bs);
void bdrv_flush_io_queue(BlockDriverState *bs);
BlockAcctStats *bdrv_get_stats(BlockDriverState *bs);
/**
* bdrv_drained_begin:
*
* Begin a quiesced section for exclusive access to the BDS, by disabling
* external request sources including NBD server and device model. Note that
* this doesn't block timers or coroutines from submitting more requests, which
* means block_job_pause is still necessary.
*
* This function can be recursive.
*/
void bdrv_drained_begin(BlockDriverState *bs);
/**
* bdrv_drained_end:
*
* End a quiescent section started by bdrv_drained_begin().
*/
void bdrv_drained_end(BlockDriverState *bs);
#endif

View file

@ -26,6 +26,7 @@
#include "block/accounting.h"
#include "block/block.h"
#include "block/throttle-groups.h"
#include "qemu/option.h"
#include "qemu/queue.h"
#include "qemu/coroutine.h"
@ -212,7 +213,7 @@ struct BlockDriver {
const char *backing_file, const char *backing_fmt);
/* removable device specific */
int (*bdrv_is_inserted)(BlockDriverState *bs);
bool (*bdrv_is_inserted)(BlockDriverState *bs);
int (*bdrv_media_changed)(BlockDriverState *bs);
void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
@ -399,8 +400,8 @@ struct BlockDriverState {
unsigned pending_reqs[2];
QLIST_ENTRY(BlockDriverState) round_robin;
/* I/O stats (display with "info blockstats"). */
BlockAcctStats stats;
/* Offset after the highest byte written to */
uint64_t wr_highest_offset;
/* I/O Limits */
BlockLimits bl;
@ -411,18 +412,9 @@ struct BlockDriverState {
/* Alignment requirement for offset/length of I/O requests */
unsigned int request_alignment;
/* the block size for which the guest device expects atomicity */
int guest_block_size;
/* do we need to tell the quest if we have a volatile write cache? */
int enable_write_cache;
/* NOTE: the following infos are only hints for real hardware
drivers. They are not used by the block driver */
BlockdevOnError on_read_error, on_write_error;
bool iostatus_enabled;
BlockDeviceIoStatus iostatus;
/* the following member gives a name to every node on the bs graph. */
char node_name[32];
/* element of the list of named nodes building the graph */
@ -456,6 +448,17 @@ struct BlockDriverState {
/* threshold limit for writes, in bytes. "High water mark". */
uint64_t write_threshold_offset;
NotifierWithReturn write_threshold_notifier;
int quiesce_counter;
};
struct BlockBackendRootState {
int open_flags;
bool read_only;
BlockdevDetectZeroesOptions detect_zeroes;
char *throttle_group;
ThrottleState *throttle_state;
};
static inline BlockDriverState *backing_bs(BlockDriverState *bs)

View file

@ -30,6 +30,9 @@
const char *throttle_group_get_name(BlockDriverState *bs);
ThrottleState *throttle_group_incref(const char *name);
void throttle_group_unref(ThrottleState *ts);
void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg);
void throttle_group_get_config(BlockDriverState *bs, ThrottleConfig *cfg);
@ -40,7 +43,4 @@ void coroutine_fn throttle_group_co_io_limits_intercept(BlockDriverState *bs,
unsigned int bytes,
bool is_write);
void throttle_group_lock(BlockDriverState *bs);
void throttle_group_unlock(BlockDriverState *bs);
#endif

View file

@ -11,6 +11,7 @@ typedef struct AddressSpace AddressSpace;
typedef struct AioContext AioContext;
typedef struct AudioState AudioState;
typedef struct BlockBackend BlockBackend;
typedef struct BlockBackendRootState BlockBackendRootState;
typedef struct BlockDriverState BlockDriverState;
typedef struct BusClass BusClass;
typedef struct BusState BusState;

View file

@ -72,10 +72,16 @@ BlockBackend *blk_by_name(const char *name);
BlockBackend *blk_next(BlockBackend *blk);
BlockDriverState *blk_bs(BlockBackend *blk);
void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs);
void blk_hide_on_behalf_of_hmp_drive_del(BlockBackend *blk);
void blk_iostatus_enable(BlockBackend *blk);
bool blk_iostatus_is_enabled(const BlockBackend *blk);
BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
void blk_iostatus_disable(BlockBackend *blk);
void blk_iostatus_reset(BlockBackend *blk);
void blk_iostatus_set_err(BlockBackend *blk, int error);
int blk_attach_dev(BlockBackend *blk, void *dev);
void blk_attach_dev_nofail(BlockBackend *blk, void *dev);
void blk_detach_dev(BlockBackend *blk, void *dev);
@ -120,6 +126,8 @@ int blk_flush(BlockBackend *blk);
int blk_flush_all(void);
void blk_drain(BlockBackend *blk);
void blk_drain_all(void);
void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
BlockdevOnError on_write_error);
BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
int error);
@ -130,7 +138,8 @@ int blk_is_sg(BlockBackend *blk);
int blk_enable_write_cache(BlockBackend *blk);
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
int blk_is_inserted(BlockBackend *blk);
bool blk_is_inserted(BlockBackend *blk);
bool blk_is_available(BlockBackend *blk);
void blk_lock_medium(BlockBackend *blk, bool locked);
void blk_eject(BlockBackend *blk, bool eject_flag);
int blk_get_flags(BlockBackend *blk);
@ -155,6 +164,8 @@ void blk_add_close_notifier(BlockBackend *blk, Notifier *notify);
void blk_io_plug(BlockBackend *blk);
void blk_io_unplug(BlockBackend *blk);
BlockAcctStats *blk_get_stats(BlockBackend *blk);
BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
void blk_update_root_state(BlockBackend *blk);
void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
BlockCompletionFunc *cb, void *opaque);