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
