From: Darrick J. Wong <djwong@xxxxxxxxxx> Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/super.c | 33 +++++++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/fs/super.c b/fs/super.c index 01891f9e6d5e..46abd21f94ac 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1762,6 +1762,24 @@ int freeze_super(struct super_block *sb) } EXPORT_SYMBOL(freeze_super); +/** + * freeze_super_excl - lock the filesystem exclusively and force it into a + * consistent state. + * @sb: the super to lock + * @cookie: magic cookie to associate with this freeze so that only the caller + * can thaw the filesystem + * + * Syncs the super to make sure the filesystem is consistent and calls the fs's + * freeze_fs. Subsequent calls to this without first thawing the fs will + * return -EBUSY. The filesystem must not already be frozen, and can only be + * thawed by passing the same cookie to thaw_super_excl. + */ +int freeze_super_excl(struct super_block *sb, unsigned long cookie) +{ + return __freeze_super(sb, cookie); +} +EXPORT_SYMBOL(freeze_super_excl); + static int thaw_super_locked(struct super_block *sb, unsigned long cookie) { int error; @@ -1813,6 +1831,21 @@ int thaw_super(struct super_block *sb) } EXPORT_SYMBOL(thaw_super); +/** + * thaw_super_excl -- unfreeze filesystem + * @sb: the super to thaw + * @cookie: magic cookie passed to freeze_super_excl + * + * Releases an exclusive freeze on a filesystem and marks it writeable again + * after freeze_super(). + */ +int thaw_super_excl(struct super_block *sb, unsigned long cookie) +{ + down_write(&sb->s_umount); + return thaw_super_locked(sb, cookie); +} +EXPORT_SYMBOL(thaw_super_excl); + /* * Create workqueue for deferred direct IO completions. We allocate the * workqueue when it's first needed. This avoids creating workqueue for diff --git a/include/linux/fs.h b/include/linux/fs.h index 800772361b1e..3a65bcc45f67 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2272,6 +2272,8 @@ extern int user_statfs(const char __user *, struct kstatfs *); extern int fd_statfs(int, struct kstatfs *); extern int freeze_super(struct super_block *super); extern int thaw_super(struct super_block *super); +extern int freeze_super_excl(struct super_block *super, unsigned long cookie); +extern int thaw_super_excl(struct super_block *super, unsigned long cookie); extern __printf(2, 3) int super_setup_bdi_name(struct super_block *sb, char *fmt, ...); extern int super_setup_bdi(struct super_block *sb);