]> www.infradead.org Git - linux.git/commit
f2fs: fix to update user block counts in block_operations()
authorChao Yu <chao@kernel.org>
Tue, 25 Jun 2024 02:32:39 +0000 (10:32 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Wed, 10 Jul 2024 22:47:57 +0000 (22:47 +0000)
commitf06c0f82e38bbda7264d6ef3c90045ad2810e0f3
tree5a3382bedf4791ec6cfc4b7ce87dba0064af2b5e
parent54f43a10fa257ad4af02a1d157fefef6ebcfa7dc
f2fs: fix to update user block counts in block_operations()

Commit 59c9081bc86e ("f2fs: allow write page cache when writting cp")
allows write() to write data to page cache during checkpoint, so block
count fields like .total_valid_block_count, .alloc_valid_block_count
and .rf_node_block_count may encounter race condition as below:

CP Thread A
- write_checkpoint
 - block_operations
  - f2fs_down_write(&sbi->node_change)
  - __prepare_cp_block
  : ckpt->valid_block_count = .total_valid_block_count
  - f2fs_up_write(&sbi->node_change)
- write
 - f2fs_preallocate_blocks
  - f2fs_map_blocks(,F2FS_GET_BLOCK_PRE_AIO)
   - f2fs_map_lock
    - f2fs_down_read(&sbi->node_change)
   - f2fs_reserve_new_blocks
    - inc_valid_block_count
    : percpu_counter_add(&sbi->alloc_valid_block_count, count)
    : sbi->total_valid_block_count += count
    - f2fs_up_read(&sbi->node_change)
 - do_checkpoint
 : sbi->last_valid_block_count = sbi->total_valid_block_count
 : percpu_counter_set(&sbi->alloc_valid_block_count, 0)
 : percpu_counter_set(&sbi->rf_node_block_count, 0)
- fsync
 - need_do_checkpoint
  - f2fs_space_for_roll_forward
  : alloc_valid_block_count was reset to zero,
    so, it may missed last data during checkpoint

Let's change to update .total_valid_block_count, .alloc_valid_block_count
and .rf_node_block_count in block_operations(), then their access can be
protected by .node_change and .cp_rwsem lock, so that it can avoid above
race condition.

Fixes: 59c9081bc86e ("f2fs: allow write page cache when writting cp")
Cc: Yunlei He <heyunlei@oppo.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c