summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/f2fs.h
diff options
context:
space:
mode:
authorDaeho Jeong <daehojeong@google.com>2020-09-08 11:44:10 +0900
committerJaegeuk Kim <jaegeuk@kernel.org>2020-09-11 11:11:26 -0700
commitc2759ebaf7e8f5510d0a77bd5003a20375ea6ed5 (patch)
tree36a905fc9badb003d76fd36342f98ad33dfaf7ec /fs/f2fs/f2fs.h
parent32c0fec1aa85f1a9aebfd9445208f4223bcd96e8 (diff)
downloadlinux-c2759ebaf7e8f5510d0a77bd5003a20375ea6ed5.tar.gz
linux-c2759ebaf7e8f5510d0a77bd5003a20375ea6ed5.tar.bz2
linux-c2759ebaf7e8f5510d0a77bd5003a20375ea6ed5.zip
f2fs: change i_compr_blocks of inode to atomic value
writepages() can be concurrently invoked for the same file by different threads such as a thread fsyncing the file and a kworker kernel thread. So, changing i_compr_blocks without protection is racy and we need to protect it by changing it with atomic type value. Plus, we don't need a 64bit value for i_compr_blocks, so just we will use a atomic value, not atomic64. Signed-off-by: Daeho Jeong <daehojeong@google.com> Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/f2fs.h')
-rw-r--r--fs/f2fs/f2fs.h17
1 files changed, 10 insertions, 7 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 53fe2853579c..4a71c1215da8 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -807,7 +807,7 @@ struct f2fs_inode_info {
struct timespec64 i_disk_time[4];/* inode disk times */
/* for file compress */
- u64 i_compr_blocks; /* # of compressed blocks */
+ atomic_t i_compr_blocks; /* # of compressed blocks */
unsigned char i_compress_algorithm; /* algorithm type */
unsigned char i_log_cluster_size; /* log of cluster size */
unsigned int i_cluster_size; /* cluster size */
@@ -3963,17 +3963,19 @@ static inline void set_compress_context(struct inode *inode)
f2fs_mark_inode_dirty_sync(inode, true);
}
-static inline u64 f2fs_disable_compressed_file(struct inode *inode)
+static inline u32 f2fs_disable_compressed_file(struct inode *inode)
{
struct f2fs_inode_info *fi = F2FS_I(inode);
+ u32 i_compr_blocks;
if (!f2fs_compressed_file(inode))
return 0;
if (S_ISREG(inode->i_mode)) {
if (get_dirty_pages(inode))
return 1;
- if (fi->i_compr_blocks)
- return fi->i_compr_blocks;
+ i_compr_blocks = atomic_read(&fi->i_compr_blocks);
+ if (i_compr_blocks)
+ return i_compr_blocks;
}
fi->i_flags &= ~F2FS_COMPR_FL;
@@ -4090,16 +4092,17 @@ static inline void f2fs_i_compr_blocks_update(struct inode *inode,
u64 blocks, bool add)
{
int diff = F2FS_I(inode)->i_cluster_size - blocks;
+ struct f2fs_inode_info *fi = F2FS_I(inode);
/* don't update i_compr_blocks if saved blocks were released */
- if (!add && !F2FS_I(inode)->i_compr_blocks)
+ if (!add && !atomic_read(&fi->i_compr_blocks))
return;
if (add) {
- F2FS_I(inode)->i_compr_blocks += diff;
+ atomic_add(diff, &fi->i_compr_blocks);
stat_add_compr_blocks(inode, diff);
} else {
- F2FS_I(inode)->i_compr_blocks -= diff;
+ atomic_sub(diff, &fi->i_compr_blocks);
stat_sub_compr_blocks(inode, diff);
}
f2fs_mark_inode_dirty_sync(inode, true);