blockdev: acquire AioContext in blockdev-snapshot-delete-internal-sync
Add dataplane support to the blockdev-snapshot-delete-internal-sync QMP command. By acquiring the AioContext we avoid race conditions with the dataplane thread which may also be accessing the BlockDriverState. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									2389eeae69
								
							
						
					
					
						commit
						4ef3982a99
					
				
							
								
								
									
										16
									
								
								blockdev.c
								
								
								
								
							
							
						
						
									
										16
									
								
								blockdev.c
								
								
								
								
							| 
						 | 
				
			
			@ -1105,6 +1105,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 | 
			
		|||
                                                         Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriverState *bs = bdrv_find(device);
 | 
			
		||||
    AioContext *aio_context;
 | 
			
		||||
    QEMUSnapshotInfo sn;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
    SnapshotInfo *info = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,25 +1129,30 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 | 
			
		|||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err);
 | 
			
		||||
    if (local_err) {
 | 
			
		||||
        error_propagate(errp, local_err);
 | 
			
		||||
        return NULL;
 | 
			
		||||
        goto out_aio_context;
 | 
			
		||||
    }
 | 
			
		||||
    if (!ret) {
 | 
			
		||||
        error_setg(errp,
 | 
			
		||||
                   "Snapshot with id '%s' and name '%s' does not exist on "
 | 
			
		||||
                   "device '%s'",
 | 
			
		||||
                   STR_OR_NULL(id), STR_OR_NULL(name), device);
 | 
			
		||||
        return NULL;
 | 
			
		||||
        goto out_aio_context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bdrv_snapshot_delete(bs, id, name, &local_err);
 | 
			
		||||
    if (local_err) {
 | 
			
		||||
        error_propagate(errp, local_err);
 | 
			
		||||
        return NULL;
 | 
			
		||||
        goto out_aio_context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context_release(aio_context);
 | 
			
		||||
 | 
			
		||||
    info = g_new0(SnapshotInfo, 1);
 | 
			
		||||
    info->id = g_strdup(sn.id_str);
 | 
			
		||||
    info->name = g_strdup(sn.name);
 | 
			
		||||
| 
						 | 
				
			
			@ -1157,6 +1163,10 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 | 
			
		|||
    info->vm_clock_sec = sn.vm_clock_nsec / 1000000000;
 | 
			
		||||
 | 
			
		||||
    return info;
 | 
			
		||||
 | 
			
		||||
out_aio_context:
 | 
			
		||||
    aio_context_release(aio_context);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* New and old BlockDriverState structs for group snapshots */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -198,6 +198,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
 | 
			
		|||
    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
 | 
			
		||||
    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker);
 | 
			
		||||
    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT, s->blocker);
 | 
			
		||||
    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
 | 
			
		||||
                   s->blocker);
 | 
			
		||||
    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_MIRROR, s->blocker);
 | 
			
		||||
    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker);
 | 
			
		||||
    blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue