blockdev: Keep track of monitor-owned BDS
As a side effect, we can now make x-blockdev-del's check whether a BDS is actually owned by the monitor explicit. Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									2c1d04e002
								
							
						
					
					
						commit
						9c4218e957
					
				
							
								
								
									
										28
									
								
								blockdev.c
								
								
								
								
							
							
						
						
									
										28
									
								
								blockdev.c
								
								
								
								
							| 
						 | 
				
			
			@ -50,6 +50,9 @@
 | 
			
		|||
#include "trace.h"
 | 
			
		||||
#include "sysemu/arch_init.h"
 | 
			
		||||
 | 
			
		||||
static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
 | 
			
		||||
    QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
 | 
			
		||||
 | 
			
		||||
static const char *const if_name[IF_COUNT] = {
 | 
			
		||||
    [IF_NONE] = "none",
 | 
			
		||||
    [IF_IDE] = "ide",
 | 
			
		||||
| 
						 | 
				
			
			@ -702,6 +705,19 @@ fail:
 | 
			
		|||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void blockdev_close_all_bdrv_states(void)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriverState *bs, *next_bs;
 | 
			
		||||
 | 
			
		||||
    QTAILQ_FOREACH_SAFE(bs, &monitor_bdrv_states, monitor_list, next_bs) {
 | 
			
		||||
        AioContext *ctx = bdrv_get_aio_context(bs);
 | 
			
		||||
 | 
			
		||||
        aio_context_acquire(ctx);
 | 
			
		||||
        bdrv_unref(bs);
 | 
			
		||||
        aio_context_release(ctx);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
 | 
			
		||||
                            Error **errp)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -3875,12 +3891,15 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 | 
			
		|||
        if (!bs) {
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (bs && bdrv_key_required(bs)) {
 | 
			
		||||
        if (blk) {
 | 
			
		||||
            blk_unref(blk);
 | 
			
		||||
        } else {
 | 
			
		||||
            QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
 | 
			
		||||
            bdrv_unref(bs);
 | 
			
		||||
        }
 | 
			
		||||
        error_setg(errp, "blockdev-add doesn't support encrypted devices");
 | 
			
		||||
| 
						 | 
				
			
			@ -3940,7 +3959,13 @@ void qmp_x_blockdev_del(bool has_id, const char *id,
 | 
			
		|||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (bs->refcnt > 1 || !QLIST_EMPTY(&bs->parents)) {
 | 
			
		||||
        if (!blk && !bs->monitor_list.tqe_prev) {
 | 
			
		||||
            error_setg(errp, "Node %s is not owned by the monitor",
 | 
			
		||||
                       bs->node_name);
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (bs->refcnt > 1) {
 | 
			
		||||
            error_setg(errp, "Block device %s is in use",
 | 
			
		||||
                       bdrv_get_device_or_node_name(bs));
 | 
			
		||||
            goto out;
 | 
			
		||||
| 
						 | 
				
			
			@ -3950,6 +3975,7 @@ void qmp_x_blockdev_del(bool has_id, const char *id,
 | 
			
		|||
    if (blk) {
 | 
			
		||||
        blk_unref(blk);
 | 
			
		||||
    } else {
 | 
			
		||||
        QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
 | 
			
		||||
        bdrv_unref(bs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -445,6 +445,8 @@ struct BlockDriverState {
 | 
			
		|||
    QTAILQ_ENTRY(BlockDriverState) device_list;
 | 
			
		||||
    /* element of the list of all BlockDriverStates (all_bdrv_states) */
 | 
			
		||||
    QTAILQ_ENTRY(BlockDriverState) bs_list;
 | 
			
		||||
    /* element of the list of monitor-owned BDS */
 | 
			
		||||
    QTAILQ_ENTRY(BlockDriverState) monitor_list;
 | 
			
		||||
    QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps;
 | 
			
		||||
    int refcnt;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -707,4 +709,6 @@ bool bdrv_requests_pending(BlockDriverState *bs);
 | 
			
		|||
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
 | 
			
		||||
void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in);
 | 
			
		||||
 | 
			
		||||
void blockdev_close_all_bdrv_states(void);
 | 
			
		||||
 | 
			
		||||
#endif /* BLOCK_INT_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
stub-obj-y += arch-query-cpu-def.o
 | 
			
		||||
stub-obj-y += bdrv-commit-all.o
 | 
			
		||||
stub-obj-y += blockdev-close-all-bdrv-states.o
 | 
			
		||||
stub-obj-y += clock-warp.o
 | 
			
		||||
stub-obj-y += cpu-get-clock.o
 | 
			
		||||
stub-obj-y += cpu-get-icount.o
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
#include "block/block_int.h"
 | 
			
		||||
 | 
			
		||||
void blockdev_close_all_bdrv_states(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue