[Devel] [PATCH RHEL7 COMMIT] ploop: push_backup: avoid preq->state corruption
Konstantin Khorenko
khorenko at virtuozzo.com
Fri Nov 25 06:46:04 PST 2016
The commit is pushed to "branch-rh7-3.10.0-327.36.1.vz7.20.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.36.1.vz7.20.3
------>
commit da4499838c05973f78e010961f547b2418bb7db6
Author: Maxim Patlasov <mpatlasov at virtuozzo.com>
Date: Fri Nov 25 18:46:04 2016 +0400
ploop: push_backup: avoid preq->state corruption
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 26017eb..4600bfe 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;
@@ -2266,7 +2267,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 f825575..5afe643 100644
--- a/drivers/block/ploop/push_backup.c
+++ b/drivers/block/ploop/push_backup.c
@@ -926,7 +926,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 8abc6f9..280bbab 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -570,8 +570,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