Skip to content

Commit 4de8514

Browse files
ndosscheJaegeuk Kim
authored andcommitted
f2fs: extend stat_lock to avoid potential race in statfs
There are multiple calculations and reads of fields of sbi that should be protected by stat_lock. As stat_lock is not used to read these values in statfs, this can lead to inconsistent results. Extend the locking to prevent this issue. Commit c9c8ed5 ("f2fs: fix to avoid potential race on sbi->unusable_block_count access/update") already added the use of sbi->stat_lock in statfs in order to make the calculation of multiple, different fields atomic so that results are consistent. This is similar to that patch regarding the change in statfs. Signed-off-by: Niels Dossche <dossche.niels@gmail.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent a7b8618 commit 4de8514

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

fs/f2fs/super.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,18 +1707,23 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
17071707
u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
17081708
block_t total_count, user_block_count, start_count;
17091709
u64 avail_node_count;
1710+
unsigned int total_valid_node_count;
17101711

17111712
total_count = le64_to_cpu(sbi->raw_super->block_count);
1712-
user_block_count = sbi->user_block_count;
17131713
start_count = le32_to_cpu(sbi->raw_super->segment0_blkaddr);
17141714
buf->f_type = F2FS_SUPER_MAGIC;
17151715
buf->f_bsize = sbi->blocksize;
17161716

17171717
buf->f_blocks = total_count - start_count;
1718+
1719+
spin_lock(&sbi->stat_lock);
1720+
1721+
user_block_count = sbi->user_block_count;
1722+
total_valid_node_count = valid_node_count(sbi);
1723+
avail_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
17181724
buf->f_bfree = user_block_count - valid_user_blocks(sbi) -
17191725
sbi->current_reserved_blocks;
17201726

1721-
spin_lock(&sbi->stat_lock);
17221727
if (unlikely(buf->f_bfree <= sbi->unusable_block_count))
17231728
buf->f_bfree = 0;
17241729
else
@@ -1731,14 +1736,12 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
17311736
else
17321737
buf->f_bavail = 0;
17331738

1734-
avail_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
1735-
17361739
if (avail_node_count > user_block_count) {
17371740
buf->f_files = user_block_count;
17381741
buf->f_ffree = buf->f_bavail;
17391742
} else {
17401743
buf->f_files = avail_node_count;
1741-
buf->f_ffree = min(avail_node_count - valid_node_count(sbi),
1744+
buf->f_ffree = min(avail_node_count - total_valid_node_count,
17421745
buf->f_bavail);
17431746
}
17441747

0 commit comments

Comments
 (0)