From: Maxim Patlasov <[email protected]>

The ioctls simply freeze and thaw ploop bdev.

If no fs is mounted over ploop bdev being frozen, then the freeze ioctl
just increments bd_fsfreeze_count, which prevents the ploop from being
mounted until it is thawed.

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

Caveats:

 1) No nested freeze: many PLOOP_IOC_FREEZE ioctls have the same effect as one.
 2) The same for thaw.

[vdavydov@: allow to freeze unmounted ploop]
Signed-off-by: Maxim Patlasov <[email protected]>
Signed-off-by: Vladimir Davydov <[email protected]>
Cc: Pavel Borzenkov <[email protected]>
---
Changes in v2:
 - avoid patching generic code

 drivers/block/ploop/dev.c      | 39 +++++++++++++++++++++++++++++++++++++++
 include/linux/ploop/ploop.h    |  2 ++
 include/linux/ploop/ploop_if.h |  6 ++++++
 3 files changed, 47 insertions(+)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index e5f010b9aeba..d52975eaaa36 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -4815,6 +4815,39 @@ static int ploop_push_backup_stop(struct ploop_device 
*plo, unsigned long arg)
        return copy_to_user((void*)arg, &ctl, sizeof(ctl));
 }
 
+static int ploop_freeze(struct ploop_device *plo, struct block_device *bdev)
+{
+       struct super_block *sb = plo->sb;
+
+       if (test_bit(PLOOP_S_FROZEN, &plo->state))
+               return 0;
+
+       sb = freeze_bdev(bdev);
+       if (sb && IS_ERR(sb))
+               return PTR_ERR(sb);
+
+       plo->sb = sb;
+       set_bit(PLOOP_S_FROZEN, &plo->state);
+       return 0;
+}
+
+static int ploop_thaw(struct ploop_device *plo, struct block_device *bdev)
+{
+       struct super_block *sb = plo->sb;
+       int err;
+
+       if (!test_bit(PLOOP_S_FROZEN, &plo->state))
+               return 0;
+
+       err = thaw_bdev(bdev, sb);
+       if (!err) {
+               plo->sb = NULL;
+               clear_bit(PLOOP_S_FROZEN, &plo->state);
+       }
+
+       return err;
+}
+
 static int ploop_ioctl(struct block_device *bdev, fmode_t fmode, unsigned int 
cmd,
                       unsigned long arg)
 {
@@ -4928,6 +4961,12 @@ static int ploop_ioctl(struct block_device *bdev, 
fmode_t fmode, unsigned int cm
        case PLOOP_IOC_PUSH_BACKUP_STOP:
                err = ploop_push_backup_stop(plo, arg);
                break;
+       case PLOOP_IOC_FREEZE:
+               err = ploop_freeze(plo, bdev);
+               break;
+       case PLOOP_IOC_THAW:
+               err = ploop_thaw(plo, bdev);
+               break;
        default:
                err = -EINVAL;
        }
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index deee8a78cc96..7864edf17f19 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -61,6 +61,7 @@ enum {
                                   (for minor mgmt only) */
        PLOOP_S_ONCE,           /* An event (e.g. printk once) happened */
        PLOOP_S_PUSH_BACKUP,    /* Push_backup is in progress */
+       PLOOP_S_FROZEN          /* Frozen PLOOP_IOC_FREEZE */
 };
 
 struct ploop_snapdata
@@ -409,6 +410,7 @@ struct ploop_device
        struct block_device     *bdev;
        struct request_queue    *queue;
        struct task_struct      *thread;
+       struct super_block      *sb;
        struct rb_node          link;
 
        /* someone who wants to quiesce state-machine waits
diff --git a/include/linux/ploop/ploop_if.h b/include/linux/ploop/ploop_if.h
index a098ca9d0ef0..302ace984a5a 100644
--- a/include/linux/ploop/ploop_if.h
+++ b/include/linux/ploop/ploop_if.h
@@ -352,6 +352,12 @@ struct ploop_track_extent
 /* Stop push backup */
 #define PLOOP_IOC_PUSH_BACKUP_STOP _IOR(PLOOPCTLTYPE, 31, struct 
ploop_push_backup_stop_ctl)
 
+/* Freeze FS mounted over ploop */
+#define PLOOP_IOC_FREEZE       _IO(PLOOPCTLTYPE, 32)
+
+/* Unfreeze FS mounted over ploop */
+#define PLOOP_IOC_THAW         _IO(PLOOPCTLTYPE, 33)
+
 /* Events exposed via /sys/block/ploopN/pstate/event */
 #define PLOOP_EVENT_ABORTED    1
 #define PLOOP_EVENT_STOPPED    2
-- 
2.1.4

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to