[Devel,RHEL7,COMMIT] ploop: push_backup: BUG() on list corruption in ploop_pb_add_req_to_tree()

Submitted by Konstantin Khorenko on May 16, 2017, 12:55 p.m.


Message ID 201705161255.v4GCtLOD020972@finist_cl7.x64_64.work.ct
State New
Series "ploop: push_backup: BUG() on list corruption in ploop_pb_add_req_to_tree()"
Headers show

Commit Message

Konstantin Khorenko May 16, 2017, 12:55 p.m.
The commit is pushed to "branch-rh7-3.10.0-514.16.1.vz7.32.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.16.1.vz7.32.3
commit 074a33731114428478323f35bb2e68de8632b0a0
Author: Maxim Patlasov <mpatlasov@virtuozzo.com>
Date:   Tue May 16 16:55:20 2017 +0400

    ploop: push_backup: BUG() on list corruption in ploop_pb_add_req_to_tree()
    As PSBM-65786 demonstrated, the node doesn't survive list corruption:
    after list corruption, pbd->reported_set.tree becomes corrupted too
    having some rb_node with rb_left and rb_right pointing to the rb_node itself.
    Then any search there becomes busy-loop, leading to hard lockup.
    The patch crashes the node at the moment of list corruption detection.
    Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com>
 drivers/block/ploop/push_backup.c | 7 +++++++
 1 file changed, 7 insertions(+)

Patch hide | download patch | download mbox

diff --git a/drivers/block/ploop/push_backup.c b/drivers/block/ploop/push_backup.c
index 975d2be..0a0a69c 100644
--- a/drivers/block/ploop/push_backup.c
+++ b/drivers/block/ploop/push_backup.c
@@ -489,6 +489,13 @@  static void ploop_pb_add_req_to_tree(struct ploop_request *preq,
 	    pbs->pbd->ppb_state == PLOOP_PB_ALIVE)
 		mod_timer(&pbs->timer, preq->tstamp + timeout + 1);
+	if (pbs->list.prev->next != &pbs->list) {
+		printk("list_add corruption. pbs->list.prev->next should be "
+		       "&pbs->list (%p), but was %p. (pbs->list.prev=%p)."
+		       " preq=%p\n",
+		       &pbs->list, pbs->list.prev->next, pbs->list.prev, preq);
+		BUG();
+	}
 	list_add_tail(&preq->list, &pbs->list);
 	rb_link_node(&preq->reloc_link, parent, p);