io.c (3c9331c47f22224118d5019b0af8eac704824d8d) | io.c (67a0fd2a9bca204d2b39f910a97c7137636a0715) |
---|---|
1/* 2 * Block layer I/O functions 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 650 unchanged lines hidden (view full) --- 659 * zeroes to the device if they currently do not return zeroes. Optional 660 * flags are passed through to bdrv_write_zeroes (e.g. BDRV_REQ_MAY_UNMAP). 661 * 662 * Returns < 0 on error, 0 on success. For error codes see bdrv_write(). 663 */ 664int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) 665{ 666 int64_t target_sectors, ret, nb_sectors, sector_num = 0; | 1/* 2 * Block layer I/O functions 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 650 unchanged lines hidden (view full) --- 659 * zeroes to the device if they currently do not return zeroes. Optional 660 * flags are passed through to bdrv_write_zeroes (e.g. BDRV_REQ_MAY_UNMAP). 661 * 662 * Returns < 0 on error, 0 on success. For error codes see bdrv_write(). 663 */ 664int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) 665{ 666 int64_t target_sectors, ret, nb_sectors, sector_num = 0; |
667 BlockDriverState *file; |
|
667 int n; 668 669 target_sectors = bdrv_nb_sectors(bs); 670 if (target_sectors < 0) { 671 return target_sectors; 672 } 673 674 for (;;) { 675 nb_sectors = MIN(target_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS); 676 if (nb_sectors <= 0) { 677 return 0; 678 } | 668 int n; 669 670 target_sectors = bdrv_nb_sectors(bs); 671 if (target_sectors < 0) { 672 return target_sectors; 673 } 674 675 for (;;) { 676 nb_sectors = MIN(target_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS); 677 if (nb_sectors <= 0) { 678 return 0; 679 } |
679 ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n); | 680 ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n, &file); |
680 if (ret < 0) { 681 error_report("error getting block status at sector %" PRId64 ": %s", 682 sector_num, strerror(-ret)); 683 return ret; 684 } 685 if (ret & BDRV_BLOCK_ZERO) { 686 sector_num += n; 687 continue; --- 773 unchanged lines hidden (view full) --- 1461 } 1462 1463 return result; 1464} 1465 1466typedef struct BdrvCoGetBlockStatusData { 1467 BlockDriverState *bs; 1468 BlockDriverState *base; | 681 if (ret < 0) { 682 error_report("error getting block status at sector %" PRId64 ": %s", 683 sector_num, strerror(-ret)); 684 return ret; 685 } 686 if (ret & BDRV_BLOCK_ZERO) { 687 sector_num += n; 688 continue; --- 773 unchanged lines hidden (view full) --- 1462 } 1463 1464 return result; 1465} 1466 1467typedef struct BdrvCoGetBlockStatusData { 1468 BlockDriverState *bs; 1469 BlockDriverState *base; |
1470 BlockDriverState **file; |
|
1469 int64_t sector_num; 1470 int nb_sectors; 1471 int *pnum; 1472 int64_t ret; 1473 bool done; 1474} BdrvCoGetBlockStatusData; 1475 1476/* --- 5 unchanged lines hidden (view full) --- 1482 * and 'pnum' is set to 0. 1483 * 1484 * 'pnum' is set to the number of sectors (including and immediately following 1485 * the specified sector) that are known to be in the same 1486 * allocated/unallocated state. 1487 * 1488 * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes 1489 * beyond the end of the disk image it will be clamped. | 1471 int64_t sector_num; 1472 int nb_sectors; 1473 int *pnum; 1474 int64_t ret; 1475 bool done; 1476} BdrvCoGetBlockStatusData; 1477 1478/* --- 5 unchanged lines hidden (view full) --- 1484 * and 'pnum' is set to 0. 1485 * 1486 * 'pnum' is set to the number of sectors (including and immediately following 1487 * the specified sector) that are known to be in the same 1488 * allocated/unallocated state. 1489 * 1490 * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes 1491 * beyond the end of the disk image it will be clamped. |
1492 * 1493 * If returned value is positive and BDRV_BLOCK_OFFSET_VALID bit is set, 'file' 1494 * points to the BDS which the sector range is allocated in. |
|
1490 */ 1491static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, 1492 int64_t sector_num, | 1495 */ 1496static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, 1497 int64_t sector_num, |
1493 int nb_sectors, int *pnum) | 1498 int nb_sectors, int *pnum, 1499 BlockDriverState **file) |
1494{ 1495 int64_t total_sectors; 1496 int64_t n; 1497 int64_t ret, ret2; 1498 1499 total_sectors = bdrv_nb_sectors(bs); 1500 if (total_sectors < 0) { 1501 return total_sectors; --- 13 unchanged lines hidden (view full) --- 1515 *pnum = nb_sectors; 1516 ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED; 1517 if (bs->drv->protocol_name) { 1518 ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE); 1519 } 1520 return ret; 1521 } 1522 | 1500{ 1501 int64_t total_sectors; 1502 int64_t n; 1503 int64_t ret, ret2; 1504 1505 total_sectors = bdrv_nb_sectors(bs); 1506 if (total_sectors < 0) { 1507 return total_sectors; --- 13 unchanged lines hidden (view full) --- 1521 *pnum = nb_sectors; 1522 ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED; 1523 if (bs->drv->protocol_name) { 1524 ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE); 1525 } 1526 return ret; 1527 } 1528 |
1523 ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum); | 1529 *file = NULL; 1530 ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum, 1531 file); |
1524 if (ret < 0) { 1525 *pnum = 0; 1526 return ret; 1527 } 1528 1529 if (ret & BDRV_BLOCK_RAW) { 1530 assert(ret & BDRV_BLOCK_OFFSET_VALID); 1531 return bdrv_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS, | 1532 if (ret < 0) { 1533 *pnum = 0; 1534 return ret; 1535 } 1536 1537 if (ret & BDRV_BLOCK_RAW) { 1538 assert(ret & BDRV_BLOCK_OFFSET_VALID); 1539 return bdrv_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS, |
1532 *pnum, pnum); | 1540 *pnum, pnum, file); |
1533 } 1534 1535 if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) { 1536 ret |= BDRV_BLOCK_ALLOCATED; 1537 } else { 1538 if (bdrv_unallocated_blocks_are_zero(bs)) { 1539 ret |= BDRV_BLOCK_ZERO; 1540 } else if (bs->backing) { 1541 BlockDriverState *bs2 = bs->backing->bs; 1542 int64_t nb_sectors2 = bdrv_nb_sectors(bs2); 1543 if (nb_sectors2 >= 0 && sector_num >= nb_sectors2) { 1544 ret |= BDRV_BLOCK_ZERO; 1545 } 1546 } 1547 } 1548 1549 if (bs->file && 1550 (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) && 1551 (ret & BDRV_BLOCK_OFFSET_VALID)) { | 1541 } 1542 1543 if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) { 1544 ret |= BDRV_BLOCK_ALLOCATED; 1545 } else { 1546 if (bdrv_unallocated_blocks_are_zero(bs)) { 1547 ret |= BDRV_BLOCK_ZERO; 1548 } else if (bs->backing) { 1549 BlockDriverState *bs2 = bs->backing->bs; 1550 int64_t nb_sectors2 = bdrv_nb_sectors(bs2); 1551 if (nb_sectors2 >= 0 && sector_num >= nb_sectors2) { 1552 ret |= BDRV_BLOCK_ZERO; 1553 } 1554 } 1555 } 1556 1557 if (bs->file && 1558 (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) && 1559 (ret & BDRV_BLOCK_OFFSET_VALID)) { |
1560 BlockDriverState *file2; |
|
1552 int file_pnum; 1553 1554 ret2 = bdrv_co_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS, | 1561 int file_pnum; 1562 1563 ret2 = bdrv_co_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS, |
1555 *pnum, &file_pnum); | 1564 *pnum, &file_pnum, &file2); |
1556 if (ret2 >= 0) { 1557 /* Ignore errors. This is just providing extra information, it 1558 * is useful but not necessary. 1559 */ 1560 if (!file_pnum) { 1561 /* !file_pnum indicates an offset at or beyond the EOF; it is 1562 * perfectly valid for the format block driver to point to such 1563 * offsets, so catch it and mark everything as zero */ --- 8 unchanged lines hidden (view full) --- 1572 1573 return ret; 1574} 1575 1576static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs, 1577 BlockDriverState *base, 1578 int64_t sector_num, 1579 int nb_sectors, | 1565 if (ret2 >= 0) { 1566 /* Ignore errors. This is just providing extra information, it 1567 * is useful but not necessary. 1568 */ 1569 if (!file_pnum) { 1570 /* !file_pnum indicates an offset at or beyond the EOF; it is 1571 * perfectly valid for the format block driver to point to such 1572 * offsets, so catch it and mark everything as zero */ --- 8 unchanged lines hidden (view full) --- 1581 1582 return ret; 1583} 1584 1585static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs, 1586 BlockDriverState *base, 1587 int64_t sector_num, 1588 int nb_sectors, |
1580 int *pnum) | 1589 int *pnum, 1590 BlockDriverState **file) |
1581{ 1582 BlockDriverState *p; 1583 int64_t ret = 0; 1584 1585 assert(bs != base); 1586 for (p = bs; p != base; p = backing_bs(p)) { | 1591{ 1592 BlockDriverState *p; 1593 int64_t ret = 0; 1594 1595 assert(bs != base); 1596 for (p = bs; p != base; p = backing_bs(p)) { |
1587 ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum); | 1597 ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum, file); |
1588 if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) { 1589 break; 1590 } 1591 /* [sector_num, pnum] unallocated on this layer, which could be only 1592 * the first part of [sector_num, nb_sectors]. */ 1593 nb_sectors = MIN(nb_sectors, *pnum); 1594 } 1595 return ret; 1596} 1597 1598/* Coroutine wrapper for bdrv_get_block_status_above() */ 1599static void coroutine_fn bdrv_get_block_status_above_co_entry(void *opaque) 1600{ 1601 BdrvCoGetBlockStatusData *data = opaque; 1602 1603 data->ret = bdrv_co_get_block_status_above(data->bs, data->base, 1604 data->sector_num, 1605 data->nb_sectors, | 1598 if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) { 1599 break; 1600 } 1601 /* [sector_num, pnum] unallocated on this layer, which could be only 1602 * the first part of [sector_num, nb_sectors]. */ 1603 nb_sectors = MIN(nb_sectors, *pnum); 1604 } 1605 return ret; 1606} 1607 1608/* Coroutine wrapper for bdrv_get_block_status_above() */ 1609static void coroutine_fn bdrv_get_block_status_above_co_entry(void *opaque) 1610{ 1611 BdrvCoGetBlockStatusData *data = opaque; 1612 1613 data->ret = bdrv_co_get_block_status_above(data->bs, data->base, 1614 data->sector_num, 1615 data->nb_sectors, |
1606 data->pnum); | 1616 data->pnum, 1617 data->file); |
1607 data->done = true; 1608} 1609 1610/* 1611 * Synchronous wrapper around bdrv_co_get_block_status_above(). 1612 * 1613 * See bdrv_co_get_block_status_above() for details. 1614 */ 1615int64_t bdrv_get_block_status_above(BlockDriverState *bs, 1616 BlockDriverState *base, 1617 int64_t sector_num, | 1618 data->done = true; 1619} 1620 1621/* 1622 * Synchronous wrapper around bdrv_co_get_block_status_above(). 1623 * 1624 * See bdrv_co_get_block_status_above() for details. 1625 */ 1626int64_t bdrv_get_block_status_above(BlockDriverState *bs, 1627 BlockDriverState *base, 1628 int64_t sector_num, |
1618 int nb_sectors, int *pnum) | 1629 int nb_sectors, int *pnum, 1630 BlockDriverState **file) |
1619{ 1620 Coroutine *co; 1621 BdrvCoGetBlockStatusData data = { 1622 .bs = bs, 1623 .base = base, | 1631{ 1632 Coroutine *co; 1633 BdrvCoGetBlockStatusData data = { 1634 .bs = bs, 1635 .base = base, |
1636 .file = file, |
|
1624 .sector_num = sector_num, 1625 .nb_sectors = nb_sectors, 1626 .pnum = pnum, 1627 .done = false, 1628 }; 1629 1630 if (qemu_in_coroutine()) { 1631 /* Fast-path if already in coroutine context */ --- 7 unchanged lines hidden (view full) --- 1639 aio_poll(aio_context, true); 1640 } 1641 } 1642 return data.ret; 1643} 1644 1645int64_t bdrv_get_block_status(BlockDriverState *bs, 1646 int64_t sector_num, | 1637 .sector_num = sector_num, 1638 .nb_sectors = nb_sectors, 1639 .pnum = pnum, 1640 .done = false, 1641 }; 1642 1643 if (qemu_in_coroutine()) { 1644 /* Fast-path if already in coroutine context */ --- 7 unchanged lines hidden (view full) --- 1652 aio_poll(aio_context, true); 1653 } 1654 } 1655 return data.ret; 1656} 1657 1658int64_t bdrv_get_block_status(BlockDriverState *bs, 1659 int64_t sector_num, |
1647 int nb_sectors, int *pnum) | 1660 int nb_sectors, int *pnum, 1661 BlockDriverState **file) |
1648{ 1649 return bdrv_get_block_status_above(bs, backing_bs(bs), | 1662{ 1663 return bdrv_get_block_status_above(bs, backing_bs(bs), |
1650 sector_num, nb_sectors, pnum); | 1664 sector_num, nb_sectors, pnum, file); |
1651} 1652 1653int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, 1654 int nb_sectors, int *pnum) 1655{ | 1665} 1666 1667int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, 1668 int nb_sectors, int *pnum) 1669{ |
1656 int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum); | 1670 BlockDriverState *file; 1671 int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum, 1672 &file); |
1657 if (ret < 0) { 1658 return ret; 1659 } 1660 return !!(ret & BDRV_BLOCK_ALLOCATED); 1661} 1662 1663/* 1664 * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] --- 1106 unchanged lines hidden --- | 1673 if (ret < 0) { 1674 return ret; 1675 } 1676 return !!(ret & BDRV_BLOCK_ALLOCATED); 1677} 1678 1679/* 1680 * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] --- 1106 unchanged lines hidden --- |