diff options
author | Chao Yu <yuchao0@huawei.com> | 2019-07-25 11:33:37 +0200 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2019-08-23 16:57:12 +0200 |
commit | fe973b065bce0e61414c33251afae501a757f8c6 (patch) | |
tree | 6cc8f115a25c34d68242b6f7e301d8e68531de33 /fs/f2fs | |
parent | f2fs: fix to detect cp error in f2fs_setxattr() (diff) | |
download | linux-fe973b065bce0e61414c33251afae501a757f8c6.tar.xz linux-fe973b065bce0e61414c33251afae501a757f8c6.zip |
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>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/super.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2d2c91c7eadd..9167deb0c417 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2000,6 +2000,12 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id, struct inode *inode; 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); if (err) return err; @@ -2019,7 +2025,7 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id, 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]; int err; @@ -2045,13 +2051,30 @@ out_put: 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) { int type; int err; for (type = 0; type < MAXQUOTAS; type++) { - err = f2fs_quota_off(sb, type); + err = __f2fs_quota_off(sb, type); if (err) { int ret = dquot_quota_off(sb, type); |