Re: [Devel] [PATCH rh7 1/4] ploop: introduce pbd

2016-04-30 Thread Dmitry Monakhov
Maxim Patlasov  writes:

> The patch introduce push_backup descriptor ("pbd") and a few simple
> functions to create and release it.
>
> Userspace can govern it by new ioctls: PLOOP_IOC_PUSH_BACKUP_INIT and
> PLOOP_IOC_PUSH_BACKUP_STOP.
Acked-by: Dmitry Monakhov 
>
> Signed-off-by: Maxim Patlasov 
> ---
>  drivers/block/ploop/Makefile  |2 
>  drivers/block/ploop/dev.c |   89 
>  drivers/block/ploop/push_backup.c |  271 
> +
>  drivers/block/ploop/push_backup.h |8 +
>  include/linux/ploop/ploop.h   |3 
>  include/linux/ploop/ploop_if.h|   19 +++
>  6 files changed, 391 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/block/ploop/push_backup.c
>  create mode 100644 drivers/block/ploop/push_backup.h
>
> diff --git a/drivers/block/ploop/Makefile b/drivers/block/ploop/Makefile
> index e36a027..0fecf16 100644
> --- a/drivers/block/ploop/Makefile
> +++ b/drivers/block/ploop/Makefile
> @@ -5,7 +5,7 @@ CFLAGS_io_direct.o = -I$(src)
>  CFLAGS_ploop_events.o = -I$(src)
>  
>  obj-$(CONFIG_BLK_DEV_PLOOP)  += ploop.o
> -ploop-objs := dev.o map.o io.o sysfs.o tracker.o freeblks.o ploop_events.o 
> discard.o
> +ploop-objs := dev.o map.o io.o sysfs.o tracker.o freeblks.o ploop_events.o 
> discard.o push_backup.o
>  
>  obj-$(CONFIG_BLK_DEV_PLOOP)  += pfmt_ploop1.o
>  pfmt_ploop1-objs := fmt_ploop1.o
> diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
> index 1da073c..23da9f5 100644
> --- a/drivers/block/ploop/dev.c
> +++ b/drivers/block/ploop/dev.c
> @@ -19,6 +19,7 @@
>  #include "ploop_events.h"
>  #include "freeblks.h"
>  #include "discard.h"
> +#include "push_backup.h"
>  
>  /* Structures and terms:
>   *
> @@ -3766,6 +3767,9 @@ static int ploop_stop(struct ploop_device * plo, struct 
> block_device *bdev)
>   return -EBUSY;
>   }
>  
> + clear_bit(PLOOP_S_PUSH_BACKUP, &plo->state);
> + ploop_pb_stop(plo->pbd);
> +
>   for (p = plo->disk->minors - 1; p > 0; p--)
>   invalidate_partition(plo->disk, p);
>   invalidate_partition(plo->disk, 0);
> @@ -3892,6 +3896,7 @@ static int ploop_clear(struct ploop_device * plo, 
> struct block_device * bdev)
>   }
>  
>   ploop_fb_fini(plo->fbd, 0);
> + ploop_pb_fini(plo->pbd);
>  
>   plo->maintenance_type = PLOOP_MNTN_OFF;
>   plo->bd_size = 0;
> @@ -4477,6 +4482,84 @@ static int ploop_getdevice_ioc(unsigned long arg)
>   return err;
>  }
>  
> +static int ploop_push_backup_init(struct ploop_device *plo, unsigned long 
> arg)
> +{
> + struct ploop_push_backup_init_ctl ctl;
> + struct ploop_pushbackup_desc *pbd = NULL;
> + int rc = 0;
> +
> + if (list_empty(&plo->map.delta_list))
> + return -ENOENT;
> +
> + if (plo->maintenance_type != PLOOP_MNTN_OFF)
> + return -EINVAL;
> +
> + BUG_ON(plo->pbd);
> +
> + if (copy_from_user(&ctl, (void*)arg, sizeof(ctl)))
> + return -EFAULT;
> +
> + pbd = ploop_pb_alloc(plo);
> + if (!pbd) {
> + rc = -ENOMEM;
> + goto pb_init_done;
> + }
> +
> + ploop_quiesce(plo);
> +
> + rc = ploop_pb_init(pbd, ctl.cbt_uuid, !ctl.cbt_mask_addr);
> + if (rc) {
> + ploop_relax(plo);
> + goto pb_init_done;
> + }
> +
> + plo->pbd = pbd;
> +
> + atomic_set(&plo->maintenance_cnt, 0);
> + plo->maintenance_type = PLOOP_MNTN_PUSH_BACKUP;
> + set_bit(PLOOP_S_PUSH_BACKUP, &plo->state);
> +
> + ploop_relax(plo);
> +
> + if (ctl.cbt_mask_addr)
> + rc = ploop_pb_copy_cbt_to_user(pbd, (char *)ctl.cbt_mask_addr);
> +pb_init_done:
> + if (rc)
> + ploop_pb_fini(pbd);
> + return rc;
> +}
> +
> +static int ploop_push_backup_stop(struct ploop_device *plo, unsigned long 
> arg)
> +{
> + struct ploop_pushbackup_desc *pbd = plo->pbd;
> + struct ploop_push_backup_stop_ctl ctl;
> +
> + if (plo->maintenance_type != PLOOP_MNTN_PUSH_BACKUP)
> + return -EINVAL;
> +
> + if (copy_from_user(&ctl, (void*)arg, sizeof(ctl)))
> + return -EFAULT;
> +
> + if (pbd && ploop_pb_check_uuid(pbd, ctl.cbt_uuid)) {
> + printk("ploop(%d): PUSH_BACKUP_STOP uuid mismatch\n",
> +plo->index);
> + return -EINVAL;
> + }
> +
> + if (!test_and_clear_bit(PLOOP_S_PUSH_BACKUP, &plo->state))
> + return -EINVAL;
> +
> + BUG_ON (!pbd);
> + ctl.status = ploop_pb_stop(pbd);
> +
> + ploop_quiesce(plo);
> + ploop_pb_fini(plo->pbd);
> + plo->maintenance_type = PLOOP_MNTN_OFF;
> + ploop_relax(plo);
> +
> + return 0;
> +}
> +
>  static int ploop_ioctl(struct block_device *bdev, fmode_t fmode, unsigned 
> int cmd,
>  unsigned long arg)
>  {
> @@ -4581,6 +4664,12 @@ static int ploop_ioctl(struct block_device *bdev, 
> fmode_t fmode, unsigned int cm
>   case PLOOP_IOC_MAX_DELTA_SIZE:
>   err = ploop_se

[Devel] [PATCH rh7 1/4] ploop: introduce pbd

2016-04-29 Thread Maxim Patlasov
The patch introduce push_backup descriptor ("pbd") and a few simple
functions to create and release it.

Userspace can govern it by new ioctls: PLOOP_IOC_PUSH_BACKUP_INIT and
PLOOP_IOC_PUSH_BACKUP_STOP.

Signed-off-by: Maxim Patlasov 
---
 drivers/block/ploop/Makefile  |2 
 drivers/block/ploop/dev.c |   89 
 drivers/block/ploop/push_backup.c |  271 +
 drivers/block/ploop/push_backup.h |8 +
 include/linux/ploop/ploop.h   |3 
 include/linux/ploop/ploop_if.h|   19 +++
 6 files changed, 391 insertions(+), 1 deletion(-)
 create mode 100644 drivers/block/ploop/push_backup.c
 create mode 100644 drivers/block/ploop/push_backup.h

diff --git a/drivers/block/ploop/Makefile b/drivers/block/ploop/Makefile
index e36a027..0fecf16 100644
--- a/drivers/block/ploop/Makefile
+++ b/drivers/block/ploop/Makefile
@@ -5,7 +5,7 @@ CFLAGS_io_direct.o = -I$(src)
 CFLAGS_ploop_events.o = -I$(src)
 
 obj-$(CONFIG_BLK_DEV_PLOOP)+= ploop.o
-ploop-objs := dev.o map.o io.o sysfs.o tracker.o freeblks.o ploop_events.o 
discard.o
+ploop-objs := dev.o map.o io.o sysfs.o tracker.o freeblks.o ploop_events.o 
discard.o push_backup.o
 
 obj-$(CONFIG_BLK_DEV_PLOOP)+= pfmt_ploop1.o
 pfmt_ploop1-objs := fmt_ploop1.o
diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 1da073c..23da9f5 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -19,6 +19,7 @@
 #include "ploop_events.h"
 #include "freeblks.h"
 #include "discard.h"
+#include "push_backup.h"
 
 /* Structures and terms:
  *
@@ -3766,6 +3767,9 @@ static int ploop_stop(struct ploop_device * plo, struct 
block_device *bdev)
return -EBUSY;
}
 
+   clear_bit(PLOOP_S_PUSH_BACKUP, &plo->state);
+   ploop_pb_stop(plo->pbd);
+
for (p = plo->disk->minors - 1; p > 0; p--)
invalidate_partition(plo->disk, p);
invalidate_partition(plo->disk, 0);
@@ -3892,6 +3896,7 @@ static int ploop_clear(struct ploop_device * plo, struct 
block_device * bdev)
}
 
ploop_fb_fini(plo->fbd, 0);
+   ploop_pb_fini(plo->pbd);
 
plo->maintenance_type = PLOOP_MNTN_OFF;
plo->bd_size = 0;
@@ -4477,6 +4482,84 @@ static int ploop_getdevice_ioc(unsigned long arg)
return err;
 }
 
+static int ploop_push_backup_init(struct ploop_device *plo, unsigned long arg)
+{
+   struct ploop_push_backup_init_ctl ctl;
+   struct ploop_pushbackup_desc *pbd = NULL;
+   int rc = 0;
+
+   if (list_empty(&plo->map.delta_list))
+   return -ENOENT;
+
+   if (plo->maintenance_type != PLOOP_MNTN_OFF)
+   return -EINVAL;
+
+   BUG_ON(plo->pbd);
+
+   if (copy_from_user(&ctl, (void*)arg, sizeof(ctl)))
+   return -EFAULT;
+
+   pbd = ploop_pb_alloc(plo);
+   if (!pbd) {
+   rc = -ENOMEM;
+   goto pb_init_done;
+   }
+
+   ploop_quiesce(plo);
+
+   rc = ploop_pb_init(pbd, ctl.cbt_uuid, !ctl.cbt_mask_addr);
+   if (rc) {
+   ploop_relax(plo);
+   goto pb_init_done;
+   }
+
+   plo->pbd = pbd;
+
+   atomic_set(&plo->maintenance_cnt, 0);
+   plo->maintenance_type = PLOOP_MNTN_PUSH_BACKUP;
+   set_bit(PLOOP_S_PUSH_BACKUP, &plo->state);
+
+   ploop_relax(plo);
+
+   if (ctl.cbt_mask_addr)
+   rc = ploop_pb_copy_cbt_to_user(pbd, (char *)ctl.cbt_mask_addr);
+pb_init_done:
+   if (rc)
+   ploop_pb_fini(pbd);
+   return rc;
+}
+
+static int ploop_push_backup_stop(struct ploop_device *plo, unsigned long arg)
+{
+   struct ploop_pushbackup_desc *pbd = plo->pbd;
+   struct ploop_push_backup_stop_ctl ctl;
+
+   if (plo->maintenance_type != PLOOP_MNTN_PUSH_BACKUP)
+   return -EINVAL;
+
+   if (copy_from_user(&ctl, (void*)arg, sizeof(ctl)))
+   return -EFAULT;
+
+   if (pbd && ploop_pb_check_uuid(pbd, ctl.cbt_uuid)) {
+   printk("ploop(%d): PUSH_BACKUP_STOP uuid mismatch\n",
+  plo->index);
+   return -EINVAL;
+   }
+
+   if (!test_and_clear_bit(PLOOP_S_PUSH_BACKUP, &plo->state))
+   return -EINVAL;
+
+   BUG_ON (!pbd);
+   ctl.status = ploop_pb_stop(pbd);
+
+   ploop_quiesce(plo);
+   ploop_pb_fini(plo->pbd);
+   plo->maintenance_type = PLOOP_MNTN_OFF;
+   ploop_relax(plo);
+
+   return 0;
+}
+
 static int ploop_ioctl(struct block_device *bdev, fmode_t fmode, unsigned int 
cmd,
   unsigned long arg)
 {
@@ -4581,6 +4664,12 @@ static int ploop_ioctl(struct block_device *bdev, 
fmode_t fmode, unsigned int cm
case PLOOP_IOC_MAX_DELTA_SIZE:
err = ploop_set_max_delta_size(plo, arg);
break;
+   case PLOOP_IOC_PUSH_BACKUP_INIT:
+   err = ploop_push_backup_init(plo, arg);
+   break;
+   case PLOOP_IOC_PUSH_BACKUP_STOP:
+   er