[Devel] [PATCH rh7 17/38] ploop: add ioctl to limit size of top delta (v2)

Andrey Smetanin asmetanin at virtuozzo.com
Fri May 15 09:48:18 PDT 2015


customer created an online backup => backup.tib file.  Most probably the
.tib file is inconsistent and in order to correctly access data inside
we need to replay the journal.

=> We have to provide to container a bundle of .tib file (read-only) and
a tiny read-writeable ploop delta - journal replayed data will be stored
there.

A cunning customer can notice that the delta is writeble and fill it
with his own data - unlimited.

=> we need an ability to limit the ploop delta max size.

https://jira.sw.ru/browse/PSBM-22002

v2: move declaration of PLOOP_IOC_MAX_DELTA_SIZE

Signed-off-by: Andrew Vagin <avagin at openvz.org>
Acked-by: Maxim V. Patlasov <mpatlasov at parallels.com>
---
 drivers/block/ploop/dev.c        | 20 ++++++++++++++++++++
 drivers/block/ploop/fmt_ploop1.c |  5 +++++
 include/linux/ploop/ploop.h      |  2 ++
 include/linux/ploop/ploop_if.h   |  3 +++
 4 files changed, 30 insertions(+)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 0124349..33f8442 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -2770,6 +2770,7 @@ init_delta(struct ploop_device * plo, struct ploop_ctl * ctl, int level)
 	delta->plo = plo;
 	delta->ops = ops;
 	delta->flags = ctl->pctl_flags & PLOOP_FMT_FLAGS;
+	delta->max_delta_size = ULLONG_MAX;
 
 	KOBJECT_INIT(&delta->kobj, &ploop_delta_ktype);
 	return delta;
@@ -2780,6 +2781,22 @@ out_err:
 }
 
 
+static int ploop_set_max_delta_size(struct ploop_device *plo, unsigned long arg)
+{
+	struct ploop_delta * top_delta = ploop_top_delta(plo);
+	u64 max_delta_size;
+
+	if (copy_from_user(&max_delta_size, (void*)arg, sizeof(u64)))
+		return -EFAULT;
+
+	if (top_delta == NULL)
+		return -EINVAL;
+
+	top_delta->max_delta_size = max_delta_size;
+
+	return 0;
+}
+
 static int ploop_add_delta(struct ploop_device * plo, unsigned long arg)
 {
 	int err;
@@ -4419,6 +4436,9 @@ static int ploop_ioctl(struct block_device *bdev, fmode_t fmode, unsigned int cm
 	case PLOOP_IOC_DISCARD_WAIT:
 		err = ploop_discard_wait_ioc(plo);
 		break;
+	case PLOOP_IOC_MAX_DELTA_SIZE:
+		err = ploop_set_max_delta_size(plo, arg);
+		break;
 	default:
 		err = -EINVAL;
 	}
diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index 5ce6915..585f6ce 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -222,6 +222,11 @@ static void
 ploop1_allocate(struct ploop_delta * delta, struct ploop_request * preq,
 		struct bio_list * sbl, unsigned int size)
 {
+	if (delta->io.alloc_head >=
+			(delta->max_delta_size >> delta->cluster_log)) {
+		ploop_fail_request(preq, -E2BIG);
+		return;
+	}
 	delta->io.ops->submit_alloc(&delta->io, preq, sbl, size);
 }
 
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index 434789e..ae3dbfc 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -286,6 +286,8 @@ struct ploop_delta
 	struct ploop_delta_ops	*ops;
 
 	struct kobject		kobj;
+
+	u64			max_delta_size; /* in sectors */
 };
 
 struct ploop_tunable
diff --git a/include/linux/ploop/ploop_if.h b/include/linux/ploop/ploop_if.h
index 45b74fc..aacddb3 100644
--- a/include/linux/ploop/ploop_if.h
+++ b/include/linux/ploop/ploop_if.h
@@ -299,6 +299,9 @@ struct ploop_track_extent
 /* Filter extents with sizes less than arg */
 #define PLOOP_IOC_FBFILTER	_IOR(PLOOPCTLTYPE, 27, unsigned long)
 
+/* Set maximum size for the top delta . */
+#define PLOOP_IOC_MAX_DELTA_SIZE _IOW(PLOOPCTLTYPE, 28, __u64)
+
 /* Events exposed via /sys/block/ploopN/pstate/event */
 #define PLOOP_EVENT_ABORTED	1
 #define PLOOP_EVENT_STOPPED	2
-- 
1.9.3




More information about the Devel mailing list