Re: [f2fs-dev] [PATCH V2 2/2] f2fs: compress: fix reserve_cblocks counting error when out of space
On 2024/3/6 11:47, Xiuhong Wang wrote: When a file only needs one direct_node, performing the following operations will cause the file to be unrepairable: unisoc # ./f2fs_io compress test.apk unisoc #df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.2M 100% /data unisoc # ./f2fs_io release_cblocks test.apk 924 unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 4.8M 100% /data unisoc # dd if=/dev/random of=file4 bs=1M count=3 3145728 bytes (3.0 M) copied, 0.025 s, 120 M/s unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 0 This is because the file has only one direct_node. After returning to -ENOSPC, reserved_blocks += ret will not be executed. As a result, the reserved_blocks at this time is still 0, which is not the real number of reserved blocks. Therefore, fsck cannot be set to repair the file. After this patch, the fsck flag will be set to fix this problem. unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot then fsck will be executed unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 924 Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu Reviewed-by: Chao Yu Thanks, ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH V2 1/2] f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks
On 2024/3/6 11:47, Xiuhong Wang wrote: The following f2fs_io test will get a "0" result instead of -EINVAL, unisoc # ./f2fs_io compress file unisoc # ./f2fs_io reserve_cblocks file 0 it's not reasonable, so the judgement of atomic_read(_I(inode)->i_compr_blocks) should be placed after the judgement of is_inode_flag_set(inode, FI_COMPRESS_RELEASED). Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu Reviewed-by: Chao Yu Thanks, ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH V2 2/2] f2fs: compress: fix reserve_cblocks counting error when out of space
When a file only needs one direct_node, performing the following operations will cause the file to be unrepairable: unisoc # ./f2fs_io compress test.apk unisoc #df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.2M 100% /data unisoc # ./f2fs_io release_cblocks test.apk 924 unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 4.8M 100% /data unisoc # dd if=/dev/random of=file4 bs=1M count=3 3145728 bytes (3.0 M) copied, 0.025 s, 120 M/s unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 0 This is because the file has only one direct_node. After returning to -ENOSPC, reserved_blocks += ret will not be executed. As a result, the reserved_blocks at this time is still 0, which is not the real number of reserved blocks. Therefore, fsck cannot be set to repair the file. After this patch, the fsck flag will be set to fix this problem. unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot then fsck will be executed unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 924 Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu --- fs/f2fs/file.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 74c5e48fce22..dc9c6bac678d 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3624,10 +3624,10 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) return ret; } -static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) +static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count, + unsigned int *reserved_blocks) { struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); - unsigned int reserved_blocks = 0; int cluster_size = F2FS_I(dn->inode)->i_cluster_size; block_t blkaddr; int i; @@ -3691,12 +3691,12 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true); - reserved_blocks += reserved; + *reserved_blocks += reserved; next: count -= cluster_size; } - return reserved_blocks; + return 0; } static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) @@ -3757,7 +3757,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) count = min(end_offset - dn.ofs_in_node, last_idx - page_idx); count = round_up(count, F2FS_I(inode)->i_cluster_size); - ret = reserve_compress_blocks(, count); + ret = reserve_compress_blocks(, count, _blocks); f2fs_put_dnode(); @@ -3765,13 +3765,12 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) break; page_idx += count; - reserved_blocks += ret; } filemap_invalidate_unlock(inode->i_mapping); f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]); - if (ret >= 0) { + if (!ret) { clear_inode_flag(inode, FI_COMPRESS_RELEASED); inode_set_ctime_current(inode); f2fs_mark_inode_dirty_sync(inode, true); @@ -3780,7 +3779,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) inode_unlock(inode); mnt_drop_write_file(filp); - if (ret >= 0) { + if (!ret) { ret = put_user(reserved_blocks, (u64 __user *)arg); } else if (reserved_blocks && atomic_read(_I(inode)->i_compr_blocks)) { -- 2.25.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH V2 1/2] f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks
The following f2fs_io test will get a "0" result instead of -EINVAL, unisoc # ./f2fs_io compress file unisoc # ./f2fs_io reserve_cblocks file 0 it's not reasonable, so the judgement of atomic_read(_I(inode)->i_compr_blocks) should be placed after the judgement of is_inode_flag_set(inode, FI_COMPRESS_RELEASED). Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu --- fs/f2fs/file.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4ca6c693b33a..74c5e48fce22 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3720,9 +3720,6 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) if (ret) return ret; - if (atomic_read(_I(inode)->i_compr_blocks)) - goto out; - f2fs_balance_fs(sbi, true); inode_lock(inode); @@ -3732,6 +3729,9 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) goto unlock_inode; } + if (atomic_read(_I(inode)->i_compr_blocks)) + goto unlock_inode; + f2fs_down_write(_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping); @@ -3778,7 +3778,6 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) } unlock_inode: inode_unlock(inode); -out: mnt_drop_write_file(filp); if (ret >= 0) { -- 2.25.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH v2] f2fs: add a proc entry show disk map
On 2024/3/6 7:28, Jaegeuk Kim wrote: This patch adds the disk map of block address ranges configured by multiple partitions. Signed-off-by: Jaegeuk Kim Reviewed-by: Chao Yu Thanks, ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH] f2fs-tools: deal with permission denial on non-root user
On 2024/3/6 4:48, Jaegeuk Kim wrote: This fixes some android build failures due to the missing permission when checking the loop device. Until we get a better solution, let's ignore the error with warnings. Signed-off-by: Jaegeuk Kim Reviewed-by: Chao Yu Thanks, ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 2/2] f2fs: compress: fix reserve_cblocks counting error when out of space
On 2024/3/5 16:40, Xiuhong Wang wrote: When a file only needs one direct_node, performing the following operations will cause the file to be unrepairable: unisoc # ./f2fs_io compress test.apk unisoc #df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.2M 100% /data unisoc # ./f2fs_io release_cblocks test.apk 924 unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 4.8M 100% /data unisoc # dd if=/dev/random of=file4 bs=1M count=3 3145728 bytes (3.0 M) copied, 0.025 s, 120 M/s unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 0 This is because the file has only one direct_node. After returning to -ENOSPC, reserved_blocks += ret will not be executed. As a result, the reserved_blocks at this time is still 0, which is not the real number of reserved blocks. Therefore, fsck cannot be set to repair the file. After this patch, the fsck flag will be set to fix this problem. unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot then fsck will be executed unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 924 Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu --- fs/f2fs/file.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 572d7bd4d161..97a7233c7ea7 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3624,10 +3624,10 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) return ret; } -static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) +static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count, + unsigned int *reserved_blocks) { struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); - unsigned int reserved_blocks = 0; int cluster_size = F2FS_I(dn->inode)->i_cluster_size; block_t blkaddr; int i; @@ -3691,12 +3691,12 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true); - reserved_blocks += reserved; + *reserved_blocks += reserved; next: count -= cluster_size; } - return reserved_blocks; + return 0; } static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) @@ -3740,6 +3740,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) while (page_idx < last_idx) { struct dnode_of_data dn; pgoff_t end_offset, count; + unsigned int tmp_reserved_blocks; set_new_dnode(, inode, NULL, NULL, 0); ret = f2fs_get_dnode_of_data(, page_idx, LOOKUP_NODE); @@ -3757,7 +3758,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) count = min(end_offset - dn.ofs_in_node, last_idx - page_idx); count = round_up(count, F2FS_I(inode)->i_cluster_size); - ret = reserve_compress_blocks(, count); + ret = reserve_compress_blocks(, count, _reserved_blocks); How about passing _blocks into reserve_compress_blocks()? Thanks, + reserved_blocks += tmp_reserved_blocks; f2fs_put_dnode(); @@ -3765,13 +3767,12 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) break; page_idx += count; - reserved_blocks += ret; } filemap_invalidate_unlock(inode->i_mapping); f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]); - if (ret >= 0) { + if (!ret) { clear_inode_flag(inode, FI_COMPRESS_RELEASED); inode_set_ctime_current(inode); f2fs_mark_inode_dirty_sync(inode, true); @@ -3780,7 +3781,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) inode_unlock(inode); mnt_drop_write_file(filp); - if (ret >= 0) { + if (!ret) { ret = put_user(reserved_blocks, (u64 __user *)arg); } else if (reserved_blocks && atomic_read(_I(inode)->i_compr_blocks)) { ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 1/2] f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks
On 2024/3/5 16:40, Xiuhong Wang wrote: The following f2fs_io test will get a "0" result instead of -EINVAL, unisoc # ./f2fs_io compress file unisoc # ./f2fs_io reserve_cblocks file 0 it's not reasonable, so the judgement of atomic_read(_I(inode)->i_compr_blocks) should be placed after the judgement of is_inode_flag_set(inode, FI_COMPRESS_RELEASED). Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu --- fs/f2fs/file.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4ca6c693b33a..572d7bd4d161 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3720,18 +3720,18 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) if (ret) return ret; - if (atomic_read(_I(inode)->i_compr_blocks)) - goto out; - f2fs_balance_fs(sbi, true); inode_lock(inode); if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { ret = -EINVAL; - goto unlock_inode; Nitpick, maybe keep unlock_inode label is better. + goto out; } + if (atomic_read(_I(inode)->i_compr_blocks)) + goto out; goto unlock_inode Thanks, + f2fs_down_write(_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping); @@ -3776,9 +3776,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) inode_set_ctime_current(inode); f2fs_mark_inode_dirty_sync(inode, true); } -unlock_inode: - inode_unlock(inode); out: + inode_unlock(inode); mnt_drop_write_file(filp); if (ret >= 0) { ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
On 2024/3/5 16:09, Roman Smirnov wrote: Cast expression type to unsigned long in __count_extent_cache() to prevent integer overflow. Found by Linux Verification Center (linuxtesting.org) with Svace. Signed-off-by: Roman Smirnov Reviewed-by: Sergey Shtylyov Reviewed-by: Chao Yu Thanks, --- fs/f2fs/shrinker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c index 83d6fb97dcae..bb86a06c5d5e 100644 --- a/fs/f2fs/shrinker.c +++ b/fs/f2fs/shrinker.c @@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi, { struct extent_tree_info *eti = >extent_tree[type]; - return atomic_read(>total_zombie_tree) + + return (unsigned long)atomic_read(>total_zombie_tree) + atomic_read(>total_ext_node); } ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [External Mail] [PATCH] f2fs-tools: deal with permission denial on non-root user
Reviewed-by: Huang Jianan Thanks. On 2024/3/6 4:48, Jaegeuk Kim wrote: > This fixes some android build failures due to the missing permission when > checking the loop device. Until we get a better solution, let's ignore > the error with warnings. > > Signed-off-by: Jaegeuk Kim > --- > lib/libf2fs.c | 12 +--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/lib/libf2fs.c b/lib/libf2fs.c > index d51e485361ee..1cfbf31a9c85 100644 > --- a/lib/libf2fs.c > +++ b/lib/libf2fs.c > @@ -854,9 +854,15 @@ int f2fs_dev_is_umounted(char *path) > > loop_fd = open(mnt->mnt_fsname, O_RDONLY); > if (loop_fd < 0) { > + /* non-root users have no permission */ > + if (errno == EPERM || errno == EACCES) { > + MSG(0, "Info: open %s failed errno:%d > - be careful to overwrite a mounted loopback file.\n", > + mnt->mnt_fsname, > errno); > + return 0; > + } > MSG(0, "Info: open %s failed errno:%d\n", > - mnt->mnt_fsname, errno); > - return -1; > + mnt->mnt_fsname, > errno); > + return -errno; > } > > err = ioctl(loop_fd, LOOP_GET_STATUS64, ); > @@ -864,7 +870,7 @@ int f2fs_dev_is_umounted(char *path) > if (err < 0) { > MSG(0, "\tError: ioctl LOOP_GET_STATUS64 > failed errno:%d!\n", > errno); > - return -1; > + return -errno; > } > > if (st_buf.st_dev == loopinfo.lo_device && > -- > 2.44.0.278.ge034bb2e1d-goog > > > > ___ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH] f2fs-tools: deal with permission denial on non-root user
Reviewed-by: Daeho Jeong On Tue, Mar 5, 2024 at 12:50 PM Jaegeuk Kim wrote: > > This fixes some android build failures due to the missing permission when > checking the loop device. Until we get a better solution, let's ignore > the error with warnings. > > Signed-off-by: Jaegeuk Kim > --- > lib/libf2fs.c | 12 +--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/lib/libf2fs.c b/lib/libf2fs.c > index d51e485361ee..1cfbf31a9c85 100644 > --- a/lib/libf2fs.c > +++ b/lib/libf2fs.c > @@ -854,9 +854,15 @@ int f2fs_dev_is_umounted(char *path) > > loop_fd = open(mnt->mnt_fsname, O_RDONLY); > if (loop_fd < 0) { > + /* non-root users have no permission */ > + if (errno == EPERM || errno == EACCES) { > + MSG(0, "Info: open %s failed errno:%d > - be careful to overwrite a mounted loopback file.\n", > + mnt->mnt_fsname, > errno); > + return 0; > + } > MSG(0, "Info: open %s failed errno:%d\n", > - mnt->mnt_fsname, errno); > - return -1; > + mnt->mnt_fsname, > errno); > + return -errno; > } > > err = ioctl(loop_fd, LOOP_GET_STATUS64, ); > @@ -864,7 +870,7 @@ int f2fs_dev_is_umounted(char *path) > if (err < 0) { > MSG(0, "\tError: ioctl LOOP_GET_STATUS64 > failed errno:%d!\n", > errno); > - return -1; > + return -errno; > } > > if (st_buf.st_dev == loopinfo.lo_device && > -- > 2.44.0.278.ge034bb2e1d-goog > > > > ___ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH v2] f2fs: add a proc entry show disk map
This patch adds the disk map of block address ranges configured by multiple partitions. Signed-off-by: Jaegeuk Kim --- from v1: - add more layout information fs/f2fs/sysfs.c | 46 ++ 1 file changed, 46 insertions(+) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 10f308b3128f..a568ce96cf56 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -1492,6 +1492,50 @@ static int __maybe_unused discard_plist_seq_show(struct seq_file *seq, return 0; } +static int __maybe_unused disk_map_seq_show(struct seq_file *seq, + void *offset) +{ + struct super_block *sb = seq->private; + struct f2fs_sb_info *sbi = F2FS_SB(sb); + int i; + + seq_printf(seq, "Address Layout : %5luB Block address (# of Segments)\n", + F2FS_BLKSIZE); + seq_printf(seq, " SB: %12s\n", "0/1024B"); + seq_printf(seq, " seg0_blkaddr : 0x%010x\n", SEG0_BLKADDR(sbi)); + seq_printf(seq, " Checkpoint: 0x%010x (%10d)\n", + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr), 2); + seq_printf(seq, " SIT : 0x%010x (%10d)\n", + SIT_I(sbi)->sit_base_addr, + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_sit)); + seq_printf(seq, " NAT : 0x%010x (%10d)\n", + NM_I(sbi)->nat_blkaddr, + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_nat)); + seq_printf(seq, " SSA : 0x%010x (%10d)\n", + SM_I(sbi)->ssa_blkaddr, + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_ssa)); + seq_printf(seq, " Main : 0x%010x (%10d)\n", + SM_I(sbi)->main_blkaddr, + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count_main)); + seq_printf(seq, " # of Sections : %12d\n", + le32_to_cpu(F2FS_RAW_SUPER(sbi)->section_count)); + seq_printf(seq, " Segs/Sections : %12d\n", + SEGS_PER_SEC(sbi)); + seq_printf(seq, " Section size : %12d MB\n", + SEGS_PER_SEC(sbi) << 1); + + if (!f2fs_is_multi_device(sbi)) + return 0; + + seq_puts(seq, "\nDisk Map for multi devices:\n"); + for (i = 0; i < sbi->s_ndevs; i++) + seq_printf(seq, "Disk:%2d (zoned=%d): 0x%010x - 0x%010x on %s\n", + i, bdev_is_zoned(FDEV(i).bdev), + FDEV(i).start_blk, FDEV(i).end_blk, + FDEV(i).path); + return 0; +} + int __init f2fs_init_sysfs(void) { int ret; @@ -1573,6 +1617,8 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi) victim_bits_seq_show, sb); proc_create_single_data("discard_plist_info", 0444, sbi->s_proc, discard_plist_seq_show, sb); + proc_create_single_data("disk_map", 0444, sbi->s_proc, + disk_map_seq_show, sb); return 0; put_feature_list_kobj: kobject_put(>s_feature_list_kobj); -- 2.44.0.278.ge034bb2e1d-goog ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [External Mail]Re: [PATCH v3] f2fs-tools: fix to check loop device for non-root users
On 03/01, 黄佳男 wrote: > On 2024/3/1 16:39, Juhyung Park wrote: > > [外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给mi...@xiaomi.com进行反馈 > > > > Hi Huang and Chao. > > > > I feel like this special loopback handling alongside Chao's > > 14197d546b93 on f2fs-tools is just unnecessarily complicating the code > > flow. > > We're now doing what, lookup to /sys, parse original backing file, > > remove trailing newline char, stat()'ing it to make sure it exists? > > Indeed this is not a good approach. > > > What if the stat()'ed file is a new file after the original backing > > file has been deleted? > > > > Being able to overwrite an active loopback backing file is a semantic > > that Linux provides willingly. > > O_EXCL only works on block devices and it's a POSIX guarantee that > > multiple writers can work on a regular file. > > > > IMHO we should honor that, but if we really want to prevent this akin > > to e2fsprogs, we should be using mntent like e2fsprogs. > > e2fsprogs will continue to check if opening the loop device fails, > rather than > > exiting. This way non-root users can use mkfs/fsck normally, although there > > may be overwrite issues. I think we need to fix this first and try to find a better way. https://lore.kernel.org/linux-f2fs-devel/20240305204834.101697-1-jaeg...@kernel.org/T/#u > > > Thanks, > > Jianan > > > On Fri, Mar 1, 2024 at 4:15 PM Huang Jianan via Linux-f2fs-devel > > wrote: > >> Currently mkfs/fsck gets the following error when executed by > >> non-root users: > >> > >> Info: open /dev/loop0 failed errno:13 > >> Error: Not available on mounted device! > >> > >> Let's fix it by reading the backing file from sysfs. > >> > >> Fixes: 14197d546b93 ("f2fs-tools: fix to check loop device") > >> Signed-off-by: Huang Jianan > >> --- > >> v3: > >> - Skip deleted backing file. > >> lib/libf2fs.c | 40 +++- > >> 1 file changed, 27 insertions(+), 13 deletions(-) > >> > >> diff --git a/lib/libf2fs.c b/lib/libf2fs.c > >> index d51e485..fad3fd4 100644 > >> --- a/lib/libf2fs.c > >> +++ b/lib/libf2fs.c > >> @@ -832,7 +832,7 @@ int f2fs_dev_is_umounted(char *path) > >> } > >> } else if (S_ISREG(st_buf.st_mode)) { > >> /* check whether regular is backfile of loop device */ > >> -#if defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H) > >> +#if defined(HAVE_LINUX_MAJOR_H) > >> struct mntent *mnt; > >> struct stat st_loop; > >> FILE *f; > >> @@ -840,8 +840,9 @@ int f2fs_dev_is_umounted(char *path) > >> f = setmntent("/proc/mounts", "r"); > >> > >> while ((mnt = getmntent(f)) != NULL) { > >> - struct loop_info64 loopinfo = {0, }; > >> - int loop_fd, err; > >> + struct stat st_back; > >> + int sysfs_fd, rc; > >> + char buf[PATH_MAX + 1]; > >> > >> if (mnt->mnt_fsname[0] != '/') > >> continue; > >> @@ -852,23 +853,36 @@ int f2fs_dev_is_umounted(char *path) > >> if (major(st_loop.st_rdev) != LOOP_MAJOR) > >> continue; > >> > >> - loop_fd = open(mnt->mnt_fsname, O_RDONLY); > >> - if (loop_fd < 0) { > >> + snprintf(buf, PATH_MAX, > >> +"/sys/dev/block/%d:%d/loop/backing_file", > >> +major(st_loop.st_rdev), > >> minor(st_loop.st_rdev)); > >> + > >> + sysfs_fd = open(buf, O_RDONLY); > >> + if (sysfs_fd < 0) { > >> MSG(0, "Info: open %s failed errno:%d\n", > >> - mnt->mnt_fsname, errno); > >> + buf, errno); > >> return -1; > >> } > >> > >> - err = ioctl(loop_fd, LOOP_GET_STATUS64, ); > >> - close(loop_fd); > >> - if (err < 0) { > >> - MSG(0, "\tError: ioctl LOOP_GET_STATUS64 > >> failed errno:%d!\n", > >> - errno); > >> + memset(buf, 0, PATH_MAX + 1); > >> + rc = read(sysfs_fd, buf, PATH_MAX); > >> + if (rc < 0) { > >> + MSG(0, "Info: read %s failed errno:%d\n", > >> + buf, errno); > >> return -1; > >> } > >> > >> - if (st_buf.st_dev == loopinfo.lo_device && > >> - st_buf.st_ino == loopinfo.lo_inode) { > >> + /* Remove trailing newline */ > >> + if
[f2fs-dev] [PATCH] f2fs-tools: deal with permission denial on non-root user
This fixes some android build failures due to the missing permission when checking the loop device. Until we get a better solution, let's ignore the error with warnings. Signed-off-by: Jaegeuk Kim --- lib/libf2fs.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/libf2fs.c b/lib/libf2fs.c index d51e485361ee..1cfbf31a9c85 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -854,9 +854,15 @@ int f2fs_dev_is_umounted(char *path) loop_fd = open(mnt->mnt_fsname, O_RDONLY); if (loop_fd < 0) { + /* non-root users have no permission */ + if (errno == EPERM || errno == EACCES) { + MSG(0, "Info: open %s failed errno:%d - be careful to overwrite a mounted loopback file.\n", + mnt->mnt_fsname, errno); + return 0; + } MSG(0, "Info: open %s failed errno:%d\n", - mnt->mnt_fsname, errno); - return -1; + mnt->mnt_fsname, errno); + return -errno; } err = ioctl(loop_fd, LOOP_GET_STATUS64, ); @@ -864,7 +870,7 @@ int f2fs_dev_is_umounted(char *path) if (err < 0) { MSG(0, "\tError: ioctl LOOP_GET_STATUS64 failed errno:%d!\n", errno); - return -1; + return -errno; } if (st_buf.st_dev == loopinfo.lo_device && -- 2.44.0.278.ge034bb2e1d-goog ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v13 5/9] f2fs: Reuse generic_ci_match for ci comparisons
From: Gabriel Krisman Bertazi Now that ci_match is part of libfs, make f2fs reuse it instead of having a different implementation. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Eugen Hristev --- fs/f2fs/dir.c | 58 --- 1 file changed, 4 insertions(+), 54 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 266279b82afc..0601b4c8bacc 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -183,58 +183,6 @@ static struct f2fs_dir_entry *find_in_block(struct inode *dir, return f2fs_find_target_dentry(, fname, max_slots); } -#if IS_ENABLED(CONFIG_UNICODE) -/* - * Test whether a case-insensitive directory entry matches the filename - * being searched for. - * - * Returns 1 for a match, 0 for no match, and -errno on an error. - */ -static int f2fs_match_ci_name(const struct inode *dir, const struct qstr *name, - const u8 *de_name, u32 de_name_len) -{ - const struct super_block *sb = dir->i_sb; - const struct unicode_map *um = sb->s_encoding; - struct fscrypt_str decrypted_name = FSTR_INIT(NULL, de_name_len); - struct qstr entry = QSTR_INIT(de_name, de_name_len); - int res; - - if (IS_ENCRYPTED(dir)) { - const struct fscrypt_str encrypted_name = - FSTR_INIT((u8 *)de_name, de_name_len); - - if (WARN_ON_ONCE(!fscrypt_has_encryption_key(dir))) - return -EINVAL; - - decrypted_name.name = kmalloc(de_name_len, GFP_KERNEL); - if (!decrypted_name.name) - return -ENOMEM; - res = fscrypt_fname_disk_to_usr(dir, 0, 0, _name, - _name); - if (res < 0) - goto out; - entry.name = decrypted_name.name; - entry.len = decrypted_name.len; - } - - res = utf8_strncasecmp_folded(um, name, ); - /* -* In strict mode, ignore invalid names. In non-strict mode, -* fall back to treating them as opaque byte sequences. -*/ - if (res < 0 && !sb_has_strict_encoding(sb)) { - res = name->len == entry.len && - memcmp(name->name, entry.name, name->len) == 0; - } else { - /* utf8_strncasecmp_folded returns 0 on match */ - res = (res == 0); - } -out: - kfree(decrypted_name.name); - return res; -} -#endif /* CONFIG_UNICODE */ - static inline int f2fs_match_name(const struct inode *dir, const struct f2fs_filename *fname, const u8 *de_name, u32 de_name_len) @@ -243,8 +191,10 @@ static inline int f2fs_match_name(const struct inode *dir, #if IS_ENABLED(CONFIG_UNICODE) if (fname->cf_name.name) - return f2fs_match_ci_name(dir, >cf_name, - de_name, de_name_len); + return generic_ci_match(dir, fname->usr_fname, + >cf_name, + de_name, de_name_len); + #endif f.usr_fname = fname->usr_fname; f.disk_name = fname->disk_name; -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v13 9/9] f2fs: Move CONFIG_UNICODE defguards into the code flow
From: Gabriel Krisman Bertazi Instead of a bunch of ifdefs, make the unicode built checks part of the code flow where possible, as requested by Torvalds. Signed-off-by: Gabriel Krisman Bertazi [eugen.hris...@collabora.com: port to 6.8-rc3] Signed-off-by: Eugen Hristev --- fs/f2fs/namei.c | 10 -- fs/f2fs/super.c | 8 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index f7f63a567d86..5da1aae7d23a 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -576,8 +576,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, goto out_iput; } out_splice: -#if IS_ENABLED(CONFIG_UNICODE) - if (!inode && IS_CASEFOLDED(dir)) { + if (IS_ENABLED(CONFIG_UNICODE) && !inode && IS_CASEFOLDED(dir)) { /* Eventually we want to call d_add_ci(dentry, NULL) * for negative dentries in the encoding case as * well. For now, prevent the negative dentry @@ -586,7 +585,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, trace_f2fs_lookup_end(dir, dentry, ino, err); return NULL; } -#endif + new = d_splice_alias(inode, dentry); trace_f2fs_lookup_end(dir, !IS_ERR_OR_NULL(new) ? new : dentry, ino, IS_ERR(new) ? PTR_ERR(new) : err); @@ -639,16 +638,15 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) f2fs_delete_entry(de, page, dir, inode); f2fs_unlock_op(sbi); -#if IS_ENABLED(CONFIG_UNICODE) /* VFS negative dentries are incompatible with Encoding and * Case-insensitiveness. Eventually we'll want avoid * invalidating the dentries here, alongside with returning the * negative dentries at f2fs_lookup(), when it is better * supported by the VFS for the CI case. */ - if (IS_CASEFOLDED(dir)) + if (IS_ENABLED(CONFIG_UNICODE) && IS_CASEFOLDED(dir)) d_invalidate(dentry); -#endif + if (IS_DIRSYNC(dir)) f2fs_sync_fs(sbi->sb, 1); fail: diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 313024f5c90c..c4325cc066c6 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -306,7 +306,7 @@ struct kmem_cache *f2fs_cf_name_slab; static int __init f2fs_create_casefold_cache(void) { f2fs_cf_name_slab = f2fs_kmem_cache_create("f2fs_casefolded_name", - F2FS_NAME_LEN); + F2FS_NAME_LEN); return f2fs_cf_name_slab ? 0 : -ENOMEM; } @@ -1354,13 +1354,13 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) return -EINVAL; } #endif -#if !IS_ENABLED(CONFIG_UNICODE) - if (f2fs_sb_has_casefold(sbi)) { + + if (!IS_ENABLED(CONFIG_UNICODE) && f2fs_sb_has_casefold(sbi)) { f2fs_err(sbi, "Filesystem with casefold feature cannot be mounted without CONFIG_UNICODE"); return -EINVAL; } -#endif + /* * The BLKZONED feature indicates that the drive was formatted with * zone alignment optimization. This is optional for host-aware -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v13 0/9] Cache insensitive cleanup for ext4/f2fs
Hello, I am trying to respin the series here : https://www.spinics.net/lists/linux-ext4/msg85081.html I resent some of the v9 patches and got some reviews from Gabriel, I did changes as requested and here is v13. Changes in v13: - removed stray wrong line in 2/8 - removed old R-b as it's too long since they were given - removed check for null buff in 2/8 - added new patch `f2fs: Log error when lookup of encoded dentry fails` as suggested - rebased on unicode.git for-next branch Changes in v12: - revert to v10 comparison with propagating the error code from utf comparison Changes in v11: - revert to the original v9 implementation for the comparison helper. Changes in v10: - reworked a bit the comparison helper to improve performance by first performing the exact lookup. * Original commit letter The case-insensitive implementations in f2fs and ext4 have quite a bit of duplicated code. This series simplifies the ext4 version, with the goal of extracting ext4_ci_compare into a helper library that can be used by both filesystems. It also reduces the clutter from many codeguards for CONFIG_UNICODE; as requested by Linus, they are part of the codeflow now. While there, I noticed we can leverage the utf8 functions to detect encoded names that are corrupted in the filesystem. Therefore, it also adds an ext4 error on that scenario, to mark the filesystem as corrupted. This series survived passes of xfstests -g quick. Eugen Hristev (1): f2fs: Log error when lookup of encoded dentry fails Gabriel Krisman Bertazi (8): ext4: Simplify the handling of cached insensitive names f2fs: Simplify the handling of cached insensitive names libfs: Introduce case-insensitive string comparison helper ext4: Reuse generic_ci_match for ci comparisons f2fs: Reuse generic_ci_match for ci comparisons ext4: Log error when lookup of encoded dentry fails ext4: Move CONFIG_UNICODE defguards into the code flow f2fs: Move CONFIG_UNICODE defguards into the code flow fs/ext4/crypto.c | 19 ++- fs/ext4/ext4.h | 35 +++- fs/ext4/namei.c| 129 - fs/ext4/super.c| 4 +- fs/f2fs/dir.c | 112 ++- fs/f2fs/f2fs.h | 16 +- fs/f2fs/namei.c| 10 ++-- fs/f2fs/recovery.c | 5 +- fs/f2fs/super.c| 8 +-- fs/libfs.c | 81 include/linux/fs.h | 4 ++ 11 files changed, 219 insertions(+), 204 deletions(-) -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v13 3/9] libfs: Introduce case-insensitive string comparison helper
From: Gabriel Krisman Bertazi generic_ci_match can be used by case-insensitive filesystems to compare strings under lookup with dirents in a case-insensitive way. This function is currently reimplemented by each filesystem supporting casefolding, so this reduces code duplication in filesystem-specific code. Signed-off-by: Gabriel Krisman Bertazi [eugen.hris...@collabora.com: rework to first test the exact match] Signed-off-by: Eugen Hristev --- fs/libfs.c | 81 ++ include/linux/fs.h | 4 +++ 2 files changed, 85 insertions(+) diff --git a/fs/libfs.c b/fs/libfs.c index c297953db948..c107c24f33b9 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1776,6 +1776,87 @@ static const struct dentry_operations generic_ci_dentry_ops = { .d_revalidate = fscrypt_d_revalidate, #endif }; + +/** + * generic_ci_match() - Match a name (case-insensitively) with a dirent. + * This is a filesystem helper for comparison with directory entries. + * generic_ci_d_compare should be used in VFS' ->d_compare instead. + * + * @parent: Inode of the parent of the dirent under comparison + * @name: name under lookup. + * @folded_name: Optional pre-folded name under lookup + * @de_name: Dirent name. + * @de_name_len: dirent name length. + * + * Test whether a case-insensitive directory entry matches the filename + * being searched. If @folded_name is provided, it is used instead of + * recalculating the casefold of @name. + * + * Return: > 0 if the directory entry matches, 0 if it doesn't match, or + * < 0 on error. + */ +int generic_ci_match(const struct inode *parent, +const struct qstr *name, +const struct qstr *folded_name, +const u8 *de_name, u32 de_name_len) +{ + const struct super_block *sb = parent->i_sb; + const struct unicode_map *um = sb->s_encoding; + struct fscrypt_str decrypted_name = FSTR_INIT(NULL, de_name_len); + struct qstr dirent = QSTR_INIT(de_name, de_name_len); + int res, match = 0; + + if (IS_ENCRYPTED(parent)) { + const struct fscrypt_str encrypted_name = + FSTR_INIT((u8 *) de_name, de_name_len); + + if (WARN_ON_ONCE(!fscrypt_has_encryption_key(parent))) + return -EINVAL; + + decrypted_name.name = kmalloc(de_name_len, GFP_KERNEL); + if (!decrypted_name.name) + return -ENOMEM; + res = fscrypt_fname_disk_to_usr(parent, 0, 0, _name, + _name); + if (res < 0) + goto out; + dirent.name = decrypted_name.name; + dirent.len = decrypted_name.len; + } + + /* +* Attempt a case-sensitive match first. It is cheaper and +* should cover most lookups, including all the sane +* applications that expect a case-sensitive filesystem. +*/ + if (folded_name->name) { + if (dirent.len == folded_name->len && + !memcmp(folded_name->name, dirent.name, dirent.len)) { + match = 1; + goto out; + } + res = utf8_strncasecmp_folded(um, folded_name, ); + } else { + if (dirent.len == name->len && + !memcmp(name->name, dirent.name, dirent.len) && + (!sb_has_strict_encoding(sb) || !utf8_validate(um, name))) { + match = 1; + goto out; + } + res = utf8_strncasecmp(um, name, ); + } + +out: + kfree(decrypted_name.name); + if (match) /* matched by direct comparison */ + return 1; + else if (!res) /* matched by utf8 comparison */ + return 1; + else if (res < 0) /* error on utf8 comparison */ + return res; + return 0; /* no match */ +} +EXPORT_SYMBOL(generic_ci_match); #endif #ifdef CONFIG_FS_ENCRYPTION diff --git a/include/linux/fs.h b/include/linux/fs.h index ff1338109b54..690b37e1db95 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3281,6 +3281,10 @@ extern int generic_file_fsync(struct file *, loff_t, loff_t, int); extern int generic_check_addressable(unsigned, u64); extern void generic_set_sb_d_ops(struct super_block *sb); +extern int generic_ci_match(const struct inode *parent, + const struct qstr *name, + const struct qstr *folded_name, + const u8 *de_name, u32 de_name_len); static inline bool sb_has_encoding(const struct super_block *sb) { -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v13 7/9] f2fs: Log error when lookup of encoded dentry fails
If the volume is in strict mode, generi c_ci_compare can report a broken encoding name. This will not trigger on a bad lookup, which is caught earlier, only if the actual disk name is bad. Suggested-by: Gabriel Krisman Bertazi Signed-off-by: Eugen Hristev --- fs/f2fs/dir.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 0601b4c8bacc..1bb98970a56a 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -190,11 +190,22 @@ static inline int f2fs_match_name(const struct inode *dir, struct fscrypt_name f; #if IS_ENABLED(CONFIG_UNICODE) - if (fname->cf_name.name) - return generic_ci_match(dir, fname->usr_fname, - >cf_name, - de_name, de_name_len); - + if (fname->cf_name.name) { + int ret = generic_ci_match(dir, fname->usr_fname, + >cf_name, + de_name, de_name_len); + if (ret < 0) { + /* +* Treat comparison errors as not a match. The +* only case where it happens is on a disk +* corruption or ENOMEM. +*/ + if (ret == -EINVAL) + f2fs_warn(F2FS_SB(dir->i_sb), + "Directory contains filename that is invalid UTF-8"); + } + return ret; + } #endif f.usr_fname = fname->usr_fname; f.disk_name = fname->disk_name; -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v13 8/9] ext4: Move CONFIG_UNICODE defguards into the code flow
From: Gabriel Krisman Bertazi Instead of a bunch of ifdefs, make the unicode built checks part of the code flow where possible, as requested by Torvalds. Signed-off-by: Gabriel Krisman Bertazi [eugen.hris...@collabora.com: port to 6.8-rc3] Signed-off-by: Eugen Hristev --- fs/ext4/crypto.c | 19 +++ fs/ext4/ext4.h | 33 + fs/ext4/namei.c | 14 +- fs/ext4/super.c | 4 +--- 4 files changed, 30 insertions(+), 40 deletions(-) diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c index 7ae0b61258a7..1d2f8b79529c 100644 --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c @@ -31,12 +31,7 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname, ext4_fname_from_fscrypt_name(fname, ); -#if IS_ENABLED(CONFIG_UNICODE) - err = ext4_fname_setup_ci_filename(dir, iname, fname); - if (err) - ext4_fname_free_filename(fname); -#endif - return err; + return ext4_fname_setup_ci_filename(dir, iname, fname); } int ext4_fname_prepare_lookup(struct inode *dir, struct dentry *dentry, @@ -51,12 +46,7 @@ int ext4_fname_prepare_lookup(struct inode *dir, struct dentry *dentry, ext4_fname_from_fscrypt_name(fname, ); -#if IS_ENABLED(CONFIG_UNICODE) - err = ext4_fname_setup_ci_filename(dir, >d_name, fname); - if (err) - ext4_fname_free_filename(fname); -#endif - return err; + return ext4_fname_setup_ci_filename(dir, >d_name, fname); } void ext4_fname_free_filename(struct ext4_filename *fname) @@ -70,10 +60,7 @@ void ext4_fname_free_filename(struct ext4_filename *fname) fname->usr_fname = NULL; fname->disk_name.name = NULL; -#if IS_ENABLED(CONFIG_UNICODE) - kfree(fname->cf_name.name); - fname->cf_name.name = NULL; -#endif + ext4_fname_free_ci_filename(fname); } static bool uuid_is_zero(__u8 u[16]) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4061d11b9763..c68f48f706cd 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2740,8 +2740,25 @@ ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); #if IS_ENABLED(CONFIG_UNICODE) extern int ext4_fname_setup_ci_filename(struct inode *dir, -const struct qstr *iname, -struct ext4_filename *fname); + const struct qstr *iname, + struct ext4_filename *fname); + +static inline void ext4_fname_free_ci_filename(struct ext4_filename *fname) +{ + kfree(fname->cf_name.name); + fname->cf_name.name = NULL; +} +#else +static inline int ext4_fname_setup_ci_filename(struct inode *dir, + const struct qstr *iname, + struct ext4_filename *fname) +{ + return 0; +} + +static inline void ext4_fname_free_ci_filename(struct ext4_filename *fname) +{ +} #endif /* ext4 encryption related stuff goes here crypto.c */ @@ -2764,16 +2781,11 @@ static inline int ext4_fname_setup_filename(struct inode *dir, int lookup, struct ext4_filename *fname) { - int err = 0; fname->usr_fname = iname; fname->disk_name.name = (unsigned char *) iname->name; fname->disk_name.len = iname->len; -#if IS_ENABLED(CONFIG_UNICODE) - err = ext4_fname_setup_ci_filename(dir, iname, fname); -#endif - - return err; + return ext4_fname_setup_ci_filename(dir, iname, fname); } static inline int ext4_fname_prepare_lookup(struct inode *dir, @@ -2785,10 +2797,7 @@ static inline int ext4_fname_prepare_lookup(struct inode *dir, static inline void ext4_fname_free_filename(struct ext4_filename *fname) { -#if IS_ENABLED(CONFIG_UNICODE) - kfree(fname->cf_name.name); - fname->cf_name.name = NULL; -#endif + ext4_fname_free_ci_filename(fname); } static inline int ext4_ioctl_get_encryption_pwsalt(struct file *filp, diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 3268cf45d9db..a5d9e5b01015 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1834,8 +1834,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi } } -#if IS_ENABLED(CONFIG_UNICODE) - if (!inode && IS_CASEFOLDED(dir)) { + if (IS_ENABLED(CONFIG_UNICODE) && !inode && IS_CASEFOLDED(dir)) { /* Eventually we want to call d_add_ci(dentry, NULL) * for negative dentries in the encoding case as * well. For now, prevent the negative dentry @@ -1843,7 +1842,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi */ return NULL; } -#endif + return d_splice_alias(inode, dentry); } @@ -3173,16 +3172,14 @@ static int ext4_rmdir(struct inode *dir, struct
[f2fs-dev] [PATCH v13 4/9] ext4: Reuse generic_ci_match for ci comparisons
From: Gabriel Krisman Bertazi Instead of reimplementing ext4_match_ci, use the new libfs helper. It also adds a comment explaining why fname->cf_name.name must be checked prior to the encryption hash optimization, because that tripped me before. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Eugen Hristev --- fs/ext4/namei.c | 91 +++-- 1 file changed, 27 insertions(+), 64 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index b96983a4c185..2d0ee232fbe7 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1390,58 +1390,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block) } #if IS_ENABLED(CONFIG_UNICODE) -/* - * Test whether a case-insensitive directory entry matches the filename - * being searched for. If quick is set, assume the name being looked up - * is already in the casefolded form. - * - * Returns: 0 if the directory entry matches, more than 0 if it - * doesn't match or less than zero on error. - */ -static int ext4_ci_compare(const struct inode *parent, const struct qstr *name, - u8 *de_name, size_t de_name_len, bool quick) -{ - const struct super_block *sb = parent->i_sb; - const struct unicode_map *um = sb->s_encoding; - struct fscrypt_str decrypted_name = FSTR_INIT(NULL, de_name_len); - struct qstr entry = QSTR_INIT(de_name, de_name_len); - int ret; - - if (IS_ENCRYPTED(parent)) { - const struct fscrypt_str encrypted_name = - FSTR_INIT(de_name, de_name_len); - - decrypted_name.name = kmalloc(de_name_len, GFP_KERNEL); - if (!decrypted_name.name) - return -ENOMEM; - ret = fscrypt_fname_disk_to_usr(parent, 0, 0, _name, - _name); - if (ret < 0) - goto out; - entry.name = decrypted_name.name; - entry.len = decrypted_name.len; - } - - if (quick) - ret = utf8_strncasecmp_folded(um, name, ); - else - ret = utf8_strncasecmp(um, name, ); - if (ret < 0) { - /* Handle invalid character sequence as either an error -* or as an opaque byte sequence. -*/ - if (sb_has_strict_encoding(sb)) - ret = -EINVAL; - else if (name->len != entry.len) - ret = 1; - else - ret = !!memcmp(name->name, entry.name, entry.len); - } -out: - kfree(decrypted_name.name); - return ret; -} - int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname, struct ext4_filename *name) { @@ -1503,20 +1451,35 @@ static bool ext4_match(struct inode *parent, #if IS_ENABLED(CONFIG_UNICODE) if (IS_CASEFOLDED(parent) && (!IS_ENCRYPTED(parent) || fscrypt_has_encryption_key(parent))) { - if (fname->cf_name.name) { - if (IS_ENCRYPTED(parent)) { - if (fname->hinfo.hash != EXT4_DIRENT_HASH(de) || - fname->hinfo.minor_hash != - EXT4_DIRENT_MINOR_HASH(de)) { + int ret; - return false; - } - } - return !ext4_ci_compare(parent, >cf_name, - de->name, de->name_len, true); + /* +* Just checking IS_ENCRYPTED(parent) below is not +* sufficient to decide whether one can use the hash for +* skipping the string comparison, because the key might +* have been added right after +* ext4_fname_setup_ci_filename(). In this case, a hash +* mismatch will be a false negative. Therefore, make +* sure cf_name was properly initialized before +* considering the calculated hash. +*/ + if (IS_ENCRYPTED(parent) && fname->cf_name.name && + (fname->hinfo.hash != EXT4_DIRENT_HASH(de) || +fname->hinfo.minor_hash != EXT4_DIRENT_MINOR_HASH(de))) + return false; + + ret = generic_ci_match(parent, fname->usr_fname, + >cf_name, de->name, + de->name_len); + if (ret < 0) { + /* +* Treat comparison errors as not a match. The +* only case where it happens is on a disk +* corruption or ENOMEM. +*/ + return false; } -
[f2fs-dev] [PATCH v13 2/9] f2fs: Simplify the handling of cached insensitive names
From: Gabriel Krisman Bertazi Keeping it as qstr avoids the unnecessary conversion in f2fs_match Signed-off-by: Gabriel Krisman Bertazi [eugen.hris...@collabora.com: port to 6.8-rc3 and minor changes] Signed-off-by: Eugen Hristev --- fs/f2fs/dir.c | 51 +- fs/f2fs/f2fs.h | 16 ++- fs/f2fs/recovery.c | 5 + 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 042593aed1ec..266279b82afc 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -42,35 +42,47 @@ static unsigned int bucket_blocks(unsigned int level) return 4; } +#if IS_ENABLED(CONFIG_UNICODE) /* If @dir is casefolded, initialize @fname->cf_name from @fname->usr_fname. */ int f2fs_init_casefolded_name(const struct inode *dir, struct f2fs_filename *fname) { -#if IS_ENABLED(CONFIG_UNICODE) struct super_block *sb = dir->i_sb; + unsigned char *buf; + int len; if (IS_CASEFOLDED(dir) && !is_dot_dotdot(fname->usr_fname->name, fname->usr_fname->len)) { - fname->cf_name.name = f2fs_kmem_cache_alloc(f2fs_cf_name_slab, - GFP_NOFS, false, F2FS_SB(sb)); - if (!fname->cf_name.name) + buf = f2fs_kmem_cache_alloc(f2fs_cf_name_slab, + GFP_NOFS, false, F2FS_SB(sb)); + if (!buf) return -ENOMEM; - fname->cf_name.len = utf8_casefold(sb->s_encoding, - fname->usr_fname, - fname->cf_name.name, - F2FS_NAME_LEN); - if ((int)fname->cf_name.len <= 0) { - kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); - fname->cf_name.name = NULL; + + len = utf8_casefold(sb->s_encoding, fname->usr_fname, + buf, F2FS_NAME_LEN); + if (len <= 0) { + kmem_cache_free(f2fs_cf_name_slab, buf); if (sb_has_strict_encoding(sb)) return -EINVAL; /* fall back to treating name as opaque byte sequence */ + return 0; } + fname->cf_name.name = buf; + fname->cf_name.len = len; } -#endif + return 0; } +void f2fs_free_casefolded_name(struct f2fs_filename *fname) +{ + unsigned char *buf = (unsigned char *)fname->cf_name.name; + + kmem_cache_free(f2fs_cf_name_slab, buf); + fname->cf_name.name = NULL; +} +#endif /* CONFIG_UNICODE */ + static int __f2fs_setup_filename(const struct inode *dir, const struct fscrypt_name *crypt_name, struct f2fs_filename *fname) @@ -142,12 +154,7 @@ void f2fs_free_filename(struct f2fs_filename *fname) kfree(fname->crypto_buf.name); fname->crypto_buf.name = NULL; #endif -#if IS_ENABLED(CONFIG_UNICODE) - if (fname->cf_name.name) { - kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); - fname->cf_name.name = NULL; - } -#endif + f2fs_free_casefolded_name(fname); } static unsigned long dir_block_index(unsigned int level, @@ -235,11 +242,9 @@ static inline int f2fs_match_name(const struct inode *dir, struct fscrypt_name f; #if IS_ENABLED(CONFIG_UNICODE) - if (fname->cf_name.name) { - struct qstr cf = FSTR_TO_QSTR(>cf_name); - - return f2fs_match_ci_name(dir, , de_name, de_name_len); - } + if (fname->cf_name.name) + return f2fs_match_ci_name(dir, >cf_name, + de_name, de_name_len); #endif f.usr_fname = fname->usr_fname; f.disk_name = fname->disk_name; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 65294e3b0bef..4f68c58718fb 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -524,7 +524,7 @@ struct f2fs_filename { * internal operation where usr_fname is also NULL. In all these cases * we fall back to treating the name as an opaque byte sequence. */ - struct fscrypt_str cf_name; + struct qstr cf_name; #endif }; @@ -3528,8 +3528,22 @@ int f2fs_get_tmpfile(struct mnt_idmap *idmap, struct inode *dir, /* * dir.c */ +#if IS_ENABLED(CONFIG_UNICODE) int f2fs_init_casefolded_name(const struct inode *dir, struct f2fs_filename *fname); +void f2fs_free_casefolded_name(struct f2fs_filename *fname); +#else +static inline int f2fs_init_casefolded_name(const struct inode *dir, + struct f2fs_filename *fname) +{ + return 0; +} + +static inline void
[f2fs-dev] [PATCH v13 6/9] ext4: Log error when lookup of encoded dentry fails
From: Gabriel Krisman Bertazi If the volume is in strict mode, ext4_ci_compare can report a broken encoding name. This will not trigger on a bad lookup, which is caught earlier, only if the actual disk name is bad. Signed-off-by: Gabriel Krisman Bertazi Signed-off-by: Eugen Hristev --- fs/ext4/namei.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 2d0ee232fbe7..3268cf45d9db 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1477,6 +1477,9 @@ static bool ext4_match(struct inode *parent, * only case where it happens is on a disk * corruption or ENOMEM. */ + if (ret == -EINVAL) + EXT4_ERROR_INODE(parent, + "Directory contains filename that is invalid UTF-8"); return false; } return ret; -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v13 1/9] ext4: Simplify the handling of cached insensitive names
From: Gabriel Krisman Bertazi Keeping it as qstr avoids the unnecessary conversion in ext4_match Signed-off-by: Gabriel Krisman Bertazi [eugen.hris...@collabora.com: port to 6.8-rc3] Signed-off-by: Eugen Hristev --- fs/ext4/ext4.h | 2 +- fs/ext4/namei.c | 23 +++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index a5d784872303..4061d11b9763 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2506,7 +2506,7 @@ struct ext4_filename { struct fscrypt_str crypto_buf; #endif #if IS_ENABLED(CONFIG_UNICODE) - struct fscrypt_str cf_name; + struct qstr cf_name; #endif }; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5e4f65c14dfb..b96983a4c185 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1445,7 +1445,8 @@ static int ext4_ci_compare(const struct inode *parent, const struct qstr *name, int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname, struct ext4_filename *name) { - struct fscrypt_str *cf_name = >cf_name; + struct qstr *cf_name = >cf_name; + unsigned char *buf; struct dx_hash_info *hinfo = >hinfo; int len; @@ -1455,18 +1456,18 @@ int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname, return 0; } - cf_name->name = kmalloc(EXT4_NAME_LEN, GFP_NOFS); - if (!cf_name->name) + buf = kmalloc(EXT4_NAME_LEN, GFP_NOFS); + if (!buf) return -ENOMEM; - len = utf8_casefold(dir->i_sb->s_encoding, - iname, cf_name->name, - EXT4_NAME_LEN); + len = utf8_casefold(dir->i_sb->s_encoding, iname, buf, EXT4_NAME_LEN); if (len <= 0) { - kfree(cf_name->name); - cf_name->name = NULL; + kfree(buf); + buf = NULL; } + cf_name->name = buf; cf_name->len = (unsigned) len; + if (!IS_ENCRYPTED(dir)) return 0; @@ -1503,8 +1504,6 @@ static bool ext4_match(struct inode *parent, if (IS_CASEFOLDED(parent) && (!IS_ENCRYPTED(parent) || fscrypt_has_encryption_key(parent))) { if (fname->cf_name.name) { - struct qstr cf = {.name = fname->cf_name.name, - .len = fname->cf_name.len}; if (IS_ENCRYPTED(parent)) { if (fname->hinfo.hash != EXT4_DIRENT_HASH(de) || fname->hinfo.minor_hash != @@ -1513,8 +1512,8 @@ static bool ext4_match(struct inode *parent, return false; } } - return !ext4_ci_compare(parent, , de->name, - de->name_len, true); + return !ext4_ci_compare(parent, >cf_name, + de->name, de->name_len, true); } return !ext4_ci_compare(parent, fname->usr_fname, de->name, de->name_len, false); -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 2/2] f2fs: compress: fix reserve_cblocks counting error when out of space
When a file only needs one direct_node, performing the following operations will cause the file to be unrepairable: unisoc # ./f2fs_io compress test.apk unisoc #df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.2M 100% /data unisoc # ./f2fs_io release_cblocks test.apk 924 unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 4.8M 100% /data unisoc # dd if=/dev/random of=file4 bs=1M count=3 3145728 bytes (3.0 M) copied, 0.025 s, 120 M/s unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 0 This is because the file has only one direct_node. After returning to -ENOSPC, reserved_blocks += ret will not be executed. As a result, the reserved_blocks at this time is still 0, which is not the real number of reserved blocks. Therefore, fsck cannot be set to repair the file. After this patch, the fsck flag will be set to fix this problem. unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 1.8M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device adb reboot then fsck will be executed unisoc # df -h | grep dm-48 /dev/block/dm-48 112G 112G 11M 100% /data unisoc # ./f2fs_io reserve_cblocks test.apk 924 Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu --- fs/f2fs/file.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 572d7bd4d161..97a7233c7ea7 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3624,10 +3624,10 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) return ret; } -static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) +static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count, + unsigned int *reserved_blocks) { struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); - unsigned int reserved_blocks = 0; int cluster_size = F2FS_I(dn->inode)->i_cluster_size; block_t blkaddr; int i; @@ -3691,12 +3691,12 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true); - reserved_blocks += reserved; + *reserved_blocks += reserved; next: count -= cluster_size; } - return reserved_blocks; + return 0; } static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) @@ -3740,6 +3740,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) while (page_idx < last_idx) { struct dnode_of_data dn; pgoff_t end_offset, count; + unsigned int tmp_reserved_blocks; set_new_dnode(, inode, NULL, NULL, 0); ret = f2fs_get_dnode_of_data(, page_idx, LOOKUP_NODE); @@ -3757,7 +3758,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) count = min(end_offset - dn.ofs_in_node, last_idx - page_idx); count = round_up(count, F2FS_I(inode)->i_cluster_size); - ret = reserve_compress_blocks(, count); + ret = reserve_compress_blocks(, count, _reserved_blocks); + reserved_blocks += tmp_reserved_blocks; f2fs_put_dnode(); @@ -3765,13 +3767,12 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) break; page_idx += count; - reserved_blocks += ret; } filemap_invalidate_unlock(inode->i_mapping); f2fs_up_write(_I(inode)->i_gc_rwsem[WRITE]); - if (ret >= 0) { + if (!ret) { clear_inode_flag(inode, FI_COMPRESS_RELEASED); inode_set_ctime_current(inode); f2fs_mark_inode_dirty_sync(inode, true); @@ -3780,7 +3781,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) inode_unlock(inode); mnt_drop_write_file(filp); - if (ret >= 0) { + if (!ret) { ret = put_user(reserved_blocks, (u64 __user *)arg); } else if (reserved_blocks && atomic_read(_I(inode)->i_compr_blocks)) { -- 2.25.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 1/2] f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks
The following f2fs_io test will get a "0" result instead of -EINVAL, unisoc # ./f2fs_io compress file unisoc # ./f2fs_io reserve_cblocks file 0 it's not reasonable, so the judgement of atomic_read(_I(inode)->i_compr_blocks) should be placed after the judgement of is_inode_flag_set(inode, FI_COMPRESS_RELEASED). Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS") Signed-off-by: Xiuhong Wang Signed-off-by: Zhiguo Niu --- fs/f2fs/file.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4ca6c693b33a..572d7bd4d161 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3720,18 +3720,18 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) if (ret) return ret; - if (atomic_read(_I(inode)->i_compr_blocks)) - goto out; - f2fs_balance_fs(sbi, true); inode_lock(inode); if (!is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) { ret = -EINVAL; - goto unlock_inode; + goto out; } + if (atomic_read(_I(inode)->i_compr_blocks)) + goto out; + f2fs_down_write(_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping); @@ -3776,9 +3776,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) inode_set_ctime_current(inode); f2fs_mark_inode_dirty_sync(inode, true); } -unlock_inode: - inode_unlock(inode); out: + inode_unlock(inode); mnt_drop_write_file(filp); if (ret >= 0) { -- 2.25.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
Cast expression type to unsigned long in __count_extent_cache() to prevent integer overflow. Found by Linux Verification Center (linuxtesting.org) with Svace. Signed-off-by: Roman Smirnov Reviewed-by: Sergey Shtylyov --- fs/f2fs/shrinker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c index 83d6fb97dcae..bb86a06c5d5e 100644 --- a/fs/f2fs/shrinker.c +++ b/fs/f2fs/shrinker.c @@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi, { struct extent_tree_info *eti = >extent_tree[type]; - return atomic_read(>total_zombie_tree) + + return (unsigned long)atomic_read(>total_zombie_tree) + atomic_read(>total_ext_node); } -- 2.34.1 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel