Revision 0bce597d block.c
b/block.c | ||
---|---|---|
1501 | 1501 |
int bdrv_commit(BlockDriverState *bs) |
1502 | 1502 |
{ |
1503 | 1503 |
BlockDriver *drv = bs->drv; |
1504 |
BlockDriver *backing_drv; |
|
1505 | 1504 |
int64_t sector, total_sectors; |
1506 | 1505 |
int n, ro, open_flags; |
1507 |
int ret = 0, rw_ret = 0;
|
|
1506 |
int ret = 0; |
|
1508 | 1507 |
uint8_t *buf; |
1509 | 1508 |
char filename[1024]; |
1510 |
BlockDriverState *bs_rw, *bs_ro; |
|
1511 | 1509 |
|
1512 | 1510 |
if (!drv) |
1513 | 1511 |
return -ENOMEDIUM; |
... | ... | |
1516 | 1514 |
return -ENOTSUP; |
1517 | 1515 |
} |
1518 | 1516 |
|
1519 |
if (bs->backing_hd->keep_read_only) { |
|
1520 |
return -EACCES; |
|
1521 |
} |
|
1522 |
|
|
1523 | 1517 |
if (bdrv_in_use(bs) || bdrv_in_use(bs->backing_hd)) { |
1524 | 1518 |
return -EBUSY; |
1525 | 1519 |
} |
1526 | 1520 |
|
1527 |
backing_drv = bs->backing_hd->drv; |
|
1528 | 1521 |
ro = bs->backing_hd->read_only; |
1529 | 1522 |
strncpy(filename, bs->backing_hd->filename, sizeof(filename)); |
1530 | 1523 |
open_flags = bs->backing_hd->open_flags; |
1531 | 1524 |
|
1532 | 1525 |
if (ro) { |
1533 |
/* re-open as RW */ |
|
1534 |
bdrv_delete(bs->backing_hd); |
|
1535 |
bs->backing_hd = NULL; |
|
1536 |
bs_rw = bdrv_new(""); |
|
1537 |
rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR, |
|
1538 |
backing_drv); |
|
1539 |
if (rw_ret < 0) { |
|
1540 |
bdrv_delete(bs_rw); |
|
1541 |
/* try to re-open read-only */ |
|
1542 |
bs_ro = bdrv_new(""); |
|
1543 |
ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, |
|
1544 |
backing_drv); |
|
1545 |
if (ret < 0) { |
|
1546 |
bdrv_delete(bs_ro); |
|
1547 |
/* drive not functional anymore */ |
|
1548 |
bs->drv = NULL; |
|
1549 |
return ret; |
|
1550 |
} |
|
1551 |
bs->backing_hd = bs_ro; |
|
1552 |
return rw_ret; |
|
1526 |
if (bdrv_reopen(bs->backing_hd, open_flags | BDRV_O_RDWR, NULL)) { |
|
1527 |
return -EACCES; |
|
1553 | 1528 |
} |
1554 |
bs->backing_hd = bs_rw; |
|
1555 | 1529 |
} |
1556 | 1530 |
|
1557 | 1531 |
total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; |
... | ... | |
1588 | 1562 |
g_free(buf); |
1589 | 1563 |
|
1590 | 1564 |
if (ro) { |
1591 |
/* re-open as RO */ |
|
1592 |
bdrv_delete(bs->backing_hd); |
|
1593 |
bs->backing_hd = NULL; |
|
1594 |
bs_ro = bdrv_new(""); |
|
1595 |
ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR, |
|
1596 |
backing_drv); |
|
1597 |
if (ret < 0) { |
|
1598 |
bdrv_delete(bs_ro); |
|
1599 |
/* drive not functional anymore */ |
|
1600 |
bs->drv = NULL; |
|
1601 |
return ret; |
|
1602 |
} |
|
1603 |
bs->backing_hd = bs_ro; |
|
1604 |
bs->backing_hd->keep_read_only = 0; |
|
1565 |
/* ignoring error return here */ |
|
1566 |
bdrv_reopen(bs->backing_hd, open_flags & ~BDRV_O_RDWR, NULL); |
|
1605 | 1567 |
} |
1606 | 1568 |
|
1607 | 1569 |
return ret; |
Also available in: Unified diff