fs: distinguish between user initiated freeze and kernel initiated freeze
Userspace can freeze a filesystem using the FIFREEZE ioctl or by
suspending the block device; this state persists until userspace thaws
the filesystem with the FITHAW ioctl or resuming the block device.
Since commit 18e9e5104f
("Introduce freeze_super and thaw_super for
the fsfreeze ioctl") we only allow the first freeze command to succeed.
The kernel may decide that it is necessary to freeze a filesystem for
its own internal purposes, such as suspends in progress, filesystem fsck
activities, or quiescing a device prior to removal. Userspace thaw
commands must never break a kernel freeze, and kernel thaw commands
shouldn't undo userspace's freeze command.
Introduce a couple of freeze holder flags and wire it into the
sb_writers state. One kernel and one userspace freeze are allowed to
coexist at the same time; the filesystem will not thaw until both are
lifted.
I wonder if the f2fs/gfs2 code should be using a kernel freeze here, but
for now we'll use FREEZE_HOLDER_USERSPACE to preserve existing
behaviors.
Cc: mcgrof@kernel.org
Cc: jack@suse.cz
Cc: hch@infradead.org
Cc: ruansy.fnst@fujitsu.com
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
fdf0eaf114
commit
880b957785
|
@ -260,9 +260,11 @@ filesystem. The following members are defined:
|
||||||
void (*evict_inode) (struct inode *);
|
void (*evict_inode) (struct inode *);
|
||||||
void (*put_super) (struct super_block *);
|
void (*put_super) (struct super_block *);
|
||||||
int (*sync_fs)(struct super_block *sb, int wait);
|
int (*sync_fs)(struct super_block *sb, int wait);
|
||||||
int (*freeze_super) (struct super_block *);
|
int (*freeze_super) (struct super_block *sb,
|
||||||
|
enum freeze_holder who);
|
||||||
int (*freeze_fs) (struct super_block *);
|
int (*freeze_fs) (struct super_block *);
|
||||||
int (*thaw_super) (struct super_block *);
|
int (*thaw_super) (struct super_block *sb,
|
||||||
|
enum freeze_wholder who);
|
||||||
int (*unfreeze_fs) (struct super_block *);
|
int (*unfreeze_fs) (struct super_block *);
|
||||||
int (*statfs) (struct dentry *, struct kstatfs *);
|
int (*statfs) (struct dentry *, struct kstatfs *);
|
||||||
int (*remount_fs) (struct super_block *, int *, char *);
|
int (*remount_fs) (struct super_block *, int *, char *);
|
||||||
|
|
|
@ -248,9 +248,9 @@ int freeze_bdev(struct block_device *bdev)
|
||||||
if (!sb)
|
if (!sb)
|
||||||
goto sync;
|
goto sync;
|
||||||
if (sb->s_op->freeze_super)
|
if (sb->s_op->freeze_super)
|
||||||
error = sb->s_op->freeze_super(sb);
|
error = sb->s_op->freeze_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
else
|
else
|
||||||
error = freeze_super(sb);
|
error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
deactivate_super(sb);
|
deactivate_super(sb);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -291,9 +291,9 @@ int thaw_bdev(struct block_device *bdev)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (sb->s_op->thaw_super)
|
if (sb->s_op->thaw_super)
|
||||||
error = sb->s_op->thaw_super(sb);
|
error = sb->s_op->thaw_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
else
|
else
|
||||||
error = thaw_super(sb);
|
error = thaw_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
if (error)
|
if (error)
|
||||||
bdev->bd_fsfreeze_count++;
|
bdev->bd_fsfreeze_count++;
|
||||||
else
|
else
|
||||||
|
|
|
@ -2181,12 +2181,14 @@ out_drop_write:
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = freeze_super(sbi->sb);
|
err = freeze_super(sbi->sb, FREEZE_HOLDER_USERSPACE);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (f2fs_readonly(sbi->sb)) {
|
if (f2fs_readonly(sbi->sb)) {
|
||||||
thaw_super(sbi->sb);
|
err = thaw_super(sbi->sb, FREEZE_HOLDER_USERSPACE);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2240,6 +2242,6 @@ recover_out:
|
||||||
out_err:
|
out_err:
|
||||||
f2fs_up_write(&sbi->cp_global_sem);
|
f2fs_up_write(&sbi->cp_global_sem);
|
||||||
f2fs_up_write(&sbi->gc_lock);
|
f2fs_up_write(&sbi->gc_lock);
|
||||||
thaw_super(sbi->sb);
|
thaw_super(sbi->sb, FREEZE_HOLDER_USERSPACE);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -689,7 +689,7 @@ static int gfs2_freeze_locally(struct gfs2_sbd *sdp)
|
||||||
struct super_block *sb = sdp->sd_vfs;
|
struct super_block *sb = sdp->sd_vfs;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = freeze_super(sb);
|
error = freeze_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -697,7 +697,9 @@ static int gfs2_freeze_locally(struct gfs2_sbd *sdp)
|
||||||
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
|
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE |
|
||||||
GFS2_LFC_FREEZE_GO_SYNC);
|
GFS2_LFC_FREEZE_GO_SYNC);
|
||||||
if (gfs2_withdrawn(sdp)) {
|
if (gfs2_withdrawn(sdp)) {
|
||||||
thaw_super(sb);
|
error = thaw_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -712,7 +714,7 @@ static int gfs2_do_thaw(struct gfs2_sbd *sdp)
|
||||||
error = gfs2_freeze_lock_shared(sdp);
|
error = gfs2_freeze_lock_shared(sdp);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail;
|
goto fail;
|
||||||
error = thaw_super(sb);
|
error = thaw_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
if (!error)
|
if (!error)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -761,7 +763,7 @@ out:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int gfs2_freeze_super(struct super_block *sb)
|
static int gfs2_freeze_super(struct super_block *sb, enum freeze_holder who)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = sb->s_fs_info;
|
struct gfs2_sbd *sdp = sb->s_fs_info;
|
||||||
int error;
|
int error;
|
||||||
|
@ -816,7 +818,7 @@ out:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int gfs2_thaw_super(struct super_block *sb)
|
static int gfs2_thaw_super(struct super_block *sb, enum freeze_holder who)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = sb->s_fs_info;
|
struct gfs2_sbd *sdp = sb->s_fs_info;
|
||||||
int error;
|
int error;
|
||||||
|
|
|
@ -168,10 +168,10 @@ static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
|
||||||
|
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 0:
|
case 0:
|
||||||
error = thaw_super(sdp->sd_vfs);
|
error = thaw_super(sdp->sd_vfs, FREEZE_HOLDER_USERSPACE);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
error = freeze_super(sdp->sd_vfs);
|
error = freeze_super(sdp->sd_vfs, FREEZE_HOLDER_USERSPACE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -396,8 +396,8 @@ static int ioctl_fsfreeze(struct file *filp)
|
||||||
|
|
||||||
/* Freeze */
|
/* Freeze */
|
||||||
if (sb->s_op->freeze_super)
|
if (sb->s_op->freeze_super)
|
||||||
return sb->s_op->freeze_super(sb);
|
return sb->s_op->freeze_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
return freeze_super(sb);
|
return freeze_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ioctl_fsthaw(struct file *filp)
|
static int ioctl_fsthaw(struct file *filp)
|
||||||
|
@ -409,8 +409,8 @@ static int ioctl_fsthaw(struct file *filp)
|
||||||
|
|
||||||
/* Thaw */
|
/* Thaw */
|
||||||
if (sb->s_op->thaw_super)
|
if (sb->s_op->thaw_super)
|
||||||
return sb->s_op->thaw_super(sb);
|
return sb->s_op->thaw_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
return thaw_super(sb);
|
return thaw_super(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ioctl_file_dedupe_range(struct file *file,
|
static int ioctl_file_dedupe_range(struct file *file,
|
||||||
|
|
79
fs/super.c
79
fs/super.c
|
@ -39,7 +39,7 @@
|
||||||
#include <uapi/linux/mount.h>
|
#include <uapi/linux/mount.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static int thaw_super_locked(struct super_block *sb);
|
static int thaw_super_locked(struct super_block *sb, enum freeze_holder who);
|
||||||
|
|
||||||
static LIST_HEAD(super_blocks);
|
static LIST_HEAD(super_blocks);
|
||||||
static DEFINE_SPINLOCK(sb_lock);
|
static DEFINE_SPINLOCK(sb_lock);
|
||||||
|
@ -1030,7 +1030,7 @@ static void do_thaw_all_callback(struct super_block *sb)
|
||||||
down_write(&sb->s_umount);
|
down_write(&sb->s_umount);
|
||||||
if (sb->s_root && sb->s_flags & SB_BORN) {
|
if (sb->s_root && sb->s_flags & SB_BORN) {
|
||||||
emergency_thaw_bdev(sb);
|
emergency_thaw_bdev(sb);
|
||||||
thaw_super_locked(sb);
|
thaw_super_locked(sb, FREEZE_HOLDER_USERSPACE);
|
||||||
} else {
|
} else {
|
||||||
up_write(&sb->s_umount);
|
up_write(&sb->s_umount);
|
||||||
}
|
}
|
||||||
|
@ -1647,11 +1647,22 @@ static void sb_freeze_unlock(struct super_block *sb, int level)
|
||||||
/**
|
/**
|
||||||
* freeze_super - lock the filesystem and force it into a consistent state
|
* freeze_super - lock the filesystem and force it into a consistent state
|
||||||
* @sb: the super to lock
|
* @sb: the super to lock
|
||||||
|
* @who: context that wants to freeze
|
||||||
*
|
*
|
||||||
* Syncs the super to make sure the filesystem is consistent and calls the fs's
|
* 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
|
* freeze_fs. Subsequent calls to this without first thawing the fs may return
|
||||||
* -EBUSY.
|
* -EBUSY.
|
||||||
*
|
*
|
||||||
|
* @who should be:
|
||||||
|
* * %FREEZE_HOLDER_USERSPACE if userspace wants to freeze the fs;
|
||||||
|
* * %FREEZE_HOLDER_KERNEL if the kernel wants to freeze the fs.
|
||||||
|
*
|
||||||
|
* The @who argument distinguishes between the kernel and userspace trying to
|
||||||
|
* freeze the filesystem. Although there cannot be multiple kernel freezes or
|
||||||
|
* multiple userspace freezes in effect at any given time, the kernel and
|
||||||
|
* userspace can both hold a filesystem frozen. The filesystem remains frozen
|
||||||
|
* until there are no kernel or userspace freezes in effect.
|
||||||
|
*
|
||||||
* During this function, sb->s_writers.frozen goes through these values:
|
* During this function, sb->s_writers.frozen goes through these values:
|
||||||
*
|
*
|
||||||
* SB_UNFROZEN: File system is normal, all writes progress as usual.
|
* SB_UNFROZEN: File system is normal, all writes progress as usual.
|
||||||
|
@ -1677,12 +1688,30 @@ static void sb_freeze_unlock(struct super_block *sb, int level)
|
||||||
*
|
*
|
||||||
* sb->s_writers.frozen is protected by sb->s_umount.
|
* sb->s_writers.frozen is protected by sb->s_umount.
|
||||||
*/
|
*/
|
||||||
int freeze_super(struct super_block *sb)
|
int freeze_super(struct super_block *sb, enum freeze_holder who)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
atomic_inc(&sb->s_active);
|
atomic_inc(&sb->s_active);
|
||||||
down_write(&sb->s_umount);
|
down_write(&sb->s_umount);
|
||||||
|
|
||||||
|
if (sb->s_writers.frozen == SB_FREEZE_COMPLETE) {
|
||||||
|
if (sb->s_writers.freeze_holders & who) {
|
||||||
|
deactivate_locked_super(sb);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN_ON(sb->s_writers.freeze_holders == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Someone else already holds this type of freeze; share the
|
||||||
|
* freeze and assign the active ref to the freeze.
|
||||||
|
*/
|
||||||
|
sb->s_writers.freeze_holders |= who;
|
||||||
|
up_write(&sb->s_umount);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (sb->s_writers.frozen != SB_UNFROZEN) {
|
if (sb->s_writers.frozen != SB_UNFROZEN) {
|
||||||
deactivate_locked_super(sb);
|
deactivate_locked_super(sb);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
@ -1695,6 +1724,7 @@ int freeze_super(struct super_block *sb)
|
||||||
|
|
||||||
if (sb_rdonly(sb)) {
|
if (sb_rdonly(sb)) {
|
||||||
/* Nothing to do really... */
|
/* Nothing to do really... */
|
||||||
|
sb->s_writers.freeze_holders |= who;
|
||||||
sb->s_writers.frozen = SB_FREEZE_COMPLETE;
|
sb->s_writers.frozen = SB_FREEZE_COMPLETE;
|
||||||
up_write(&sb->s_umount);
|
up_write(&sb->s_umount);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1738,6 +1768,7 @@ int freeze_super(struct super_block *sb)
|
||||||
* For debugging purposes so that fs can warn if it sees write activity
|
* For debugging purposes so that fs can warn if it sees write activity
|
||||||
* when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super().
|
* when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super().
|
||||||
*/
|
*/
|
||||||
|
sb->s_writers.freeze_holders |= who;
|
||||||
sb->s_writers.frozen = SB_FREEZE_COMPLETE;
|
sb->s_writers.frozen = SB_FREEZE_COMPLETE;
|
||||||
lockdep_sb_freeze_release(sb);
|
lockdep_sb_freeze_release(sb);
|
||||||
up_write(&sb->s_umount);
|
up_write(&sb->s_umount);
|
||||||
|
@ -1745,16 +1776,39 @@ int freeze_super(struct super_block *sb)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(freeze_super);
|
EXPORT_SYMBOL(freeze_super);
|
||||||
|
|
||||||
static int thaw_super_locked(struct super_block *sb)
|
/*
|
||||||
|
* Undoes the effect of a freeze_super_locked call. If the filesystem is
|
||||||
|
* frozen both by userspace and the kernel, a thaw call from either source
|
||||||
|
* removes that state without releasing the other state or unlocking the
|
||||||
|
* filesystem.
|
||||||
|
*/
|
||||||
|
static int thaw_super_locked(struct super_block *sb, enum freeze_holder who)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
|
if (sb->s_writers.frozen == SB_FREEZE_COMPLETE) {
|
||||||
|
if (!(sb->s_writers.freeze_holders & who)) {
|
||||||
|
up_write(&sb->s_umount);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Freeze is shared with someone else. Release our hold and
|
||||||
|
* drop the active ref that freeze_super assigned to the
|
||||||
|
* freezer.
|
||||||
|
*/
|
||||||
|
if (sb->s_writers.freeze_holders & ~who) {
|
||||||
|
sb->s_writers.freeze_holders &= ~who;
|
||||||
|
deactivate_locked_super(sb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
up_write(&sb->s_umount);
|
up_write(&sb->s_umount);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb_rdonly(sb)) {
|
if (sb_rdonly(sb)) {
|
||||||
|
sb->s_writers.freeze_holders &= ~who;
|
||||||
sb->s_writers.frozen = SB_UNFROZEN;
|
sb->s_writers.frozen = SB_UNFROZEN;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1772,6 +1826,7 @@ static int thaw_super_locked(struct super_block *sb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sb->s_writers.freeze_holders &= ~who;
|
||||||
sb->s_writers.frozen = SB_UNFROZEN;
|
sb->s_writers.frozen = SB_UNFROZEN;
|
||||||
sb_freeze_unlock(sb, SB_FREEZE_FS);
|
sb_freeze_unlock(sb, SB_FREEZE_FS);
|
||||||
out:
|
out:
|
||||||
|
@ -1782,13 +1837,19 @@ out:
|
||||||
/**
|
/**
|
||||||
* thaw_super -- unlock filesystem
|
* thaw_super -- unlock filesystem
|
||||||
* @sb: the super to thaw
|
* @sb: the super to thaw
|
||||||
|
* @who: context that wants to freeze
|
||||||
*
|
*
|
||||||
* Unlocks the filesystem and marks it writeable again after freeze_super().
|
* Unlocks the filesystem and marks it writeable again after freeze_super()
|
||||||
|
* if there are no remaining freezes on the filesystem.
|
||||||
|
*
|
||||||
|
* @who should be:
|
||||||
|
* * %FREEZE_HOLDER_USERSPACE if userspace wants to thaw the fs;
|
||||||
|
* * %FREEZE_HOLDER_KERNEL if the kernel wants to thaw the fs.
|
||||||
*/
|
*/
|
||||||
int thaw_super(struct super_block *sb)
|
int thaw_super(struct super_block *sb, enum freeze_holder who)
|
||||||
{
|
{
|
||||||
down_write(&sb->s_umount);
|
down_write(&sb->s_umount);
|
||||||
return thaw_super_locked(sb);
|
return thaw_super_locked(sb, who);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(thaw_super);
|
EXPORT_SYMBOL(thaw_super);
|
||||||
|
|
||||||
|
|
|
@ -1147,7 +1147,8 @@ enum {
|
||||||
#define SB_FREEZE_LEVELS (SB_FREEZE_COMPLETE - 1)
|
#define SB_FREEZE_LEVELS (SB_FREEZE_COMPLETE - 1)
|
||||||
|
|
||||||
struct sb_writers {
|
struct sb_writers {
|
||||||
int frozen; /* Is sb frozen? */
|
unsigned short frozen; /* Is sb frozen? */
|
||||||
|
unsigned short freeze_holders; /* Who froze fs? */
|
||||||
struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS];
|
struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1902,6 +1903,10 @@ extern loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
|
||||||
struct file *dst_file, loff_t dst_pos,
|
struct file *dst_file, loff_t dst_pos,
|
||||||
loff_t len, unsigned int remap_flags);
|
loff_t len, unsigned int remap_flags);
|
||||||
|
|
||||||
|
enum freeze_holder {
|
||||||
|
FREEZE_HOLDER_KERNEL = (1U << 0),
|
||||||
|
FREEZE_HOLDER_USERSPACE = (1U << 1),
|
||||||
|
};
|
||||||
|
|
||||||
struct super_operations {
|
struct super_operations {
|
||||||
struct inode *(*alloc_inode)(struct super_block *sb);
|
struct inode *(*alloc_inode)(struct super_block *sb);
|
||||||
|
@ -1914,9 +1919,9 @@ struct super_operations {
|
||||||
void (*evict_inode) (struct inode *);
|
void (*evict_inode) (struct inode *);
|
||||||
void (*put_super) (struct super_block *);
|
void (*put_super) (struct super_block *);
|
||||||
int (*sync_fs)(struct super_block *sb, int wait);
|
int (*sync_fs)(struct super_block *sb, int wait);
|
||||||
int (*freeze_super) (struct super_block *);
|
int (*freeze_super) (struct super_block *, enum freeze_holder who);
|
||||||
int (*freeze_fs) (struct super_block *);
|
int (*freeze_fs) (struct super_block *);
|
||||||
int (*thaw_super) (struct super_block *);
|
int (*thaw_super) (struct super_block *, enum freeze_holder who);
|
||||||
int (*unfreeze_fs) (struct super_block *);
|
int (*unfreeze_fs) (struct super_block *);
|
||||||
int (*statfs) (struct dentry *, struct kstatfs *);
|
int (*statfs) (struct dentry *, struct kstatfs *);
|
||||||
int (*remount_fs) (struct super_block *, int *, char *);
|
int (*remount_fs) (struct super_block *, int *, char *);
|
||||||
|
@ -2290,8 +2295,8 @@ extern int unregister_filesystem(struct file_system_type *);
|
||||||
extern int vfs_statfs(const struct path *, struct kstatfs *);
|
extern int vfs_statfs(const struct path *, struct kstatfs *);
|
||||||
extern int user_statfs(const char __user *, struct kstatfs *);
|
extern int user_statfs(const char __user *, struct kstatfs *);
|
||||||
extern int fd_statfs(int, struct kstatfs *);
|
extern int fd_statfs(int, struct kstatfs *);
|
||||||
extern int freeze_super(struct super_block *super);
|
int freeze_super(struct super_block *super, enum freeze_holder who);
|
||||||
extern int thaw_super(struct super_block *super);
|
int thaw_super(struct super_block *super, enum freeze_holder who);
|
||||||
extern __printf(2, 3)
|
extern __printf(2, 3)
|
||||||
int super_setup_bdi_name(struct super_block *sb, char *fmt, ...);
|
int super_setup_bdi_name(struct super_block *sb, char *fmt, ...);
|
||||||
extern int super_setup_bdi(struct super_block *sb);
|
extern int super_setup_bdi(struct super_block *sb);
|
||||||
|
|
Loading…
Reference in New Issue