Signed-off-by: Dmitry Monakhov <dmonak...@openvz.org>
---
drivers/block/ploop/dev.c | 10 ++++++----
drivers/block/ploop/io_direct.c | 15 ++++++++++++---
include/linux/ploop/ploop.h | 12 +++++++++++-
3 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index e405232..e8b0304 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -2351,10 +2351,12 @@ static void ploop_req_state_process(struct
ploop_request * preq)
preq->prealloc_size = 0; /* only for sanity */
}
- if (test_bit(PLOOP_REQ_POST_SUBMIT, &preq->state)) {
- preq->eng_io->ops->post_submit(preq->eng_io, preq);
- clear_bit(PLOOP_REQ_POST_SUBMIT, &preq->state);
+ if (test_and_clear_bit(PLOOP_REQ_POST_SUBMIT, &preq->state)) {
+ struct ploop_io *io = preq->eng_io;
+
preq->eng_io = NULL;
+ if (preq->eng_io->ops->post_submit(io, preq))
+ goto out;
}
restart:
@@ -2633,7 +2635,7 @@ restart:
default:
BUG();
}
-
+out:
if (release_ioc) {
struct io_context * ioc = current->io_context;
current->io_context = saved_ioc;
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index f1812fe..ec905b4 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -416,8 +416,8 @@ try_again:
}
preq->iblock = iblk;
- preq->eng_io = io;
- set_bit(PLOOP_REQ_POST_SUBMIT, &preq->state);
+ set_bit(PLOOP_REQ_DEL_CONV, &preq->state);
+ ploop_add_post_submit(io, preq);
dio_submit_pad(io, preq, sbl, size, em);
err = 0;
goto end_write;
@@ -501,7 +501,7 @@ end_write:
}
static void
-dio_post_submit(struct ploop_io *io, struct ploop_request * preq)
+dio_convert_extent(struct ploop_io *io, struct ploop_request * preq)
{
struct ploop_device *plo = preq->plo;
sector_t sec = (sector_t)preq->iblock << preq->plo->cluster_log;
@@ -540,6 +540,15 @@ dio_post_submit(struct ploop_io *io, struct ploop_request
* preq)
}
}
+static int
+dio_post_submit(struct ploop_io *io, struct ploop_request * preq)
+{
+ if (test_and_clear_bit(PLOOP_REQ_DEL_CONV, &preq->state))
+ dio_convert_extent(io, preq);
+
+ return 0;
+}
+
/* Submit the whole cluster. If preq contains only partial data
* within the cluster, pad the rest of cluster with zeros.
*/
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index 0fba25e..4c52a40 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -148,7 +148,7 @@ struct ploop_io_ops
struct bio_list *sbl, iblock_t iblk, unsigned int
size);
void (*submit_alloc)(struct ploop_io *, struct ploop_request *,
struct bio_list *sbl, unsigned int size);
- void (*post_submit)(struct ploop_io *, struct ploop_request *);
+ int (*post_submit)(struct ploop_io *, struct ploop_request *);
int (*disable_merge)(struct ploop_io * io, sector_t isector, unsigned int len);
int (*fastmap)(struct ploop_io * io, struct bio *orig_bio,
@@ -471,6 +471,7 @@ enum
PLOOP_REQ_POST_SUBMIT, /* preq needs post_submit processing */
PLOOP_REQ_PUSH_BACKUP, /* preq was ACKed by userspace push_backup */
PLOOP_REQ_ALLOW_READS, /* READs are allowed for given req_cluster */
+ PLOOP_REQ_DEL_CONV, /* post_submit: conversion required */
PLOOP_REQ_FSYNC_DONE, /* fsync_thread() performed f_op->fsync() */
};
@@ -479,6 +480,8 @@ enum
#define PLOOP_REQ_RELOC_S_FL (1 << PLOOP_REQ_RELOC_S)
#define PLOOP_REQ_DISCARD_FL (1 << PLOOP_REQ_DISCARD)
#define PLOOP_REQ_ZERO_FL (1 << PLOOP_REQ_ZERO)
+#define PLOOP_REQ_POST_SUBMIT_FL (1 << PLOOP_REQ_POST_SUBMIT)
+#define PLOOP_REQ_DEL_CONV_FL (1 << PLOOP_REQ_DEL_CONV)
enum
{
@@ -767,6 +770,13 @@ static inline void ploop_entry_qlen_dec(struct
ploop_request * preq)
preq->plo->read_sync_reqs--;
}
}
+static inline
+void ploop_add_post_submit(struct ploop_io *io, struct ploop_request * preq)
+{
+ BUG_ON(preq->eng_io && preq->eng_io != io);
+ preq->eng_io = io;
+ set_bit(PLOOP_REQ_POST_SUBMIT, &preq->state);
+}
static inline int ploop_map_log(struct ploop_device *plo)
{