f2fs: fix to handle quota_{on,off} correctly
With quota_ino feature on, generic/232 reports an inconsistence issue on the image. The root cause is that the testcase tries to: - use quotactl to shutdown journalled quota based on sysfile; - and then use quotactl to enable/turn on quota based on specific file (aquota.user or aquota.group). Eventually, quota sysfile will be out-of-update due to following specific file creation. Change as below to fix this issue: - deny enabling quota based on specific file if quota sysfile exists. - set SBI_QUOTA_NEED_REPAIR once sysfile based quota shutdowns via ioctl. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
a25c2cdcb6
commit
fe973b065b
|
@ -2000,6 +2000,12 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/* if quota sysfile exists, deny enabling quota with specific file */
|
||||||
|
if (f2fs_sb_has_quota_ino(F2FS_SB(sb))) {
|
||||||
|
f2fs_err(F2FS_SB(sb), "quota sysfile already exists");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
err = f2fs_quota_sync(sb, type);
|
err = f2fs_quota_sync(sb, type);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -2019,7 +2025,7 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f2fs_quota_off(struct super_block *sb, int type)
|
static int __f2fs_quota_off(struct super_block *sb, int type)
|
||||||
{
|
{
|
||||||
struct inode *inode = sb_dqopt(sb)->files[type];
|
struct inode *inode = sb_dqopt(sb)->files[type];
|
||||||
int err;
|
int err;
|
||||||
|
@ -2045,13 +2051,30 @@ out_put:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int f2fs_quota_off(struct super_block *sb, int type)
|
||||||
|
{
|
||||||
|
struct f2fs_sb_info *sbi = F2FS_SB(sb);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = __f2fs_quota_off(sb, type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* quotactl can shutdown journalled quota, result in inconsistence
|
||||||
|
* between quota record and fs data by following updates, tag the
|
||||||
|
* flag to let fsck be aware of it.
|
||||||
|
*/
|
||||||
|
if (is_journalled_quota(sbi))
|
||||||
|
set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
void f2fs_quota_off_umount(struct super_block *sb)
|
void f2fs_quota_off_umount(struct super_block *sb)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
for (type = 0; type < MAXQUOTAS; type++) {
|
for (type = 0; type < MAXQUOTAS; type++) {
|
||||||
err = f2fs_quota_off(sb, type);
|
err = __f2fs_quota_off(sb, type);
|
||||||
if (err) {
|
if (err) {
|
||||||
int ret = dquot_quota_off(sb, type);
|
int ret = dquot_quota_off(sb, type);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue