[Devel] [PATCH RHEL8 COMMIT] ploop: Introduce aio interfaces

Konstantin Khorenko khorenko at virtuozzo.com
Mon May 17 19:04:39 MSK 2021


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.30
------>
commit 3101438c7a013cdc5058ebeabe9538f4f7ed13df
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Mon May 17 19:04:39 2021 +0300

    ploop: Introduce aio interfaces
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    
    =====================
    Patchset description:
    
    dm-ploop: Kill loop
    
    Intermediate patches can't be base for bisect.
    
    In scope of https://jira.sw.ru/browse/PSBM-123654
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-ploop-map.c    |  5 ---
 drivers/md/dm-ploop-target.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/md/dm-ploop.h        | 15 ++++++++-
 3 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index c15e08a2dcd1..9fe77addcb63 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -66,11 +66,6 @@ static void ploop_index_wb_init(struct ploop_index_wb *piwb, struct ploop *ploop
 	piwb->type = PIWB_TYPE_ALLOC;
 }
 
-static struct pio *bio_to_endio_hook(struct bio *bio)
-{
-	return dm_per_bio_data(bio, sizeof(struct pio));
-}
-
 static void __ploop_init_end_io(struct ploop *ploop, struct pio *pio)
 {
 	pio->action = PLOOP_END_IO_NONE;
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index e9f1eaf51eb0..e3955819f341 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -9,6 +9,7 @@
 #include <linux/file.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/uio.h>
 #include "dm-ploop.h"
 
 #define DM_MSG_PREFIX "ploop"
@@ -21,6 +22,81 @@ MODULE_PARM_DESC(ignore_signature_disk_in_use,
 struct kmem_cache *piocb_cache;
 struct kmem_cache *cow_cache;
 
+static void ploop_aio_do_completion(struct pio *pio)
+{
+	if (!atomic_dec_and_test(&pio->aio_ref))
+		return;
+	pio->complete(pio);
+}
+
+static void ploop_aio_complete(struct kiocb *iocb, long ret, long ret2)
+{
+	struct pio *pio;
+
+	pio = container_of(iocb, struct pio, iocb);
+
+	WARN_ON_ONCE(ret > INT_MAX);
+	pio->ret = (int)ret;
+	ploop_aio_do_completion(pio);
+}
+
+void call_rw_iter(struct file *file, loff_t pos, unsigned rw,
+		  struct iov_iter *iter, struct bio *bio)
+{
+	struct pio *pio = bio_to_endio_hook(bio);
+	struct kiocb *iocb = &pio->iocb;
+	int ret;
+
+	iocb->ki_pos = pos;
+	iocb->ki_filp = file;
+	iocb->ki_complete = ploop_aio_complete;
+	iocb->ki_flags = IOCB_DIRECT;
+	iocb->ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
+
+	atomic_set(&pio->aio_ref, 2);
+
+	if (rw == WRITE)
+		ret = call_write_iter(file, iocb, iter);
+	else
+		ret = call_read_iter(file, iocb, iter);
+
+	ploop_aio_do_completion(pio);
+
+	if (ret != -EIOCBQUEUED)
+		iocb->ki_complete(iocb, ret, 0);
+}
+
+static int rw_page_sync(unsigned rw, struct file *file,
+			u64 index, struct page *page)
+{
+	struct bio_vec *bvec, bvec_on_stack;
+	struct iov_iter iter;
+	ssize_t ret;
+	loff_t pos;
+
+	BUG_ON(rw != READ && rw != WRITE);
+
+	bvec = &bvec_on_stack;
+	bvec->bv_page = page;
+	bvec->bv_len = PAGE_SIZE;
+	bvec->bv_offset = 0;
+
+	iov_iter_bvec(&iter, rw, bvec, 1, PAGE_SIZE);
+	pos = index << PAGE_SHIFT;
+
+	if (rw == READ)
+		ret = vfs_iter_read(file, &iter, &pos, 0);
+	else
+		ret = vfs_iter_write(file, &iter, &pos, 0);
+
+	if (ret == PAGE_SIZE)
+		ret = 0;
+	else if (ret >= 0)
+		ret = -ENODATA;
+
+	return ret;
+}
+
 static void inflight_bios_ref_exit0(struct percpu_ref *ref)
 {
 	struct ploop *ploop = container_of(ref, struct ploop,
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 53e7060df8e3..290924dc9b54 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -251,6 +251,12 @@ struct pio {
 	unsigned int ref_index:2;
 
 	struct ploop_index_wb *piwb;
+
+	struct kiocb iocb;
+	atomic_t aio_ref;
+	int ret; /* iocb result */
+	void (*complete)(struct pio *me);
+	void *data;
 };
 
 struct ploop_iocb {
@@ -467,6 +473,12 @@ static inline struct pio *find_endio_hook(struct ploop *ploop, struct rb_root *r
 
 extern int prealloc_md_pages(struct rb_root *root, unsigned int nr_bat_entries,
 			     unsigned int new_nr_bat_entries);
+
+static inline struct pio *bio_to_endio_hook(struct bio *bio)
+{
+	return dm_per_bio_data(bio, sizeof(struct pio));
+}
+
 extern void md_page_insert(struct ploop *ploop, struct md_page *md);
 extern void free_md_page(struct md_page *md);
 extern void free_md_pages_tree(struct rb_root *root);
@@ -508,5 +520,6 @@ extern int ploop_read_cluster_sync(struct ploop *, struct bio *, unsigned int);
 extern int ploop_read_metadata(struct dm_target *ti, struct ploop *ploop, u8 nr_deltas);
 extern int ploop_read_delta_metadata(struct ploop *ploop, struct file *file,
 				     void **d_hdr);
-
+extern void call_rw_iter(struct file *file, loff_t pos, unsigned rw,
+			 struct iov_iter *iter, struct bio *bio);
 #endif /* __DM_PLOOP_H */


More information about the Devel mailing list