[Devel] [PATCH RH8 08/61] ploop: Become use top delta
Kirill Tkhai
ktkhai at virtuozzo.com
Fri May 14 18:55:18 MSK 2021
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
drivers/md/dm-ploop-map.c | 72 ++++++++++++++++++++++++++++++++++++++++++---
drivers/md/dm-ploop.h | 6 ++++
2 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index b1fd15d5516d..518075645ed9 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -5,6 +5,7 @@
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/uio.h>
+#include <uapi/linux/falloc.h>
#include "dm-ploop.h"
/*
@@ -49,6 +50,22 @@
read_unlock_irqrestore(&ploop->bat_rwlock, flags); \
} while (0)
+static unsigned int bio_nr_segs(struct bio *bio)
+{
+ struct bvec_iter bi = {
+ .bi_size = bio->bi_iter.bi_size,
+ .bi_bvec_done = bio->bi_iter.bi_bvec_done,
+ .bi_idx = bio->bi_iter.bi_idx,
+ };
+ unsigned int nr_segs = 0;
+ struct bio_vec bv;
+
+ for_each_bvec(bv, bio->bi_io_vec, bi, bi)
+ nr_segs++;
+
+ return nr_segs;
+}
+
static void ploop_index_wb_init(struct ploop_index_wb *piwb, struct ploop *ploop)
{
piwb->ploop = ploop;
@@ -410,12 +427,19 @@ static bool bio_endio_if_all_zeros(struct bio *bio)
return true;
}
+static int punch_hole(struct file *file, loff_t pos, loff_t len)
+{
+ return vfs_fallocate(file, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE,
+ pos, len);
+}
+
static void handle_discard_bio(struct ploop *ploop, struct bio *bio,
unsigned int cluster, unsigned int dst_cluster)
{
struct pio *h = bio_to_endio_hook(bio);
struct pio *inflight_h;
unsigned long flags;
+ loff_t pos;
int ret;
if (!cluster_is_in_top_delta(ploop, cluster) || ploop->nr_deltas != 1) {
@@ -463,9 +487,14 @@ static void handle_discard_bio(struct ploop *ploop, struct bio *bio,
read_unlock_irq(&ploop->bat_rwlock);
atomic_inc(&ploop->nr_discard_bios);
- remap_to_cluster(ploop, bio, dst_cluster);
remap_to_origin(ploop, bio);
- generic_make_request(bio);
+ remap_to_cluster(ploop, bio, dst_cluster);
+
+ pos = to_bytes(bio->bi_iter.bi_sector);
+ ret = punch_hole(top_delta(ploop)->file, pos, bio->bi_iter.bi_size);
+ if (ret)
+ bio->bi_status = errno_to_blk_status(ret);
+ bio_endio(bio);
}
static int ploop_discard_bio_end(struct ploop *ploop, struct bio *bio)
@@ -1279,6 +1308,41 @@ static bool locate_new_cluster_and_attach_bio(struct ploop *ploop,
return false;
}
+static void data_rw_complete(struct pio *pio)
+{
+ struct bio *bio = pio->data;
+
+ if (pio->ret != bio->bi_iter.bi_size)
+ bio->bi_status = BLK_STS_IOERR;
+
+ bio_endio(bio);
+}
+
+static void submit_rw_mapped(struct ploop *ploop, loff_t clu_pos, struct bio *bio)
+{
+ struct pio *pio = bio_to_endio_hook(bio);
+ unsigned int rw, nr_segs;
+ struct bio_vec *bvec;
+ struct iov_iter iter;
+ loff_t pos;
+
+ pio->complete = data_rw_complete;
+ pio->data = bio;
+
+ rw = (op_is_write(bio->bi_opf) ? WRITE : READ);
+ nr_segs = bio_nr_segs(bio);
+ bvec = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter);
+
+ iov_iter_bvec(&iter, rw, bvec, nr_segs, bio->bi_iter.bi_size);
+ iter.iov_offset = bio->bi_iter.bi_bvec_done;
+
+ remap_to_origin(ploop, bio);
+ remap_to_cluster(ploop, bio, clu_pos);
+ pos = to_bytes(bio->bi_iter.bi_sector);
+
+ call_rw_iter(top_delta(ploop)->file, pos, rw, &iter, bio);
+}
+
static int process_one_deferred_bio(struct ploop *ploop, struct bio *bio,
struct ploop_index_wb *piwb)
{
@@ -1343,9 +1407,7 @@ static int process_one_deferred_bio(struct ploop *ploop, struct bio *bio,
maybe_link_submitting_bio(ploop, bio, cluster);
- remap_to_cluster(ploop, bio, dst_cluster);
- remap_to_origin(ploop, bio);
- generic_make_request(bio);
+ submit_rw_mapped(ploop, dst_cluster, bio);
out:
return 0;
}
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index f8194e3869d7..55a30722b18b 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -105,6 +105,7 @@ struct ploop_cmd {
#define PLOOP_BIOS_HTABLE_BITS 8
#define PLOOP_BIOS_HTABLE_SIZE (1 << PLOOP_BIOS_HTABLE_BITS)
+#define CLU_OFF(ploop, pos) (pos & (to_bytes(1 << ploop->cluster_log) - 1))
enum piwb_type {
PIWB_TYPE_ALLOC = 0, /* Allocation of new clusters */
@@ -322,6 +323,11 @@ static inline u8 top_level(struct ploop *ploop)
return ploop->nr_deltas - 1;
}
+static inline struct ploop_delta *top_delta(struct ploop *ploop)
+{
+ return &ploop->deltas[top_level(ploop)];
+}
+
static inline void ploop_hole_set_bit(unsigned long nr, struct ploop *ploop)
{
if (!WARN_ON_ONCE(nr >= ploop->hb_nr))
More information about the Devel
mailing list