提交 4de85145 编写于 作者: N Niels Dossche 提交者: Jaegeuk Kim

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 c9c8ed50 ("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: NNiels Dossche <dossche.niels@gmail.com>
Reviewed-by: NChao Yu <chao@kernel.org>
Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
上级 a7b8618a
...@@ -1707,18 +1707,23 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -1707,18 +1707,23 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
u64 id = huge_encode_dev(sb->s_bdev->bd_dev); u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
block_t total_count, user_block_count, start_count; block_t total_count, user_block_count, start_count;
u64 avail_node_count; u64 avail_node_count;
unsigned int total_valid_node_count;
total_count = le64_to_cpu(sbi->raw_super->block_count); total_count = le64_to_cpu(sbi->raw_super->block_count);
user_block_count = sbi->user_block_count;
start_count = le32_to_cpu(sbi->raw_super->segment0_blkaddr); start_count = le32_to_cpu(sbi->raw_super->segment0_blkaddr);
buf->f_type = F2FS_SUPER_MAGIC; buf->f_type = F2FS_SUPER_MAGIC;
buf->f_bsize = sbi->blocksize; buf->f_bsize = sbi->blocksize;
buf->f_blocks = total_count - start_count; buf->f_blocks = total_count - start_count;
spin_lock(&sbi->stat_lock);
user_block_count = sbi->user_block_count;
total_valid_node_count = valid_node_count(sbi);
avail_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
buf->f_bfree = user_block_count - valid_user_blocks(sbi) - buf->f_bfree = user_block_count - valid_user_blocks(sbi) -
sbi->current_reserved_blocks; sbi->current_reserved_blocks;
spin_lock(&sbi->stat_lock);
if (unlikely(buf->f_bfree <= sbi->unusable_block_count)) if (unlikely(buf->f_bfree <= sbi->unusable_block_count))
buf->f_bfree = 0; buf->f_bfree = 0;
else else
...@@ -1731,14 +1736,12 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -1731,14 +1736,12 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
else else
buf->f_bavail = 0; buf->f_bavail = 0;
avail_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
if (avail_node_count > user_block_count) { if (avail_node_count > user_block_count) {
buf->f_files = user_block_count; buf->f_files = user_block_count;
buf->f_ffree = buf->f_bavail; buf->f_ffree = buf->f_bavail;
} else { } else {
buf->f_files = avail_node_count; buf->f_files = avail_node_count;
buf->f_ffree = min(avail_node_count - valid_node_count(sbi), buf->f_ffree = min(avail_node_count - total_valid_node_count,
buf->f_bavail); buf->f_bavail);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册