Message ID | 20240110091009.138206-1-frank.li@vivo.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [f2fs-dev] f2fs: compress: reserve blocks on released compress inode while writing | expand |
Ping......
On 2024/1/10 17:10, Yangtao Li wrote: > Reserve blocks on released compress inode while writing, so > compressed files with released space are allowed to be rewritten. > > Signed-off-by: Yangtao Li <frank.li@vivo.com> > --- > fs/f2fs/file.c | 86 ++++++++++++++++++++++++++++++-------------------- > 1 file changed, 51 insertions(+), 35 deletions(-) > > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c > index 15dabeac4690..749b5af17141 100644 > --- a/fs/f2fs/file.c > +++ b/fs/f2fs/file.c > @@ -3612,39 +3612,15 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) > return reserved_blocks; > } > > -static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) > +static int f2fs_reserve_file(struct inode *inode, unsigned int *blocks) f2fs_do_reserve_compress_blocks()? > { > - struct inode *inode = file_inode(filp); > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > pgoff_t page_idx = 0, last_idx; > unsigned int reserved_blocks = 0; > int ret; > > - if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) > - return -EOPNOTSUPP; > - > - if (!f2fs_compressed_file(inode)) > - return -EINVAL; > - > - if (f2fs_readonly(sbi->sb)) > - return -EROFS; > - > - ret = mnt_want_write_file(filp); > - if (ret) > - return ret; > - > - if (atomic_read(&F2FS_I(inode)->i_compr_blocks)) > - goto out; > - > f2fs_balance_fs(F2FS_I_SB(inode), true); > > - inode_lock(inode); > - > - if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { > - ret = -EINVAL; > - goto unlock_inode; > - } > - > f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); > filemap_invalidate_lock(inode->i_mapping); > > @@ -3688,14 +3664,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) > clear_inode_flag(inode, FI_COMPRESS_RELEASED); > inode->i_ctime = current_time(inode); > f2fs_mark_inode_dirty_sync(inode, true); > - } > -unlock_inode: > - inode_unlock(inode); > -out: > - mnt_drop_write_file(filp); > - > - if (ret >= 0) { > - ret = put_user(reserved_blocks, (u64 __user *)arg); > + if (blocks) > + *blocks = reserved_blocks; > } else if (reserved_blocks && > atomic_read(&F2FS_I(inode)->i_compr_blocks)) { > set_sbi_flag(sbi, SBI_NEED_FSCK); > @@ -3710,6 +3680,49 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) > return ret; > } > > +static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) > +{ > + struct inode *inode = file_inode(filp); > + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > + unsigned int reserved_blocks = 0; > + int ret; > + > + if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) > + return -EOPNOTSUPP; > + > + if (!f2fs_compressed_file(inode)) > + return -EINVAL; > + > + if (f2fs_readonly(sbi->sb)) > + return -EROFS; > + > + ret = mnt_want_write_file(filp); > + if (ret) > + return ret; > + > + if (atomic_read(&F2FS_I(inode)->i_compr_blocks)) > + goto out; > + > + inode_lock(inode); > + > + if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { > + ret = -EINVAL; > + goto unlock_inode; > + } > + > + ret = f2fs_reserve_file(inode, &reserved_blocks); > + > +unlock_inode: > + inode_unlock(inode); > +out: > + mnt_drop_write_file(filp); > + > + if (ret >= 0) > + ret = put_user(reserved_blocks, (u64 __user *)arg); > + > + return ret; > +} > + > static int f2fs_secure_erase(struct block_device *bdev, struct inode *inode, > pgoff_t off, block_t block, block_t len, u32 flags) > { > @@ -4412,8 +4425,11 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from) > if (IS_IMMUTABLE(inode)) > return -EPERM; > > - if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) > - return -EPERM; > + if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { > + err = f2fs_reserve_file(inode, NULL); How about reserving blocks after generic_write_checks() in f2fs_file_write_iter()? Thanks, > + if (err < 0) > + return err; > + } > > count = generic_write_checks(iocb, from); > if (count <= 0)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 15dabeac4690..749b5af17141 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3612,39 +3612,15 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) return reserved_blocks; } -static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) +static int f2fs_reserve_file(struct inode *inode, unsigned int *blocks) { - struct inode *inode = file_inode(filp); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); pgoff_t page_idx = 0, last_idx; unsigned int reserved_blocks = 0; int ret; - if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) - return -EOPNOTSUPP; - - if (!f2fs_compressed_file(inode)) - return -EINVAL; - - if (f2fs_readonly(sbi->sb)) - return -EROFS; - - ret = mnt_want_write_file(filp); - if (ret) - return ret; - - if (atomic_read(&F2FS_I(inode)->i_compr_blocks)) - goto out; - f2fs_balance_fs(F2FS_I_SB(inode), true); - inode_lock(inode); - - if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { - ret = -EINVAL; - goto unlock_inode; - } - f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping); @@ -3688,14 +3664,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) clear_inode_flag(inode, FI_COMPRESS_RELEASED); inode->i_ctime = current_time(inode); f2fs_mark_inode_dirty_sync(inode, true); - } -unlock_inode: - inode_unlock(inode); -out: - mnt_drop_write_file(filp); - - if (ret >= 0) { - ret = put_user(reserved_blocks, (u64 __user *)arg); + if (blocks) + *blocks = reserved_blocks; } else if (reserved_blocks && atomic_read(&F2FS_I(inode)->i_compr_blocks)) { set_sbi_flag(sbi, SBI_NEED_FSCK); @@ -3710,6 +3680,49 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) return ret; } +static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + unsigned int reserved_blocks = 0; + int ret; + + if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) + return -EOPNOTSUPP; + + if (!f2fs_compressed_file(inode)) + return -EINVAL; + + if (f2fs_readonly(sbi->sb)) + return -EROFS; + + ret = mnt_want_write_file(filp); + if (ret) + return ret; + + if (atomic_read(&F2FS_I(inode)->i_compr_blocks)) + goto out; + + inode_lock(inode); + + if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { + ret = -EINVAL; + goto unlock_inode; + } + + ret = f2fs_reserve_file(inode, &reserved_blocks); + +unlock_inode: + inode_unlock(inode); +out: + mnt_drop_write_file(filp); + + if (ret >= 0) + ret = put_user(reserved_blocks, (u64 __user *)arg); + + return ret; +} + static int f2fs_secure_erase(struct block_device *bdev, struct inode *inode, pgoff_t off, block_t block, block_t len, u32 flags) { @@ -4412,8 +4425,11 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from) if (IS_IMMUTABLE(inode)) return -EPERM; - if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) - return -EPERM; + if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { + err = f2fs_reserve_file(inode, NULL); + if (err < 0) + return err; + } count = generic_write_checks(iocb, from); if (count <= 0)
Reserve blocks on released compress inode while writing, so compressed files with released space are allowed to be rewritten. Signed-off-by: Yangtao Li <frank.li@vivo.com> --- fs/f2fs/file.c | 86 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 35 deletions(-)