[Devel] [PATCH rh7 v2] ploop: add PLOOP_IOC_FREEZE and PLOOP_IOC_THAW ioctls

Vladimir Davydov vdavydov at virtuozzo.com
Wed Jul 13 09:26:40 PDT 2016


From: Maxim Patlasov <mpatlasov at virtuozzo.com>

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 <mpatlasov at virtuozzo.com>
Signed-off-by: Vladimir Davydov <vdavydov at virtuozzo.com>
Cc: Pavel Borzenkov <pborzenkov at virtuozzo.com>
---
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



More information about the Devel mailing list