Skip to content

Commit

Permalink
f2fs: fix to avoid race in between atomic write and background GC
Browse files Browse the repository at this point in the history
Sqlite user			Background GC
				- move_data_block
				  : move page #1
				 - f2fs_is_atomic_file
- f2fs_ioc_start_atomic_write
- f2fs_ioc_commit_atomic_write
 - commit_inmem_pages
   : commit page #1 & set node #2 dirty
				 - f2fs_submit_page_write
				  - f2fs_update_data_blkaddr
				   - set_page_dirty
				     : set node #2 dirty
 - f2fs_do_sync_file
  - fsync_node_pages
   : commit node #1 & node #2, then sudden power-cut

In a race case, we may check FI_ATOMIC_FILE flag before starting atomic
write flow, then we will commit meta data before data with reversed
order, after a sudden pow-cut, database transaction will be inconsistent.

So we'd better to exclude gc/atomic_write to each other by using lock
instead of flag checking.

Signed-off-by: Chao Yu <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
  • Loading branch information
chaseyu authored and Jaegeuk Kim committed Apr 8, 2018
1 parent e87b13e commit f4f1022
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions fs/f2fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1709,6 +1709,8 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)

inode_lock(inode);

down_write(&F2FS_I(inode)->dio_rwsem[WRITE]);

if (f2fs_is_volatile_file(inode))
goto err_out;

Expand All @@ -1727,6 +1729,7 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false);
}
err_out:
up_write(&F2FS_I(inode)->dio_rwsem[WRITE]);
inode_unlock(inode);
mnt_drop_write_file(filp);
return ret;
Expand Down

0 comments on commit f4f1022

Please sign in to comment.