[Devel] [PATCH rh7] ploop: push_backup: avoid preq->state corruption
Maxim Patlasov
mpatlasov at virtuozzo.com
Sun Oct 30 10:37:59 PDT 2016
ploop-state-machine does not expect someone else changing preq->state.
Hence, __set_bit(lockout_bit, &preq->state) called from ploop_thread()
races with __set_bit(PLOOP_REQ_PUSH_BACKUP, &preq->state) called from
ioctl(PLOOP_IOC_PUSH_BACKUP_IO) handler.
The only place where push_backup engine modifies preq->state is that
__set_bit(PLOOP_REQ_PUSH_BACKUP, &preq->state) from ploop_pb_process_extent().
So the patch simply moves this bit from preq->state to preq->ppb_state
ensuring that only race-safe set_bit() changes it.
Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
drivers/block/ploop/dev.c | 3 ++-
drivers/block/ploop/push_backup.c | 2 +-
include/linux/ploop/ploop.h | 9 +++++++--
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index a8720db..8bfd96a 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -521,6 +521,7 @@ ploop_bio_queue(struct ploop_device * plo, struct bio * bio,
preq->req_rw = bio->bi_rw;
preq->eng_state = PLOOP_E_ENTRY;
preq->state = 0;
+ preq->ppb_state = 0;
preq->error = 0;
preq->tstamp = jiffies;
preq->iblock = 0;
@@ -2201,7 +2202,7 @@ restart:
return;
}
} else if (test_bit(PLOOP_REQ_PB_LOCKOUT, &preq->state) &&
- test_and_clear_bit(PLOOP_REQ_PUSH_BACKUP, &preq->state)) {
+ test_and_clear_bit(PLOOP_REQ_PUSH_BACKUP, &preq->ppb_state)) {
/*
* preq OUT: out-of-band push_backup processing by
* userspace done; preq was re-scheduled
diff --git a/drivers/block/ploop/push_backup.c b/drivers/block/ploop/push_backup.c
index 8f19310..975d2be 100644
--- a/drivers/block/ploop/push_backup.c
+++ b/drivers/block/ploop/push_backup.c
@@ -924,7 +924,7 @@ static void ploop_pb_process_extent(struct pb_set *pbs, cluster_t clu,
while (preq) {
struct rb_node *n;
- __set_bit(PLOOP_REQ_PUSH_BACKUP, &preq->state);
+ set_bit(PLOOP_REQ_PUSH_BACKUP, &preq->ppb_state);
list_add(&preq->list, ready_list);
if (n_found)
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index b8c480a..c14da7b 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -567,8 +567,13 @@ struct ploop_request
iblock_t iblock;
/* relocation info */
- iblock_t src_iblock;
- iblock_t dst_iblock;
+ union {
+ struct {
+ iblock_t src_iblock;
+ iblock_t dst_iblock;
+ };
+ unsigned long ppb_state;
+ };
cluster_t dst_cluster;
struct rb_node reloc_link;
More information about the Devel
mailing list