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;
|
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))
|
while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb))
|
||||||
printk(KERN_WARNING "Emergency Thaw on %pg\n", sb->s_bdev);
|
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
|
* sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers
|
||||||
* @mapping: the mapping which wants those buffers written
|
* @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 <linux/user_namespace.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
static int thaw_super_locked(struct super_block *sb);
|
||||||
|
|
||||||
static LIST_HEAD(super_blocks);
|
static LIST_HEAD(super_blocks);
|
||||||
static DEFINE_SPINLOCK(sb_lock);
|
static DEFINE_SPINLOCK(sb_lock);
|
||||||
@ -574,6 +575,28 @@ void drop_super_exclusive(struct super_block *sb)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drop_super_exclusive);
|
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
|
* iterate_supers - call function for all active superblocks
|
||||||
* @f: function to call
|
* @f: function to call
|
||||||
@ -881,33 +904,22 @@ cancel_readonly:
|
|||||||
return retval;
|
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)
|
static void do_emergency_remount(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct super_block *sb, *p = NULL;
|
__iterate_supers(do_emergency_remount_callback);
|
||||||
|
|
||||||
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);
|
|
||||||
kfree(work);
|
kfree(work);
|
||||||
printk("Emergency Remount complete\n");
|
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
|
* Unnamed block devices are dummy devices used by virtual
|
||||||
* filesystems which don't use real block-devices. -- jrs
|
* 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().
|
* 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;
|
int error;
|
||||||
|
|
||||||
down_write(&sb->s_umount);
|
|
||||||
if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
|
if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
|
||||||
up_write(&sb->s_umount);
|
up_write(&sb->s_umount);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1527,4 +1572,10 @@ out:
|
|||||||
deactivate_locked_super(sb);
|
deactivate_locked_super(sb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int thaw_super(struct super_block *sb)
|
||||||
|
{
|
||||||
|
down_write(&sb->s_umount);
|
||||||
|
return thaw_super_locked(sb);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(thaw_super);
|
EXPORT_SYMBOL(thaw_super);
|
||||||
|
@ -2445,6 +2445,7 @@ extern int sync_blockdev(struct block_device *bdev);
|
|||||||
extern void kill_bdev(struct block_device *);
|
extern void kill_bdev(struct block_device *);
|
||||||
extern struct super_block *freeze_bdev(struct block_device *);
|
extern struct super_block *freeze_bdev(struct block_device *);
|
||||||
extern void emergency_thaw_all(void);
|
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 thaw_bdev(struct block_device *bdev, struct super_block *sb);
|
||||||
extern int fsync_bdev(struct block_device *);
|
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;
|
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)
|
static inline void iterate_bdevs(void (*f)(struct block_device *, void *), void *arg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user