[Devel] [PATCH RHEL7 COMMIT] ploop: push_backup must pass READs intact

Konstantin Khorenko khorenko at virtuozzo.com
Tue May 10 09:37:00 PDT 2016


The commit is pushed to "branch-rh7-3.10.0-327.10.1.vz7.12.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.10.1.vz7.12.17
------>
commit 8193d31f2de13045c14475e949af2e48312d13e3
Author: Maxim Patlasov <mpatlasov at virtuozzo.com>
Date:   Tue May 10 20:37:00 2016 +0400

    ploop: push_backup must pass READs intact
    
    If push_backup is in progress (doesn't matter "full" or "incremental") and
    ploop state-machine detects incoming WRITE request to the cluster-block that
    was not push_backup-ed yet, it suspends the request until userspace reports it
    as "processed".
    
    The above is fine, but while such a WRITE request is suspended, only
    subsequent WRITEs (to given cluster-block) must be suspended too. READs must
    not. Otherwise userspace backup tool will be blocked infinintely trying
    to push_backup given cluster-block.
    
    Passing READs while blocking WRITEs must be OK because: 1) ploop has not
    finalized that first WRITE yet; 2) given cluster-block will be kept
    intact (non-modified) while the WRITE is suspended.
    
    https://jira.sw.ru/browse/PSBM-46775
    
    Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
 drivers/block/ploop/dev.c   | 7 +++++++
 include/linux/ploop/ploop.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index c7cc385..6058449 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -1137,6 +1137,11 @@ static int check_lockout(struct ploop_request *preq)
 		else if (preq->req_cluster > p->req_cluster)
 			n = n->rb_right;
 		else {
+			/* do not block backup tool READs from /dev/ploop */
+			if (!(preq->req_rw & REQ_WRITE) &&
+			    test_bit(PLOOP_REQ_ALLOW_READS, &p->state))
+				return 0;
+
 			list_add_tail(&preq->list, &p->delay_list);
 			plo->st.bio_lockouts++;
 			trace_preq_lockout(preq, p);
@@ -2030,6 +2035,7 @@ restart:
 			ploop_pb_clear_bit(plo->pbd, preq->req_cluster);
 		} else {
 			spin_lock_irq(&plo->lock);
+			__set_bit(PLOOP_REQ_ALLOW_READS, &preq->state);
 			ploop_add_lockout(preq, 0);
 			spin_unlock_irq(&plo->lock);
 			/*
@@ -2048,6 +2054,7 @@ restart:
 
 		spin_lock_irq(&plo->lock);
 		del_lockout(preq);
+		__clear_bit(PLOOP_REQ_ALLOW_READS, &preq->state);
 		if (!list_empty(&preq->delay_list))
 			list_splice_init(&preq->delay_list, plo->ready_queue.prev);
 		spin_unlock_irq(&plo->lock);
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index 762d2fd..ad36a91 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -465,6 +465,7 @@ enum
 	PLOOP_REQ_KAIO_FSYNC,	/*force image fsync by KAIO module */
 	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 */
 };
 
 enum


More information about the Devel mailing list