[Devel] [PATCH RHEL7 COMMIT] ploop: ensure non-empty delta list on running ploop

Konstantin Khorenko khorenko at odin.com
Mon May 18 21:27:05 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.1
------>
commit ace664d9412efd2fa814851b0be55751dc9ed13a
Author: Andrey Smetanin <asmetanin at virtuozzo.com>
Date:   Tue May 19 08:27:05 2015 +0400

    ploop: ensure non-empty delta list on running ploop
    
    The only allowed use-case for delta removal on running ploop is the merge
    operation. But merge never removes base delta. Hence, we can prohibit
    base delta removal if ploop is in RUNNING state. This resolves the following
    issue: buggy userspace removes all deltas from a running ploop, but leaves
    ploop in RUNNING state making any further ploop-mount impossible.
    
    https://jira.sw.ru/browse/PSBM-25102
    
    Signed-off-by: Maxim Patlasov <MPatlasov at parallels.com>
    
    Acked-by: Pavel Emelyanov <xemul at parallels.com>
---
 drivers/block/ploop/dev.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 33f8442..d2a9eb4 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -3173,6 +3173,12 @@ static int ploop_del_delta(struct ploop_device * plo, unsigned long arg)
 	if (plo->maintenance_type != PLOOP_MNTN_OFF)
 		return -EBUSY;
 
+	if (level == 0 && test_bit(PLOOP_S_RUNNING, &plo->state)) {
+		printk(KERN_INFO "Can't del base delta on running ploop%d\n",
+		       plo->index);
+		return -EBUSY;
+	}
+
 	delta = find_delta(plo, level);
 
 	if (delta == NULL)
@@ -3197,6 +3203,8 @@ static int ploop_del_delta(struct ploop_device * plo, unsigned long arg)
 	delta->ops->stop(delta);
 	delta->ops->destroy(delta);
 	kobject_put(&delta->kobj);
+	BUG_ON(test_bit(PLOOP_S_RUNNING, &plo->state) &&
+	       list_empty(&plo->map.delta_list));
 	return 0;
 }
 
@@ -3573,6 +3581,7 @@ static int ploop_start(struct ploop_device * plo, struct block_device *bdev)
 
 	wake_up_process(plo->thread);
 	set_bit(PLOOP_S_RUNNING, &plo->state);
+	BUG_ON(list_empty(&plo->map.delta_list));
 	return 0;
 
 out_err:
@@ -3605,8 +3614,11 @@ static int ploop_stop(struct ploop_device * plo, struct block_device *bdev)
 	if (!test_bit(PLOOP_S_RUNNING, &plo->state))
 		return -EINVAL;
 
-	if (list_empty(&plo->map.delta_list))
+	if (list_empty(&plo->map.delta_list)) {
+		printk(KERN_INFO "stop ploop%d failed (no deltas)\n",
+		       plo->index);
 		return -ENOENT;
+	}
 
 	cnt = atomic_read(&plo->open_count);
 	if (cnt > 1) {
@@ -3755,6 +3767,7 @@ static int ploop_clear(struct ploop_device * plo, struct block_device * bdev)
 	plo->maintenance_type = PLOOP_MNTN_OFF;
 	plo->bd_size = 0;
 	plo->state = (1 << PLOOP_S_CHANGED);
+	BUG_ON(test_bit(PLOOP_S_RUNNING, &plo->state));
 	return 0;
 }
 



More information about the Devel mailing list