Revision ddf5636d 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, NULL, 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); |
... | ... | |
1125 | 1125 |
|
1126 | 1126 |
assert(bs->backing_hd == NULL); |
1127 | 1127 |
ret = bdrv_open(&bs->backing_hd, |
1128 |
*backing_filename ? backing_filename : NULL, options, |
|
1128 |
*backing_filename ? backing_filename : NULL, NULL, options,
|
|
1129 | 1129 |
back_flags, back_drv, &local_err); |
1130 | 1130 |
if (ret < 0) { |
1131 | 1131 |
bs->backing_hd = NULL; |
... | ... | |
1206 | 1206 |
goto done; |
1207 | 1207 |
} |
1208 | 1208 |
|
1209 |
ret = bdrv_open(pbs, filename, image_options, flags, NULL, errp); |
|
1209 |
ret = bdrv_open(pbs, filename, NULL, image_options, flags, NULL, errp);
|
|
1210 | 1210 |
} else { |
1211 | 1211 |
ret = bdrv_file_open(pbs, filename, reference, image_options, flags, |
1212 | 1212 |
errp); |
... | ... | |
1227 | 1227 |
* |
1228 | 1228 |
* If *pbs is NULL, a new BDS will be created with a pointer to it stored there. |
1229 | 1229 |
* If it is not NULL, the referenced BDS will be reused. |
1230 |
* |
|
1231 |
* The reference parameter may be used to specify an existing block device which |
|
1232 |
* should be opened. If specified, neither options nor a filename may be given, |
|
1233 |
* nor can an existing BDS be reused (that is, *pbs has to be NULL). |
|
1230 | 1234 |
*/ |
1231 |
int bdrv_open(BlockDriverState **pbs, const char *filename, QDict *options, |
|
1232 |
int flags, BlockDriver *drv, Error **errp) |
|
1235 |
int bdrv_open(BlockDriverState **pbs, const char *filename, |
|
1236 |
const char *reference, QDict *options, int flags, |
|
1237 |
BlockDriver *drv, Error **errp) |
|
1233 | 1238 |
{ |
1234 | 1239 |
int ret; |
1235 | 1240 |
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ |
... | ... | |
1240 | 1245 |
|
1241 | 1246 |
assert(pbs); |
1242 | 1247 |
|
1248 |
if (reference) { |
|
1249 |
bool options_non_empty = options ? qdict_size(options) : false; |
|
1250 |
QDECREF(options); |
|
1251 |
|
|
1252 |
if (*pbs) { |
|
1253 |
error_setg(errp, "Cannot reuse an existing BDS when referencing " |
|
1254 |
"another block device"); |
|
1255 |
return -EINVAL; |
|
1256 |
} |
|
1257 |
|
|
1258 |
if (filename || options_non_empty) { |
|
1259 |
error_setg(errp, "Cannot reference an existing block device with " |
|
1260 |
"additional options or a new filename"); |
|
1261 |
return -EINVAL; |
|
1262 |
} |
|
1263 |
|
|
1264 |
bs = bdrv_lookup_bs(reference, reference, errp); |
|
1265 |
if (!bs) { |
|
1266 |
return -ENODEV; |
|
1267 |
} |
|
1268 |
bdrv_ref(bs); |
|
1269 |
*pbs = bs; |
|
1270 |
return 0; |
|
1271 |
} |
|
1272 |
|
|
1243 | 1273 |
if (*pbs) { |
1244 | 1274 |
bs = *pbs; |
1245 | 1275 |
} else { |
... | ... | |
1268 | 1298 |
/* Get the required size from the image */ |
1269 | 1299 |
QINCREF(options); |
1270 | 1300 |
bs1 = NULL; |
1271 |
ret = bdrv_open(&bs1, filename, options, BDRV_O_NO_BACKING, |
|
1301 |
ret = bdrv_open(&bs1, filename, NULL, options, BDRV_O_NO_BACKING,
|
|
1272 | 1302 |
drv, &local_err); |
1273 | 1303 |
if (ret < 0) { |
1274 | 1304 |
goto fail; |
... | ... | |
5309 | 5339 |
flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); |
5310 | 5340 |
|
5311 | 5341 |
bs = NULL; |
5312 |
ret = bdrv_open(&bs, backing_file->value.s, NULL, back_flags, |
|
5342 |
ret = bdrv_open(&bs, backing_file->value.s, NULL, NULL, back_flags,
|
|
5313 | 5343 |
backing_drv, &local_err); |
5314 | 5344 |
if (ret < 0) { |
5315 | 5345 |
error_setg_errno(errp, -ret, "Could not open '%s': %s", |
Also available in: Unified diff