[Devel] [PATCH RH8 06/61] ploop: Introduce aio interfaces
Kirill Tkhai
ktkhai at virtuozzo.com
Fri May 14 18:55:07 MSK 2021
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