Revision f67503e5 block.c

b/block.c
1046 1046
    }
1047 1047

  
1048 1048
    if (!drv->bdrv_file_open) {
1049
        ret = bdrv_open(bs, filename, options, flags, drv, &local_err);
1049
        ret = bdrv_open(&bs, filename, options, flags, drv, &local_err);
1050 1050
        options = NULL;
1051 1051
    } else {
1052 1052
        ret = bdrv_open_common(bs, NULL, options, flags, drv, &local_err);
......
1115 1115
                                       sizeof(backing_filename));
1116 1116
    }
1117 1117

  
1118
    bs->backing_hd = bdrv_new("");
1119

  
1120 1118
    if (bs->backing_format[0] != '\0') {
1121 1119
        back_drv = bdrv_find_format(bs->backing_format);
1122 1120
    }
......
1125 1123
    back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT |
1126 1124
                                    BDRV_O_COPY_ON_READ);
1127 1125

  
1128
    ret = bdrv_open(bs->backing_hd,
1126
    assert(bs->backing_hd == NULL);
1127
    ret = bdrv_open(&bs->backing_hd,
1129 1128
                    *backing_filename ? backing_filename : NULL, options,
1130 1129
                    back_flags, back_drv, &local_err);
1131 1130
    if (ret < 0) {
1132
        bdrv_unref(bs->backing_hd);
1133 1131
        bs->backing_hd = NULL;
1134 1132
        bs->open_flags |= BDRV_O_NO_BACKING;
1135 1133
        error_setg(errp, "Could not open backing file: %s",
......
1166 1164
 * BlockdevRef.
1167 1165
 *
1168 1166
 * The BlockdevRef will be removed from the options QDict.
1167
 *
1168
 * To conform with the behavior of bdrv_open(), *pbs has to be NULL.
1169 1169
 */
1170 1170
int bdrv_open_image(BlockDriverState **pbs, const char *filename,
1171 1171
                    QDict *options, const char *bdref_key, int flags,
......
1176 1176
    char *bdref_key_dot;
1177 1177
    const char *reference;
1178 1178

  
1179
    assert(pbs);
1180
    assert(*pbs == NULL);
1181

  
1179 1182
    bdref_key_dot = g_strdup_printf("%s.", bdref_key);
1180 1183
    qdict_extract_subqdict(options, &image_options, bdref_key_dot);
1181 1184
    g_free(bdref_key_dot);
......
1196 1199
        /* If a filename is given and the block driver should be detected
1197 1200
           automatically (instead of using none), use bdrv_open() in order to do
1198 1201
           that auto-detection. */
1199
        BlockDriverState *bs;
1200

  
1201 1202
        if (reference) {
1202 1203
            error_setg(errp, "Cannot reference an existing block device while "
1203 1204
                       "giving a filename");
......
1205 1206
            goto done;
1206 1207
        }
1207 1208

  
1208
        bs = bdrv_new("");
1209
        ret = bdrv_open(bs, filename, image_options, flags, NULL, errp);
1210
        if (ret < 0) {
1211
            bdrv_unref(bs);
1212
        } else {
1213
            *pbs = bs;
1214
        }
1209
        ret = bdrv_open(pbs, filename, image_options, flags, NULL, errp);
1215 1210
    } else {
1216 1211
        ret = bdrv_file_open(pbs, filename, reference, image_options, flags,
1217 1212
                             errp);
......
1229 1224
 * empty set of options. The reference to the QDict belongs to the block layer
1230 1225
 * after the call (even on failure), so if the caller intends to reuse the
1231 1226
 * dictionary, it needs to use QINCREF() before calling bdrv_open.
1227
 *
1228
 * If *pbs is NULL, a new BDS will be created with a pointer to it stored there.
1229
 * If it is not NULL, the referenced BDS will be reused.
1232 1230
 */
1233
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
1231
int bdrv_open(BlockDriverState **pbs, const char *filename, QDict *options,
1234 1232
              int flags, BlockDriver *drv, Error **errp)
1235 1233
{
1236 1234
    int ret;
1237 1235
    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
1238 1236
    char tmp_filename[PATH_MAX + 1];
1239
    BlockDriverState *file = NULL;
1237
    BlockDriverState *file = NULL, *bs;
1240 1238
    const char *drvname;
1241 1239
    Error *local_err = NULL;
1242 1240

  
1241
    assert(pbs);
1242

  
1243
    if (*pbs) {
1244
        bs = *pbs;
1245
    } else {
1246
        bs = bdrv_new("");
1247
    }
1248

  
1243 1249
    /* NULL means an empty set of options */
1244 1250
    if (options == NULL) {
1245 1251
        options = qdict_new();
......
1260 1266
           instead of opening 'filename' directly */
1261 1267

  
1262 1268
        /* Get the required size from the image */
1263
        bs1 = bdrv_new("");
1264 1269
        QINCREF(options);
1265
        ret = bdrv_open(bs1, filename, options, BDRV_O_NO_BACKING,
1270
        bs1 = NULL;
1271
        ret = bdrv_open(&bs1, filename, options, BDRV_O_NO_BACKING,
1266 1272
                        drv, &local_err);
1267 1273
        if (ret < 0) {
1268
            bdrv_unref(bs1);
1269 1274
            goto fail;
1270 1275
        }
1271 1276
        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
......
1322 1327
        flags |= BDRV_O_ALLOW_RDWR;
1323 1328
    }
1324 1329

  
1330
    assert(file == NULL);
1325 1331
    ret = bdrv_open_image(&file, filename, options, "file",
1326 1332
                          bdrv_open_flags(bs, flags | BDRV_O_UNMAP), true, true,
1327 1333
                          &local_err);
......
1393 1399
        bdrv_dev_change_media_cb(bs, true);
1394 1400
    }
1395 1401

  
1402
    *pbs = bs;
1396 1403
    return 0;
1397 1404

  
1398 1405
unlink_and_fail:
......
1406 1413
    QDECREF(bs->options);
1407 1414
    QDECREF(options);
1408 1415
    bs->options = NULL;
1416
    if (!*pbs) {
1417
        /* If *pbs is NULL, a new BDS has been created in this function and
1418
           needs to be freed now. Otherwise, it does not need to be closed,
1419
           since it has not really been opened yet. */
1420
        bdrv_unref(bs);
1421
    }
1409 1422
    if (local_err) {
1410 1423
        error_propagate(errp, local_err);
1411 1424
    }
1412 1425
    return ret;
1413 1426

  
1414 1427
close_and_fail:
1415
    bdrv_close(bs);
1428
    /* See fail path, but now the BDS has to be always closed */
1429
    if (*pbs) {
1430
        bdrv_close(bs);
1431
    } else {
1432
        bdrv_unref(bs);
1433
    }
1416 1434
    QDECREF(options);
1417 1435
    if (local_err) {
1418 1436
        error_propagate(errp, local_err);
......
5290 5308
            back_flags =
5291 5309
                flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
5292 5310

  
5293
            bs = bdrv_new("");
5294

  
5295
            ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
5311
            bs = NULL;
5312
            ret = bdrv_open(&bs, backing_file->value.s, NULL, back_flags,
5296 5313
                            backing_drv, &local_err);
5297 5314
            if (ret < 0) {
5298 5315
                error_setg_errno(errp, -ret, "Could not open '%s': %s",
......
5300 5317
                                 error_get_pretty(local_err));
5301 5318
                error_free(local_err);
5302 5319
                local_err = NULL;
5303
                bdrv_unref(bs);
5304 5320
                goto out;
5305 5321
            }
5306 5322
            bdrv_get_geometry(bs, &size);

Also available in: Unified diff