提交 c79d967d 编写于 作者: C Christoph Hellwig 提交者: Jan Kara

quota: move remount handling into the filesystem

Currently do_remount_sb calls into the dquot code to tell it about going
from rw to ro and ro to rw.  Move this code into the filesystem to
not depend on the dquot code in the VFS - note ocfs2 already ignores
these calls and handles remount by itself.  This gets rid of overloading
the quotactl calls and allows to unify the VFS and XFS codepaths in
that area later.
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Signed-off-by: NJan Kara <jack@suse.cz>
上级 eea7feb0
...@@ -1241,6 +1241,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) ...@@ -1241,6 +1241,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
spin_unlock(&sbi->s_lock); spin_unlock(&sbi->s_lock);
return 0; return 0;
} }
/* /*
* OK, we are remounting a valid rw partition rdonly, so set * OK, we are remounting a valid rw partition rdonly, so set
* the rdonly flag and then mark the partition as valid again. * the rdonly flag and then mark the partition as valid again.
...@@ -1248,6 +1249,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) ...@@ -1248,6 +1249,14 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
es->s_state = cpu_to_le16(sbi->s_mount_state); es->s_state = cpu_to_le16(sbi->s_mount_state);
es->s_mtime = cpu_to_le32(get_seconds()); es->s_mtime = cpu_to_le32(get_seconds());
spin_unlock(&sbi->s_lock); spin_unlock(&sbi->s_lock);
err = vfs_dq_off(sb, 1);
if (err < 0 && err != -ENOSYS) {
err = -EBUSY;
spin_lock(&sbi->s_lock);
goto restore_opts;
}
ext2_sync_super(sb, es, 1); ext2_sync_super(sb, es, 1);
} else { } else {
__le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb,
...@@ -1269,8 +1278,12 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) ...@@ -1269,8 +1278,12 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
if (!ext2_setup_super (sb, es, 0)) if (!ext2_setup_super (sb, es, 0))
sb->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
spin_unlock(&sbi->s_lock); spin_unlock(&sbi->s_lock);
ext2_write_super(sb); ext2_write_super(sb);
vfs_dq_quota_on_remount(sb);
} }
return 0; return 0;
restore_opts: restore_opts:
sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_mount_opt = old_opts.s_mount_opt;
......
...@@ -2551,6 +2551,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) ...@@ -2551,6 +2551,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
ext3_fsblk_t n_blocks_count = 0; ext3_fsblk_t n_blocks_count = 0;
unsigned long old_sb_flags; unsigned long old_sb_flags;
struct ext3_mount_options old_opts; struct ext3_mount_options old_opts;
int enable_quota = 0;
int err; int err;
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
int i; int i;
...@@ -2597,6 +2598,12 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) ...@@ -2597,6 +2598,12 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
} }
if (*flags & MS_RDONLY) { if (*flags & MS_RDONLY) {
err = vfs_dq_off(sb, 1);
if (err < 0 && err != -ENOSYS) {
err = -EBUSY;
goto restore_opts;
}
/* /*
* First of all, the unconditional stuff we have to do * First of all, the unconditional stuff we have to do
* to disable replay of the journal when we next remount * to disable replay of the journal when we next remount
...@@ -2651,6 +2658,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) ...@@ -2651,6 +2658,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
goto restore_opts; goto restore_opts;
if (!ext3_setup_super (sb, es, 0)) if (!ext3_setup_super (sb, es, 0))
sb->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
enable_quota = 1;
} }
} }
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
...@@ -2662,6 +2670,9 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) ...@@ -2662,6 +2670,9 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
#endif #endif
unlock_super(sb); unlock_super(sb);
unlock_kernel(); unlock_kernel();
if (enable_quota)
vfs_dq_quota_on_remount(sb);
return 0; return 0;
restore_opts: restore_opts:
sb->s_flags = old_sb_flags; sb->s_flags = old_sb_flags;
......
...@@ -3574,6 +3574,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -3574,6 +3574,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
ext4_fsblk_t n_blocks_count = 0; ext4_fsblk_t n_blocks_count = 0;
unsigned long old_sb_flags; unsigned long old_sb_flags;
struct ext4_mount_options old_opts; struct ext4_mount_options old_opts;
int enable_quota = 0;
ext4_group_t g; ext4_group_t g;
unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
int err; int err;
...@@ -3630,6 +3631,12 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -3630,6 +3631,12 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
} }
if (*flags & MS_RDONLY) { if (*flags & MS_RDONLY) {
err = vfs_dq_off(sb, 1);
if (err < 0 && err != -ENOSYS) {
err = -EBUSY;
goto restore_opts;
}
/* /*
* First of all, the unconditional stuff we have to do * First of all, the unconditional stuff we have to do
* to disable replay of the journal when we next remount * to disable replay of the journal when we next remount
...@@ -3698,6 +3705,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -3698,6 +3705,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
goto restore_opts; goto restore_opts;
if (!ext4_setup_super(sb, es, 0)) if (!ext4_setup_super(sb, es, 0))
sb->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
enable_quota = 1;
} }
} }
ext4_setup_system_zone(sb); ext4_setup_system_zone(sb);
...@@ -3713,6 +3721,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) ...@@ -3713,6 +3721,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
#endif #endif
unlock_super(sb); unlock_super(sb);
unlock_kernel(); unlock_kernel();
if (enable_quota)
vfs_dq_quota_on_remount(sb);
return 0; return 0;
restore_opts: restore_opts:
......
...@@ -396,10 +396,20 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) ...@@ -396,10 +396,20 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
JFS_SBI(sb)->flag = flag; JFS_SBI(sb)->flag = flag;
ret = jfs_mount_rw(sb, 1); ret = jfs_mount_rw(sb, 1);
/* mark the fs r/w for quota activity */
sb->s_flags &= ~MS_RDONLY;
unlock_kernel(); unlock_kernel();
vfs_dq_quota_on_remount(sb);
return ret; return ret;
} }
if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
rc = vfs_dq_off(sb, 1);
if (rc < 0 && rc != -ENOSYS) {
unlock_kernel();
return -EBUSY;
}
rc = jfs_umount_rw(sb); rc = jfs_umount_rw(sb);
JFS_SBI(sb)->flag = flag; JFS_SBI(sb)->flag = flag;
unlock_kernel(); unlock_kernel();
......
...@@ -1242,6 +1242,13 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) ...@@ -1242,6 +1242,13 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
if (s->s_flags & MS_RDONLY) if (s->s_flags & MS_RDONLY)
/* it is read-only already */ /* it is read-only already */
goto out_ok; goto out_ok;
err = vfs_dq_off(s, 1);
if (err < 0 && err != -ENOSYS) {
err = -EBUSY;
goto out_err;
}
/* try to remount file system with read-only permissions */ /* try to remount file system with read-only permissions */
if (sb_umount_state(rs) == REISERFS_VALID_FS if (sb_umount_state(rs) == REISERFS_VALID_FS
|| REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
...@@ -1295,6 +1302,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) ...@@ -1295,6 +1302,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
s->s_dirt = 0; s->s_dirt = 0;
if (!(*mount_flags & MS_RDONLY)) { if (!(*mount_flags & MS_RDONLY)) {
vfs_dq_quota_on_remount(s);
finish_unfinished(s); finish_unfinished(s);
reiserfs_xattr_init(s, *mount_flags); reiserfs_xattr_init(s, *mount_flags);
} }
......
...@@ -524,7 +524,7 @@ struct super_block *user_get_super(dev_t dev) ...@@ -524,7 +524,7 @@ struct super_block *user_get_super(dev_t dev)
int do_remount_sb(struct super_block *sb, int flags, void *data, int force) int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
{ {
int retval; int retval;
int remount_rw, remount_ro; int remount_ro;
if (sb->s_frozen != SB_UNFROZEN) if (sb->s_frozen != SB_UNFROZEN)
return -EBUSY; return -EBUSY;
...@@ -540,7 +540,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) ...@@ -540,7 +540,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
sync_filesystem(sb); sync_filesystem(sb);
remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
/* If we are remounting RDONLY and current sb is read/write, /* If we are remounting RDONLY and current sb is read/write,
make sure there are no rw files opened */ make sure there are no rw files opened */
...@@ -549,9 +548,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) ...@@ -549,9 +548,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
mark_files_ro(sb); mark_files_ro(sb);
else if (!fs_may_remount_ro(sb)) else if (!fs_may_remount_ro(sb))
return -EBUSY; return -EBUSY;
retval = vfs_dq_off(sb, 1);
if (retval < 0 && retval != -ENOSYS)
return -EBUSY;
} }
if (sb->s_op->remount_fs) { if (sb->s_op->remount_fs) {
...@@ -560,8 +556,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) ...@@ -560,8 +556,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
return retval; return retval;
} }
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
if (remount_rw)
vfs_dq_quota_on_remount(sb);
/* /*
* Some filesystems modify their metadata via some other path than the * Some filesystems modify their metadata via some other path than the
* bdev buffer cache (eg. use a private mapping, or directories in * bdev buffer cache (eg. use a private mapping, or directories in
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/quotaops.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/crc-itu-t.h> #include <linux/crc-itu-t.h>
...@@ -557,6 +558,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) ...@@ -557,6 +558,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
{ {
struct udf_options uopt; struct udf_options uopt;
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
int error = 0;
uopt.flags = sbi->s_flags; uopt.flags = sbi->s_flags;
uopt.uid = sbi->s_uid; uopt.uid = sbi->s_uid;
...@@ -582,17 +584,26 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) ...@@ -582,17 +584,26 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
} }
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
unlock_kernel(); goto out_unlock;
return 0;
} if (*flags & MS_RDONLY) {
if (*flags & MS_RDONLY)
udf_close_lvid(sb); udf_close_lvid(sb);
else
error = vfs_dq_off(sb, 1);
if (error < 0 && error != -ENOSYS)
error = -EBUSY;
} else {
udf_open_lvid(sb); udf_open_lvid(sb);
/* mark the fs r/w for quota activity */
sb->s_flags &= ~MS_RDONLY;
vfs_dq_quota_on_remount(sb);
}
out_unlock:
unlock_kernel(); unlock_kernel();
return 0; return error;
} }
/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ /* Check Volume Structure Descriptors (ECMA 167 2/9.1) */
......
...@@ -1248,7 +1248,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) ...@@ -1248,7 +1248,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
struct ufs_super_block_first * usb1; struct ufs_super_block_first * usb1;
struct ufs_super_block_third * usb3; struct ufs_super_block_third * usb3;
unsigned new_mount_opt, ufstype; unsigned new_mount_opt, ufstype;
int enable_quota = 0;
unsigned flags; unsigned flags;
int err;
lock_kernel(); lock_kernel();
lock_super(sb); lock_super(sb);
...@@ -1289,6 +1291,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) ...@@ -1289,6 +1291,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
* fs was mouted as rw, remounting ro * fs was mouted as rw, remounting ro
*/ */
if (*mount_flags & MS_RDONLY) { if (*mount_flags & MS_RDONLY) {
err = vfs_dq_off(sb, 1);
if (err < 0 && err != -ENOSYS) {
unlock_super(sb);
unlock_kernel();
return -EBUSY;
}
ufs_put_super_internal(sb); ufs_put_super_internal(sb);
usb1->fs_time = cpu_to_fs32(sb, get_seconds()); usb1->fs_time = cpu_to_fs32(sb, get_seconds());
if ((flags & UFS_ST_MASK) == UFS_ST_SUN if ((flags & UFS_ST_MASK) == UFS_ST_SUN
...@@ -1327,11 +1336,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) ...@@ -1327,11 +1336,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
return -EPERM; return -EPERM;
} }
sb->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
enable_quota = 1;
#endif #endif
} }
UFS_SB(sb)->s_mount_opt = new_mount_opt; UFS_SB(sb)->s_mount_opt = new_mount_opt;
unlock_super(sb); unlock_super(sb);
unlock_kernel(); unlock_kernel();
if (enable_quota)
vfs_dq_quota_on_remount(sb);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册