[RHEL8,COMMIT] dm-ploop: Skip zero writes to unallocated clusters

Submitted by Konstantin Khorenko on Dec. 22, 2020, 11:21 a.m.

Details

Message ID 202012221121.0BMBLDk8228007@finist-co8.sw.ru
State New
Series "dm-ploop: Skip zero writes to unallocated clusters"
Headers show

Commit Message

Konstantin Khorenko Dec. 22, 2020, 11:21 a.m.
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.3
------>
commit 8d9b6a4975972a522c1790ad5cc93c221e68604a
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Tue Dec 22 14:21:13 2020 +0300

    dm-ploop: Skip zero writes to unallocated clusters
    
    Sometimes this may save some space...
    
    https://jira.sw.ru/browse/PSBM-123748
    
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 drivers/md/dm-ploop-map.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Patch hide | download patch | download mbox

diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 4b12b5fc082a..f193b25cbd28 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -397,6 +397,27 @@  static void maybe_unlink_completed_bio(struct ploop *ploop, struct bio *bio)
 		queue_work(ploop->wq, &ploop->worker);
 }
 
+static bool bio_endio_if_all_zeros(struct bio *bio)
+{
+	struct bvec_iter bi = {
+		.bi_size = bio->bi_iter.bi_size,
+	};
+	struct bio_vec bv;
+	void *data, *ret;
+
+	for_each_bvec(bv, bio->bi_io_vec, bi, bi) {
+		data = kmap(bv.bv_page);
+		ret = memchr_inv(data + bv.bv_offset, 0, bv.bv_len);
+		kunmap(bv.bv_page);
+		if (ret)
+			return false;
+	}
+
+	bio->bi_status = BLK_STS_OK;
+	bio_endio(bio);
+	return true;
+}
+
 static void handle_discard_bio(struct ploop *ploop, struct bio *bio,
 		     unsigned int cluster, unsigned int dst_cluster)
 {
@@ -1326,6 +1347,9 @@  static int process_one_deferred_bio(struct ploop *ploop, struct bio *bio,
 		goto out;
 	}
 
+	if (unlikely(bio_endio_if_all_zeros(bio)))
+		goto out;
+
 	/* Cluster exists nowhere. Allocate it and setup bio as outrunning */
 	ret = locate_new_cluster_and_attach_bio(ploop, piwb, cluster,
 						&dst_cluster, bio);