mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
f2fs: fix to avoid potential section-unaligned pinfile
Blocks of pinfile may not aligned to section size due to wrong use
on pinfile, result in heavy overhead of GC, let avoid this by
adding additional check condition in f2fs_setattr().
- truncate -s 8mb pinfile
: random checkpoint may persist filesize w/ inode
- fallocate -o 0 -l 8mb pinfile
- f2fs_fallocate
- f2fs_expand_inode_data
- f2fs_allocate_pinning_section
- f2fs_map_blocks
- f2fs_map_lock
- __allocate_data_block
- file_need_truncate
: w/ FADVISE_TRUNC_BIT, we can expect unaligned mapping can be
truncated while open() if f2fs is not umount abnormally
- f2fs_map_unlock
: following f2fs checkpoint and sudden power-cut
- mount
- open pinfile
- f2fs_file_open
- finish_preallocate_blocks
- truncate_setsize
: filesize is 8mb
- f2fs_truncate
: can only truncate block outside filesize, rather than truncating
unaligned blocks inside filesize
Fixes: f5a53edcf0 ("f2fs: support aligned pinned file")
Cc: stable@kernel.org
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
3d7bca9d58
commit
d0a481fad5
|
|
@ -1107,17 +1107,23 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
|||
!IS_ALIGNED(attr->ia_size,
|
||||
F2FS_BLK_TO_BYTES(fi->i_cluster_size)))
|
||||
return -EINVAL;
|
||||
/*
|
||||
* To prevent scattered pin block generation, we don't allow
|
||||
* smaller/equal size unaligned truncation for pinned file.
|
||||
* We only support overwrite IO to pinned file, so don't
|
||||
* care about larger size truncation.
|
||||
*/
|
||||
if (f2fs_is_pinned_file(inode) &&
|
||||
attr->ia_size <= i_size_read(inode) &&
|
||||
!IS_ALIGNED(attr->ia_size,
|
||||
F2FS_BLK_TO_BYTES(CAP_BLKS_PER_SEC(sbi))))
|
||||
return -EINVAL;
|
||||
|
||||
if (f2fs_is_pinned_file(inode)) {
|
||||
/*
|
||||
* It may break section-aligned fallocate recovery
|
||||
* mechanism, so do not allow larger size truncation.
|
||||
*/
|
||||
if (attr->ia_size > i_size_read(inode))
|
||||
return -EINVAL;
|
||||
/*
|
||||
* To prevent scattered pin block generation, we don't
|
||||
* allow smaller/equal size unaligned truncation for
|
||||
* pinned file.
|
||||
*/
|
||||
else if (!IS_ALIGNED(attr->ia_size,
|
||||
F2FS_BLK_TO_BYTES(CAP_BLKS_PER_SEC(sbi))))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_quota_modification(idmap, inode, attr)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user