Skip to content

Commit af033b2

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: guarantee journalled quota data by checkpoint
For journalled quota mode, let checkpoint to flush dquot dirty data and quota file data to guarntee persistence of all quota sysfile in last checkpoint, by this way, we can avoid corrupting quota sysfile when encountering SPO. The implementation is as below: 1. add a global state SBI_QUOTA_NEED_FLUSH to indicate that there is cached dquot metadata changes in quota subsystem, and later checkpoint should: a) flush dquot metadata into quota file. b) flush quota file to storage to keep file usage be consistent. 2. add a global state SBI_QUOTA_NEED_REPAIR to indicate that quota operation failed due to -EIO or -ENOSPC, so later, a) checkpoint will skip syncing dquot metadata. b) CP_QUOTA_NEED_FSCK_FLAG will be set in last cp pack to give a hint for fsck repairing. 3. add a global state SBI_QUOTA_SKIP_FLUSH, in checkpoint, if quota data updating is very heavy, it may cause hungtask in block_operation(). To avoid this, if our retry time exceed threshold, let's just skip flushing and retry in next checkpoint(). Signed-off-by: Weichao Guo <guoweichao@huawei.com> Signed-off-by: Chao Yu <yuchao0@huawei.com> [Jaegeuk Kim: avoid warnings and set fsck flag] Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 26b5a07 commit af033b2

File tree

10 files changed

+294
-48
lines changed

10 files changed

+294
-48
lines changed

fs/f2fs/checkpoint.c

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,21 @@ static void __prepare_cp_block(struct f2fs_sb_info *sbi)
10791079
ckpt->next_free_nid = cpu_to_le32(last_nid);
10801080
}
10811081

1082+
static bool __need_flush_quota(struct f2fs_sb_info *sbi)
1083+
{
1084+
if (!is_journalled_quota(sbi))
1085+
return false;
1086+
if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH))
1087+
return false;
1088+
if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR))
1089+
return false;
1090+
if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_FLUSH))
1091+
return true;
1092+
if (get_pages(sbi, F2FS_DIRTY_QDATA))
1093+
return true;
1094+
return false;
1095+
}
1096+
10821097
/*
10831098
* Freeze all the FS-operations for checkpoint.
10841099
*/
@@ -1090,20 +1105,44 @@ static int block_operations(struct f2fs_sb_info *sbi)
10901105
.for_reclaim = 0,
10911106
};
10921107
struct blk_plug plug;
1093-
int err = 0;
1108+
int err = 0, cnt = 0;
10941109

10951110
blk_start_plug(&plug);
10961111

1097-
retry_flush_dents:
1112+
retry_flush_quotas:
1113+
if (__need_flush_quota(sbi)) {
1114+
int locked;
1115+
1116+
if (++cnt > DEFAULT_RETRY_QUOTA_FLUSH_COUNT) {
1117+
set_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH);
1118+
f2fs_lock_all(sbi);
1119+
goto retry_flush_dents;
1120+
}
1121+
clear_sbi_flag(sbi, SBI_QUOTA_NEED_FLUSH);
1122+
1123+
/* only failed during mount/umount/freeze/quotactl */
1124+
locked = down_read_trylock(&sbi->sb->s_umount);
1125+
f2fs_quota_sync(sbi->sb, -1);
1126+
if (locked)
1127+
up_read(&sbi->sb->s_umount);
1128+
}
1129+
10981130
f2fs_lock_all(sbi);
1131+
if (__need_flush_quota(sbi)) {
1132+
f2fs_unlock_all(sbi);
1133+
cond_resched();
1134+
goto retry_flush_quotas;
1135+
}
1136+
1137+
retry_flush_dents:
10991138
/* write all the dirty dentry pages */
11001139
if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
11011140
f2fs_unlock_all(sbi);
11021141
err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
11031142
if (err)
11041143
goto out;
11051144
cond_resched();
1106-
goto retry_flush_dents;
1145+
goto retry_flush_quotas;
11071146
}
11081147

11091148
/*
@@ -1112,14 +1151,20 @@ static int block_operations(struct f2fs_sb_info *sbi)
11121151
*/
11131152
down_write(&sbi->node_change);
11141153

1154+
if (__need_flush_quota(sbi)) {
1155+
up_write(&sbi->node_change);
1156+
f2fs_unlock_all(sbi);
1157+
goto retry_flush_quotas;
1158+
}
1159+
11151160
if (get_pages(sbi, F2FS_DIRTY_IMETA)) {
11161161
up_write(&sbi->node_change);
11171162
f2fs_unlock_all(sbi);
11181163
err = f2fs_sync_inode_meta(sbi);
11191164
if (err)
11201165
goto out;
11211166
cond_resched();
1122-
goto retry_flush_dents;
1167+
goto retry_flush_quotas;
11231168
}
11241169

11251170
retry_flush_nodes:
@@ -1215,6 +1260,14 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc)
12151260
else
12161261
__clear_ckpt_flags(ckpt, CP_DISABLED_FLAG);
12171262

1263+
if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH))
1264+
__set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
1265+
else
1266+
__clear_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
1267+
1268+
if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR))
1269+
__set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG);
1270+
12181271
/* set this flag to activate crc|cp_ver for recovery */
12191272
__set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG);
12201273
__clear_ckpt_flags(ckpt, CP_NOCRC_RECOVERY_FLAG);
@@ -1422,6 +1475,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
14221475

14231476
clear_sbi_flag(sbi, SBI_IS_DIRTY);
14241477
clear_sbi_flag(sbi, SBI_NEED_CP);
1478+
clear_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH);
14251479
sbi->unusable_block_count = 0;
14261480
__set_cp_next_pack(sbi);
14271481

fs/f2fs/data.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static bool __is_cp_guaranteed(struct page *page)
4646
inode->i_ino == F2FS_NODE_INO(sbi) ||
4747
S_ISDIR(inode->i_mode) ||
4848
(S_ISREG(inode->i_mode) &&
49-
is_inode_flag_set(inode, FI_ATOMIC_FILE)) ||
49+
(f2fs_is_atomic_file(inode) || IS_NOQUOTA(inode))) ||
5050
is_cold_data(page))
5151
return true;
5252
return false;
@@ -1766,6 +1766,8 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
17661766
return true;
17671767
if (S_ISDIR(inode->i_mode))
17681768
return true;
1769+
if (IS_NOQUOTA(inode))
1770+
return true;
17691771
if (f2fs_is_atomic_file(inode))
17701772
return true;
17711773
if (fio) {
@@ -2016,7 +2018,7 @@ static int __write_data_page(struct page *page, bool *submitted,
20162018
}
20172019

20182020
unlock_page(page);
2019-
if (!S_ISDIR(inode->i_mode))
2021+
if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode))
20202022
f2fs_balance_fs(sbi, need_balance_fs);
20212023

20222024
if (unlikely(f2fs_cp_error(sbi))) {
@@ -2207,6 +2209,8 @@ static inline bool __should_serialize_io(struct inode *inode,
22072209
{
22082210
if (!S_ISREG(inode->i_mode))
22092211
return false;
2212+
if (IS_NOQUOTA(inode))
2213+
return false;
22102214
if (wbc->sync_mode != WB_SYNC_ALL)
22112215
return true;
22122216
if (get_dirty_pages(inode) >= SM_I(F2FS_I_SB(inode))->min_seq_blocks)
@@ -2236,7 +2240,8 @@ static int __f2fs_write_data_pages(struct address_space *mapping,
22362240
if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
22372241
goto skip_write;
22382242

2239-
if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
2243+
if ((S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) &&
2244+
wbc->sync_mode == WB_SYNC_NONE &&
22402245
get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
22412246
f2fs_available_free_memory(sbi, DIRTY_DENTS))
22422247
goto skip_write;
@@ -2301,7 +2306,7 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)
23012306
down_write(&F2FS_I(inode)->i_mmap_sem);
23022307

23032308
truncate_pagecache(inode, i_size);
2304-
f2fs_truncate_blocks(inode, i_size, true);
2309+
f2fs_truncate_blocks(inode, i_size, true, true);
23052310

23062311
up_write(&F2FS_I(inode)->i_mmap_sem);
23072312
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
@@ -2440,7 +2445,8 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
24402445
if (err)
24412446
goto fail;
24422447

2443-
if (need_balance && has_not_enough_free_secs(sbi, 0, 0)) {
2448+
if (need_balance && !IS_NOQUOTA(inode) &&
2449+
has_not_enough_free_secs(sbi, 0, 0)) {
24442450
unlock_page(page);
24452451
f2fs_balance_fs(sbi, true);
24462452
lock_page(page);

fs/f2fs/f2fs.h

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,9 @@ enum {
531531

532532
#define DEFAULT_RETRY_IO_COUNT 8 /* maximum retry read IO count */
533533

534+
/* maximum retry quota flush count */
535+
#define DEFAULT_RETRY_QUOTA_FLUSH_COUNT 8
536+
534537
#define F2FS_LINK_MAX 0xffffffff /* maximum link count per file */
535538

536539
#define MAX_DIR_RA_PAGES 4 /* maximum ra pages of dir */
@@ -1099,6 +1102,9 @@ enum {
10991102
SBI_IS_SHUTDOWN, /* shutdown by ioctl */
11001103
SBI_IS_RECOVERED, /* recovered orphan/data */
11011104
SBI_CP_DISABLED, /* CP was disabled last mount */
1105+
SBI_QUOTA_NEED_FLUSH, /* need to flush quota info in CP */
1106+
SBI_QUOTA_SKIP_FLUSH, /* skip flushing quota in current CP */
1107+
SBI_QUOTA_NEED_REPAIR, /* quota file may be corrupted */
11021108
};
11031109

11041110
enum {
@@ -1923,12 +1929,18 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
19231929
{
19241930
block_t valid_block_count;
19251931
unsigned int valid_node_count;
1926-
bool quota = inode && !is_inode;
1932+
int err;
19271933

1928-
if (quota) {
1929-
int ret = dquot_reserve_block(inode, 1);
1930-
if (ret)
1931-
return ret;
1934+
if (is_inode) {
1935+
if (inode) {
1936+
err = dquot_alloc_inode(inode);
1937+
if (err)
1938+
return err;
1939+
}
1940+
} else {
1941+
err = dquot_reserve_block(inode, 1);
1942+
if (err)
1943+
return err;
19321944
}
19331945

19341946
if (time_to_inject(sbi, FAULT_BLOCK)) {
@@ -1972,8 +1984,12 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
19721984
return 0;
19731985

19741986
enospc:
1975-
if (quota)
1987+
if (is_inode) {
1988+
if (inode)
1989+
dquot_free_inode(inode);
1990+
} else {
19761991
dquot_release_reservation_block(inode, 1);
1992+
}
19771993
return -ENOSPC;
19781994
}
19791995

@@ -1994,7 +2010,9 @@ static inline void dec_valid_node_count(struct f2fs_sb_info *sbi,
19942010

19952011
spin_unlock(&sbi->stat_lock);
19962012

1997-
if (!is_inode)
2013+
if (is_inode)
2014+
dquot_free_inode(inode);
2015+
else
19982016
f2fs_i_blocks_write(inode, 1, false, true);
19992017
}
20002018

@@ -2782,7 +2800,8 @@ static inline bool is_valid_data_blkaddr(struct f2fs_sb_info *sbi,
27822800
*/
27832801
int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
27842802
void f2fs_truncate_data_blocks(struct dnode_of_data *dn);
2785-
int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock);
2803+
int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock,
2804+
bool buf_write);
27862805
int f2fs_truncate(struct inode *inode);
27872806
int f2fs_getattr(const struct path *path, struct kstat *stat,
27882807
u32 request_mask, unsigned int flags);
@@ -2870,6 +2889,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode)
28702889
int f2fs_inode_dirtied(struct inode *inode, bool sync);
28712890
void f2fs_inode_synced(struct inode *inode);
28722891
int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
2892+
int f2fs_quota_sync(struct super_block *sb, int type);
28732893
void f2fs_quota_off_umount(struct super_block *sb);
28742894
int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
28752895
int f2fs_sync_fs(struct super_block *sb, int sync);
@@ -3564,3 +3584,16 @@ extern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
35643584
#endif
35653585

35663586
#endif
3587+
3588+
static inline bool is_journalled_quota(struct f2fs_sb_info *sbi)
3589+
{
3590+
#ifdef CONFIG_QUOTA
3591+
if (f2fs_sb_has_quota_ino(sbi->sb))
3592+
return true;
3593+
if (F2FS_OPTION(sbi).s_qf_names[USRQUOTA] ||
3594+
F2FS_OPTION(sbi).s_qf_names[GRPQUOTA] ||
3595+
F2FS_OPTION(sbi).s_qf_names[PRJQUOTA])
3596+
return true;
3597+
#endif
3598+
return false;
3599+
}

fs/f2fs/file.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -586,14 +586,16 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
586586
return 0;
587587
}
588588

589-
int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock)
589+
int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock,
590+
bool buf_write)
590591
{
591592
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
592593
struct dnode_of_data dn;
593594
pgoff_t free_from;
594595
int count = 0, err = 0;
595596
struct page *ipage;
596597
bool truncate_page = false;
598+
int flag = buf_write ? F2FS_GET_BLOCK_PRE_AIO : F2FS_GET_BLOCK_PRE_DIO;
597599

598600
trace_f2fs_truncate_blocks_enter(inode, from);
599601

@@ -603,7 +605,7 @@ int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock)
603605
goto free_partial;
604606

605607
if (lock)
606-
f2fs_lock_op(sbi);
608+
__do_map_lock(sbi, flag, true);
607609

608610
ipage = f2fs_get_node_page(sbi, inode->i_ino);
609611
if (IS_ERR(ipage)) {
@@ -641,7 +643,7 @@ int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock)
641643
err = f2fs_truncate_inode_blocks(inode, free_from);
642644
out:
643645
if (lock)
644-
f2fs_unlock_op(sbi);
646+
__do_map_lock(sbi, flag, false);
645647
free_partial:
646648
/* lastly zero out the first data page */
647649
if (!err)
@@ -676,7 +678,7 @@ int f2fs_truncate(struct inode *inode)
676678
return err;
677679
}
678680

679-
err = f2fs_truncate_blocks(inode, i_size_read(inode), true);
681+
err = f2fs_truncate_blocks(inode, i_size_read(inode), true, false);
680682
if (err)
681683
return err;
682684

@@ -785,9 +787,24 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
785787
!uid_eq(attr->ia_uid, inode->i_uid)) ||
786788
(attr->ia_valid & ATTR_GID &&
787789
!gid_eq(attr->ia_gid, inode->i_gid))) {
790+
f2fs_lock_op(F2FS_I_SB(inode));
788791
err = dquot_transfer(inode, attr);
789-
if (err)
792+
if (err) {
793+
set_sbi_flag(F2FS_I_SB(inode),
794+
SBI_QUOTA_NEED_REPAIR);
795+
f2fs_unlock_op(F2FS_I_SB(inode));
790796
return err;
797+
}
798+
/*
799+
* update uid/gid under lock_op(), so that dquot and inode can
800+
* be updated atomically.
801+
*/
802+
if (attr->ia_valid & ATTR_UID)
803+
inode->i_uid = attr->ia_uid;
804+
if (attr->ia_valid & ATTR_GID)
805+
inode->i_gid = attr->ia_gid;
806+
f2fs_mark_inode_dirty_sync(inode, true);
807+
f2fs_unlock_op(F2FS_I_SB(inode));
791808
}
792809

793810
if (attr->ia_valid & ATTR_SIZE) {
@@ -1242,7 +1259,7 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
12421259
new_size = i_size_read(inode) - len;
12431260
truncate_pagecache(inode, new_size);
12441261

1245-
ret = f2fs_truncate_blocks(inode, new_size, true);
1262+
ret = f2fs_truncate_blocks(inode, new_size, true, false);
12461263
up_write(&F2FS_I(inode)->i_mmap_sem);
12471264
if (!ret)
12481265
f2fs_i_size_write(inode, new_size);
@@ -1427,7 +1444,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
14271444
f2fs_balance_fs(sbi, true);
14281445

14291446
down_write(&F2FS_I(inode)->i_mmap_sem);
1430-
ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
1447+
ret = f2fs_truncate_blocks(inode, i_size_read(inode), true, false);
14311448
up_write(&F2FS_I(inode)->i_mmap_sem);
14321449
if (ret)
14331450
return ret;

fs/f2fs/inline.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ bool f2fs_recover_inline_data(struct inode *inode, struct page *npage)
298298
clear_inode_flag(inode, FI_INLINE_DATA);
299299
f2fs_put_page(ipage, 1);
300300
} else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) {
301-
if (f2fs_truncate_blocks(inode, 0, false))
301+
if (f2fs_truncate_blocks(inode, 0, false, false))
302302
return false;
303303
goto process_inline;
304304
}
@@ -470,7 +470,7 @@ static int f2fs_add_inline_entries(struct inode *dir, void *inline_dentry)
470470
return 0;
471471
punch_dentry_pages:
472472
truncate_inode_pages(&dir->i_data, 0);
473-
f2fs_truncate_blocks(dir, 0, false);
473+
f2fs_truncate_blocks(dir, 0, false, false);
474474
f2fs_remove_dirty_inode(dir);
475475
return err;
476476
}

0 commit comments

Comments
 (0)