summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2019-07-25 05:33:37 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2019-08-23 10:57:12 -0400
commitfe973b065bce0e61414c33251afae501a757f8c6 (patch)
tree6cc8f115a25c34d68242b6f7e301d8e68531de33
parenta25c2cdcb61ab3d8d99623a9e72cf1747979a1f9 (diff)
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>
-rw-r--r--fs/f2fs/super.c27
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,
2000 struct inode *inode; 2000 struct inode *inode;
2001 int err; 2001 int err;
2002 2002
2003 /* if quota sysfile exists, deny enabling quota with specific file */
2004 if (f2fs_sb_has_quota_ino(F2FS_SB(sb))) {
2005 f2fs_err(F2FS_SB(sb), "quota sysfile already exists");
2006 return -EBUSY;
2007 }
2008
2003 err = f2fs_quota_sync(sb, type); 2009 err = f2fs_quota_sync(sb, type);
2004 if (err) 2010 if (err)
2005 return err; 2011 return err;
@@ -2019,7 +2025,7 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
2019 return 0; 2025 return 0;
2020} 2026}
2021 2027
2022static int f2fs_quota_off(struct super_block *sb, int type) 2028static int __f2fs_quota_off(struct super_block *sb, int type)
2023{ 2029{
2024 struct inode *inode = sb_dqopt(sb)->files[type]; 2030 struct inode *inode = sb_dqopt(sb)->files[type];
2025 int err; 2031 int err;
@@ -2045,13 +2051,30 @@ out_put:
2045 return err; 2051 return err;
2046} 2052}
2047 2053
2054static int f2fs_quota_off(struct super_block *sb, int type)
2055{
2056 struct f2fs_sb_info *sbi = F2FS_SB(sb);
2057 int err;
2058
2059 err = __f2fs_quota_off(sb, type);
2060
2061 /*
2062 * quotactl can shutdown journalled quota, result in inconsistence
2063 * between quota record and fs data by following updates, tag the
2064 * flag to let fsck be aware of it.
2065 */
2066 if (is_journalled_quota(sbi))
2067 set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
2068 return err;
2069}
2070
2048void f2fs_quota_off_umount(struct super_block *sb) 2071void f2fs_quota_off_umount(struct super_block *sb)
2049{ 2072{
2050 int type; 2073 int type;
2051 int err; 2074 int err;
2052 2075
2053 for (type = 0; type < MAXQUOTAS; type++) { 2076 for (type = 0; type < MAXQUOTAS; type++) {
2054 err = f2fs_quota_off(sb, type); 2077 err = __f2fs_quota_off(sb, type);
2055 if (err) { 2078 if (err) {
2056 int ret = dquot_quota_off(sb, type); 2079 int ret = dquot_quota_off(sb, type);
2057 2080