Vova,

Let's keep flies and cutlets separately. It seems we can easily satisfy push-backup needs by implementing freeze/thaw ploop ioctls without tackling generic code at all, see a patch in attachment (unless I missed something obvious). And apart from these ploop/push-backup stuff, if you think your changes for freeze_bdev() and thaw_bdev() are useful, send them upstream, so we'll back-port them later, when they are accepted upstream (unless I missed some scenario for which those changes matter for us). In the other words, I think we have to keep our vz7 generic code base closer to ms, unless we have good reason to deviate.


Thanks,

Maxim


On 07/12/2016 03:04 AM, Vladimir Davydov wrote:
It's possible to freeze a bdev which is not mounted. In this case
freeze_bdev() only increments bd_fsfrozen_count in order to prevent the
bdev from being mounted and does nothing else. A second freeze attempt
on the same device is supposed to increment bd_fsfrozen_count again, but
it results in NULL ptr dereference, because freeze_bdev() doesn't check
the return value of get_super(). Fix that.

Signed-off-by: Vladimir Davydov <vdavy...@virtuozzo.com>
---
  fs/block_dev.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 4575c62d8b0b..325ee7161fbf 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -227,7 +227,8 @@ struct super_block *freeze_bdev(struct block_device *bdev)
                 * thaw_bdev drops it.
                 */
                sb = get_super(bdev);
-               drop_super(sb);
+               if (sb)
+                       drop_super(sb);
                mutex_unlock(&bdev->bd_fsfreeze_mutex);
                return sb;
        }

The ioctls simply freeze and thaw ploop bdev.

Caveats:

1) If no fs mounted, the ioctls have no effect.
2) No nested freeze: many PLOOP_IOC_FREEZE ioctls have the same effect as one.
3) The same for thaw.

Signed-off-by: Maxim Patlasov <mpatla...@virtuozzo.com>
---
 drivers/block/ploop/dev.c      |   38 ++++++++++++++++++++++++++++++++++++++
 include/linux/ploop/ploop.h    |    1 +
 include/linux/ploop/ploop_if.h |    6 ++++++
 3 files changed, 45 insertions(+)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 6d449b7..e583d10 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -4892,6 +4892,38 @@ 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 (sb)
+		return 0;
+
+	sb = freeze_bdev(bdev);
+	if (sb && IS_ERR(sb))
+		return PTR_ERR(sb);
+	if (!sb)
+		thaw_bdev(bdev, sb);
+
+	plo->sb = sb;
+	return 0;
+}
+
+static int ploop_thaw(struct ploop_device *plo, struct block_device *bdev)
+{
+	struct super_block *sb = plo->sb;
+	int err;
+
+	if (!sb)
+		return 0;
+
+	err = thaw_bdev(bdev, sb);
+	if (!err)
+		plo->sb = NULL;
+
+	return err;
+}
+
 static int ploop_ioctl(struct block_device *bdev, fmode_t fmode, unsigned int cmd,
 		       unsigned long arg)
 {
@@ -5005,6 +5037,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 859fe51..e60ada4 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -414,6 +414,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 a098ca9..302ace9 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
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to