Skip to content

Commit ca7f76e

Browse files
chaseyuJaegeuk Kim
authored andcommitted
f2fs: fix wrong discard space
Under heavy fsstress, we may triggle panic while issuing discard, because __check_sit_bitmap() detects that discard command may earse valid data blocks, the root cause is as below race stack described, since we removed lock when flushing quota data, quota data writeback may race with write_checkpoint(), so that it causes inconsistency in between cached discard entry and segment bitmap. - f2fs_write_checkpoint - block_operations - set_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH) - f2fs_flush_sit_entries - add_discard_addrs - __set_bit_le(i, (void *)de->discard_map); - f2fs_write_data_pages - f2fs_write_single_data_page : inode is quota one, cp_rwsem won't be locked - f2fs_do_write_data_page - f2fs_allocate_data_block - f2fs_wait_discard_bio : discard entry has not been added yet. - update_sit_entry - f2fs_clear_prefree_segments - f2fs_issue_discard : add discard entry In order to fix this, this patch uses node_write to serialize f2fs_allocate_data_block and checkpoint. Fixes: 435cbab ("f2fs: fix quota_sync failure due to f2fs_lock_op") Signed-off-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent dc35d73 commit ca7f76e

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

fs/f2fs/segment.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3107,6 +3107,14 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
31073107
type = CURSEG_COLD_DATA;
31083108
}
31093109

3110+
/*
3111+
* We need to wait for node_write to avoid block allocation during
3112+
* checkpoint. This can only happen to quota writes which can cause
3113+
* the below discard race condition.
3114+
*/
3115+
if (IS_DATASEG(type))
3116+
down_write(&sbi->node_write);
3117+
31103118
down_read(&SM_I(sbi)->curseg_lock);
31113119

31123120
mutex_lock(&curseg->curseg_mutex);
@@ -3172,6 +3180,9 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
31723180

31733181
up_read(&SM_I(sbi)->curseg_lock);
31743182

3183+
if (IS_DATASEG(type))
3184+
up_write(&sbi->node_write);
3185+
31753186
if (put_pin_sem)
31763187
up_read(&sbi->pin_sem);
31773188
}

0 commit comments

Comments
 (0)