mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-15 05:11:32 +00:00
Merge branch 'work.thaw' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs thaw updates from Al Viro: "An ancient series that has fallen through the cracks in the previous cycle" * 'work.thaw' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: buffer.c: call thaw_super during emergency thaw vfs: factor sb iteration out of do_emergency_remount
This commit is contained in:
commit
7214dd4ea9
25
fs/buffer.c
25
fs/buffer.c
@ -494,35 +494,12 @@ repeat:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void do_thaw_one(struct super_block *sb, void *unused)
|
||||
void emergency_thaw_bdev(struct super_block *sb)
|
||||
{
|
||||
while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb))
|
||||
printk(KERN_WARNING "Emergency Thaw on %pg\n", sb->s_bdev);
|
||||
}
|
||||
|
||||
static void do_thaw_all(struct work_struct *work)
|
||||
{
|
||||
iterate_supers(do_thaw_one, NULL);
|
||||
kfree(work);
|
||||
printk(KERN_WARNING "Emergency Thaw complete\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* emergency_thaw_all -- forcibly thaw every frozen filesystem
|
||||
*
|
||||
* Used for emergency unfreeze of all filesystems via SysRq
|
||||
*/
|
||||
void emergency_thaw_all(void)
|
||||
{
|
||||
struct work_struct *work;
|
||||
|
||||
work = kmalloc(sizeof(*work), GFP_ATOMIC);
|
||||
if (work) {
|
||||
INIT_WORK(work, do_thaw_all);
|
||||
schedule_work(work);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers
|
||||
* @mapping: the mapping which wants those buffers written
|
||||
|
105
fs/super.c
105
fs/super.c
@ -37,6 +37,7 @@
|
||||
#include <linux/user_namespace.h>
|
||||
#include "internal.h"
|
||||
|
||||
static int thaw_super_locked(struct super_block *sb);
|
||||
|
||||
static LIST_HEAD(super_blocks);
|
||||
static DEFINE_SPINLOCK(sb_lock);
|
||||
@ -574,6 +575,28 @@ void drop_super_exclusive(struct super_block *sb)
|
||||
}
|
||||
EXPORT_SYMBOL(drop_super_exclusive);
|
||||
|
||||
static void __iterate_supers(void (*f)(struct super_block *))
|
||||
{
|
||||
struct super_block *sb, *p = NULL;
|
||||
|
||||
spin_lock(&sb_lock);
|
||||
list_for_each_entry(sb, &super_blocks, s_list) {
|
||||
if (hlist_unhashed(&sb->s_instances))
|
||||
continue;
|
||||
sb->s_count++;
|
||||
spin_unlock(&sb_lock);
|
||||
|
||||
f(sb);
|
||||
|
||||
spin_lock(&sb_lock);
|
||||
if (p)
|
||||
__put_super(p);
|
||||
p = sb;
|
||||
}
|
||||
if (p)
|
||||
__put_super(p);
|
||||
spin_unlock(&sb_lock);
|
||||
}
|
||||
/**
|
||||
* iterate_supers - call function for all active superblocks
|
||||
* @f: function to call
|
||||
@ -881,33 +904,22 @@ cancel_readonly:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void do_emergency_remount_callback(struct super_block *sb)
|
||||
{
|
||||
down_write(&sb->s_umount);
|
||||
if (sb->s_root && sb->s_bdev && (sb->s_flags & SB_BORN) &&
|
||||
!sb_rdonly(sb)) {
|
||||
/*
|
||||
* What lock protects sb->s_flags??
|
||||
*/
|
||||
do_remount_sb(sb, SB_RDONLY, NULL, 1);
|
||||
}
|
||||
up_write(&sb->s_umount);
|
||||
}
|
||||
|
||||
static void do_emergency_remount(struct work_struct *work)
|
||||
{
|
||||
struct super_block *sb, *p = NULL;
|
||||
|
||||
spin_lock(&sb_lock);
|
||||
list_for_each_entry(sb, &super_blocks, s_list) {
|
||||
if (hlist_unhashed(&sb->s_instances))
|
||||
continue;
|
||||
sb->s_count++;
|
||||
spin_unlock(&sb_lock);
|
||||
down_write(&sb->s_umount);
|
||||
if (sb->s_root && sb->s_bdev && (sb->s_flags & SB_BORN) &&
|
||||
!sb_rdonly(sb)) {
|
||||
/*
|
||||
* What lock protects sb->s_flags??
|
||||
*/
|
||||
do_remount_sb(sb, SB_RDONLY, NULL, 1);
|
||||
}
|
||||
up_write(&sb->s_umount);
|
||||
spin_lock(&sb_lock);
|
||||
if (p)
|
||||
__put_super(p);
|
||||
p = sb;
|
||||
}
|
||||
if (p)
|
||||
__put_super(p);
|
||||
spin_unlock(&sb_lock);
|
||||
__iterate_supers(do_emergency_remount_callback);
|
||||
kfree(work);
|
||||
printk("Emergency Remount complete\n");
|
||||
}
|
||||
@ -923,6 +935,40 @@ void emergency_remount(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_thaw_all_callback(struct super_block *sb)
|
||||
{
|
||||
down_write(&sb->s_umount);
|
||||
if (sb->s_root && sb->s_flags & MS_BORN) {
|
||||
emergency_thaw_bdev(sb);
|
||||
thaw_super_locked(sb);
|
||||
} else {
|
||||
up_write(&sb->s_umount);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_thaw_all(struct work_struct *work)
|
||||
{
|
||||
__iterate_supers(do_thaw_all_callback);
|
||||
kfree(work);
|
||||
printk(KERN_WARNING "Emergency Thaw complete\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* emergency_thaw_all -- forcibly thaw every frozen filesystem
|
||||
*
|
||||
* Used for emergency unfreeze of all filesystems via SysRq
|
||||
*/
|
||||
void emergency_thaw_all(void)
|
||||
{
|
||||
struct work_struct *work;
|
||||
|
||||
work = kmalloc(sizeof(*work), GFP_ATOMIC);
|
||||
if (work) {
|
||||
INIT_WORK(work, do_thaw_all);
|
||||
schedule_work(work);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unnamed block devices are dummy devices used by virtual
|
||||
* filesystems which don't use real block-devices. -- jrs
|
||||
@ -1492,11 +1538,10 @@ EXPORT_SYMBOL(freeze_super);
|
||||
*
|
||||
* Unlocks the filesystem and marks it writeable again after freeze_super().
|
||||
*/
|
||||
int thaw_super(struct super_block *sb)
|
||||
static int thaw_super_locked(struct super_block *sb)
|
||||
{
|
||||
int error;
|
||||
|
||||
down_write(&sb->s_umount);
|
||||
if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
|
||||
up_write(&sb->s_umount);
|
||||
return -EINVAL;
|
||||
@ -1527,4 +1572,10 @@ out:
|
||||
deactivate_locked_super(sb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thaw_super(struct super_block *sb)
|
||||
{
|
||||
down_write(&sb->s_umount);
|
||||
return thaw_super_locked(sb);
|
||||
}
|
||||
EXPORT_SYMBOL(thaw_super);
|
||||
|
@ -2445,6 +2445,7 @@ extern int sync_blockdev(struct block_device *bdev);
|
||||
extern void kill_bdev(struct block_device *);
|
||||
extern struct super_block *freeze_bdev(struct block_device *);
|
||||
extern void emergency_thaw_all(void);
|
||||
extern void emergency_thaw_bdev(struct super_block *sb);
|
||||
extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
|
||||
extern int fsync_bdev(struct block_device *);
|
||||
|
||||
@ -2470,6 +2471,11 @@ static inline int thaw_bdev(struct block_device *bdev, struct super_block *sb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int emergency_thaw_bdev(struct super_block *sb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void iterate_bdevs(void (*f)(struct block_device *, void *), void *arg)
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user