* [Qemu-devel] [PATCH v2] qcow2: Add bdrv_discard support
@ 2011-01-28 11:41 Kevin Wolf
2011-01-28 12:46 ` Stefan Hajnoczi
0 siblings, 1 reply; 4+ messages in thread
From: Kevin Wolf @ 2011-01-28 11:41 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
This adds a bdrv_discard function to qcow2 that frees the discarded clusters.
It does not yet pass the discard on to the underlying file system driver, but
the space can be reused by future writes to the image.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
v2:
- Added offset > end_offset check
block/qcow2-cluster.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
block/qcow2.c | 8 +++++
block/qcow2.h | 2 +
3 files changed, 92 insertions(+), 0 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 1c2003a..5fb8c66 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -888,3 +888,85 @@ int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
}
return 0;
}
+
+/*
+ * This discards as many clusters of nb_clusters as possible at once (i.e.
+ * all clusters in the same L2 table) and returns the number of discarded
+ * clusters.
+ */
+static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
+ unsigned int nb_clusters)
+{
+ BDRVQcowState *s = bs->opaque;
+ uint64_t l2_offset, *l2_table;
+ int l2_index;
+ int ret;
+ int i;
+
+ ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Limit nb_clusters to one L2 table */
+ nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
+
+ for (i = 0; i < nb_clusters; i++) {
+ uint64_t old_offset;
+
+ old_offset = be64_to_cpu(l2_table[l2_index + i]);
+ old_offset &= ~QCOW_OFLAG_COPIED;
+
+ if (old_offset == 0) {
+ continue;
+ }
+
+ /* First remove L2 entries */
+ qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
+ l2_table[l2_index + i] = cpu_to_be64(0);
+
+ /* Then decrease the refcount */
+ qcow2_free_any_clusters(bs, old_offset, 1);
+ }
+
+ ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return nb_clusters;
+}
+
+int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
+ int nb_sectors)
+{
+ BDRVQcowState *s = bs->opaque;
+ uint64_t end_offset;
+ unsigned int nb_clusters;
+ int ret;
+
+ end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS);
+
+ /* Round start up and end down */
+ offset = align_offset(offset, s->cluster_size);
+ end_offset &= ~(s->cluster_size - 1);
+
+ if (offset > end_offset) {
+ return 0;
+ }
+
+ nb_clusters = size_to_clusters(s, end_offset - offset);
+
+ /* Each L2 table is handled by its own loop iteration */
+ while (nb_clusters > 0) {
+ ret = discard_single_l2(bs, offset, nb_clusters);
+ if (ret < 0) {
+ return ret;
+ }
+
+ nb_clusters -= ret;
+ offset += (ret * s->cluster_size);
+ }
+
+ return 0;
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index 49bf7b9..dbe4fdd 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1084,6 +1084,13 @@ static int qcow2_make_empty(BlockDriverState *bs)
return 0;
}
+static int qcow2_discard(BlockDriverState *bs, int64_t sector_num,
+ int nb_sectors)
+{
+ return qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
+ nb_sectors);
+}
+
static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
{
BDRVQcowState *s = bs->opaque;
@@ -1349,6 +1356,7 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_aio_writev = qcow2_aio_writev,
.bdrv_aio_flush = qcow2_aio_flush,
+ .bdrv_discard = qcow2_discard,
.bdrv_truncate = qcow2_truncate,
.bdrv_write_compressed = qcow2_write_compressed,
diff --git a/block/qcow2.h b/block/qcow2.h
index 6d80120..a019831 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -209,6 +209,8 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
int compressed_size);
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
+int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
+ int nb_sectors);
/* qcow2-snapshot.c functions */
int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2] qcow2: Add bdrv_discard support
2011-01-28 11:41 Kevin Wolf
@ 2011-01-28 12:46 ` Stefan Hajnoczi
0 siblings, 0 replies; 4+ messages in thread
From: Stefan Hajnoczi @ 2011-01-28 12:46 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On Fri, Jan 28, 2011 at 11:41 AM, Kevin Wolf <kwolf@redhat.com> wrote:
> This adds a bdrv_discard function to qcow2 that frees the discarded clusters.
> It does not yet pass the discard on to the underlying file system driver, but
> the space can be reused by future writes to the image.
>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>
> v2:
> - Added offset > end_offset check
>
> block/qcow2-cluster.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
> block/qcow2.c | 8 +++++
> block/qcow2.h | 2 +
> 3 files changed, 92 insertions(+), 0 deletions(-)
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2] qcow2: Add bdrv_discard support
@ 2014-08-24 16:38 Jun Li
2014-08-27 14:12 ` Stefan Hajnoczi
0 siblings, 1 reply; 4+ messages in thread
From: Jun Li @ 2014-08-24 16:38 UTC (permalink / raw)
To: kwolf, stefanha; +Cc: qemu-devel
Hi Kevin and Stefan,
As the realize of bdrv_discard, and this patch has been received, but
I have some question.
This adds a bdrv_discard function to qcow2 that frees the discarded clusters.
It does not yet pass the discard on to the underlying file system driver, but
the space can be reused by future writes to the image.
Above content is on url:
https://lists.gnu.org/archive/html/qemu-devel/2011-01/msg03100.html
I have following question:
Why bdrv_discard does not yet pass the discard on to the underlying file
system driver? And this exist a potential issue: host cluster leak for
qcow2. As qcow2 image can be created on RAW disk,
so this is not just "does not yet pass the discard on to the underlying
file system driver". Could you give some explanation why do not realize
this function? Thx.
As I am trying to realize qcow2 shrinking, but hit bdrv_discard can not
release the free cluster on host.
Best Regards,
Jun Li
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2] qcow2: Add bdrv_discard support
2014-08-24 16:38 [Qemu-devel] [PATCH v2] qcow2: Add bdrv_discard support Jun Li
@ 2014-08-27 14:12 ` Stefan Hajnoczi
0 siblings, 0 replies; 4+ messages in thread
From: Stefan Hajnoczi @ 2014-08-27 14:12 UTC (permalink / raw)
To: Jun Li; +Cc: kwolf, qemu-devel, stefanha
[-- Attachment #1: Type: text/plain, Size: 809 bytes --]
On Mon, Aug 25, 2014 at 12:38:06AM +0800, Jun Li wrote:
> Why bdrv_discard does not yet pass the discard on to the underlying file
> system driver? And this exist a potential issue: host cluster leak for
> qcow2. As qcow2 image can be created on RAW disk,
> so this is not just "does not yet pass the discard on to the underlying file
> system driver". Could you give some explanation why do not realize this
> function? Thx.
>
> As I am trying to realize qcow2 shrinking, but hit bdrv_discard can not
> release the free cluster on host.
qcow2 is capable of passing discards down to the image file. See
qcow2_process_discards().
It is important that s->discard_passthrough[QCOW2_DISCARD_REQUEST] is
true! Make sure to use the pass-discard-request=on or discard=unmap
options.
Stefan
[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-08-27 14:13 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-24 16:38 [Qemu-devel] [PATCH v2] qcow2: Add bdrv_discard support Jun Li
2014-08-27 14:12 ` Stefan Hajnoczi
-- strict thread matches above, loose matches on Subject: below --
2011-01-28 11:41 Kevin Wolf
2011-01-28 12:46 ` Stefan Hajnoczi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).