Revision a8e0fdd7
b/block/sheepdog.c | ||
---|---|---|
1286 | 1286 |
return 0; |
1287 | 1287 |
} |
1288 | 1288 |
|
1289 |
static int sd_prealloc(const char *filename) |
|
1290 |
{ |
|
1291 |
BlockDriverState *bs = NULL; |
|
1292 |
uint32_t idx, max_idx; |
|
1293 |
int64_t vdi_size; |
|
1294 |
void *buf = qemu_mallocz(SD_DATA_OBJ_SIZE); |
|
1295 |
int ret; |
|
1296 |
|
|
1297 |
ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR); |
|
1298 |
if (ret < 0) { |
|
1299 |
goto out; |
|
1300 |
} |
|
1301 |
|
|
1302 |
vdi_size = bdrv_getlength(bs); |
|
1303 |
if (vdi_size < 0) { |
|
1304 |
ret = vdi_size; |
|
1305 |
goto out; |
|
1306 |
} |
|
1307 |
max_idx = DIV_ROUND_UP(vdi_size, SD_DATA_OBJ_SIZE); |
|
1308 |
|
|
1309 |
for (idx = 0; idx < max_idx; idx++) { |
|
1310 |
/* |
|
1311 |
* The created image can be a cloned image, so we need to read |
|
1312 |
* a data from the source image. |
|
1313 |
*/ |
|
1314 |
ret = bdrv_pread(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE); |
|
1315 |
if (ret < 0) { |
|
1316 |
goto out; |
|
1317 |
} |
|
1318 |
ret = bdrv_pwrite(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE); |
|
1319 |
if (ret < 0) { |
|
1320 |
goto out; |
|
1321 |
} |
|
1322 |
} |
|
1323 |
out: |
|
1324 |
if (bs) { |
|
1325 |
bdrv_delete(bs); |
|
1326 |
} |
|
1327 |
qemu_free(buf); |
|
1328 |
|
|
1329 |
return ret; |
|
1330 |
} |
|
1331 |
|
|
1289 | 1332 |
static int sd_create(const char *filename, QEMUOptionParameter *options) |
1290 | 1333 |
{ |
1291 | 1334 |
int ret; |
... | ... | |
1295 | 1338 |
BDRVSheepdogState s; |
1296 | 1339 |
char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN]; |
1297 | 1340 |
uint32_t snapid; |
1341 |
int prealloc = 0; |
|
1342 |
const char *vdiname; |
|
1298 | 1343 |
|
1299 |
strstart(filename, "sheepdog:", (const char **)&filename);
|
|
1344 |
strstart(filename, "sheepdog:", &vdiname);
|
|
1300 | 1345 |
|
1301 | 1346 |
memset(&s, 0, sizeof(s)); |
1302 | 1347 |
memset(vdi, 0, sizeof(vdi)); |
1303 | 1348 |
memset(tag, 0, sizeof(tag)); |
1304 |
if (parse_vdiname(&s, filename, vdi, &snapid, tag) < 0) {
|
|
1349 |
if (parse_vdiname(&s, vdiname, vdi, &snapid, tag) < 0) {
|
|
1305 | 1350 |
error_report("invalid filename"); |
1306 | 1351 |
return -EINVAL; |
1307 | 1352 |
} |
... | ... | |
1311 | 1356 |
vdi_size = options->value.n; |
1312 | 1357 |
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { |
1313 | 1358 |
backing_file = options->value.s; |
1359 |
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { |
|
1360 |
if (!options->value.s || !strcmp(options->value.s, "off")) { |
|
1361 |
prealloc = 0; |
|
1362 |
} else if (!strcmp(options->value.s, "full")) { |
|
1363 |
prealloc = 1; |
|
1364 |
} else { |
|
1365 |
error_report("Invalid preallocation mode: '%s'", |
|
1366 |
options->value.s); |
|
1367 |
return -EINVAL; |
|
1368 |
} |
|
1314 | 1369 |
} |
1315 | 1370 |
options++; |
1316 | 1371 |
} |
... | ... | |
1348 | 1403 |
bdrv_delete(bs); |
1349 | 1404 |
} |
1350 | 1405 |
|
1351 |
return do_sd_create((char *)vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port); |
|
1406 |
ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port); |
|
1407 |
if (!prealloc || ret) { |
|
1408 |
return ret; |
|
1409 |
} |
|
1410 |
|
|
1411 |
return sd_prealloc(filename); |
|
1352 | 1412 |
} |
1353 | 1413 |
|
1354 | 1414 |
static void sd_close(BlockDriverState *bs) |
... | ... | |
1984 | 2044 |
.type = OPT_STRING, |
1985 | 2045 |
.help = "File name of a base image" |
1986 | 2046 |
}, |
2047 |
{ |
|
2048 |
.name = BLOCK_OPT_PREALLOC, |
|
2049 |
.type = OPT_STRING, |
|
2050 |
.help = "Preallocation mode (allowed values: off, full)" |
|
2051 |
}, |
|
1987 | 2052 |
{ NULL } |
1988 | 2053 |
}; |
1989 | 2054 |
|
Also available in: Unified diff