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