History log of /linux-master/fs/exfat/balloc.c
Revision Date Author Comments
# 34939ae0 07-Dec-2023 John Sanpe <sanpeqf@gmail.com>

exfat: using ffs instead of internal logic

Replaced the internal table lookup algorithm with ffs of
the bitops library with better performance.

Use it to increase the single processing length of the
exfat_find_free_bitmap function, from single-byte search to long type.

Signed-off-by: John Sanpe <sanpeqf@gmail.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>


# 74235460 05-Dec-2023 John Sanpe <sanpeqf@gmail.com>

exfat: using hweight instead of internal logic

Replace the internal table lookup algorithm with the hweight
library, which has instruction set acceleration capabilities.

Use it to increase the length of a single calculation of
the exfat_find_free_bitmap function to the long type.

Signed-off-by: John Sanpe <sanpeqf@gmail.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>


# daf60d6c 05-Jul-2023 gaoming <gaoming20@hihonor.com>

exfat: use kvmalloc_array/kvfree instead of kmalloc_array/kfree

The call stack shown below is a scenario in the Linux 4.19 kernel.
Allocating memory failed where exfat fs use kmalloc_array due to
system memory fragmentation, while the u-disk was inserted without
recognition.
Devices such as u-disk using the exfat file system are pluggable and
may be insert into the system at any time.
However, long-term running systems cannot guarantee the continuity of
physical memory. Therefore, it's necessary to address this issue.

Binder:2632_6: page allocation failure: order:4,
mode:0x6040c0(GFP_KERNEL|__GFP_COMP), nodemask=(null)
Call trace:
[242178.097582] dump_backtrace+0x0/0x4
[242178.097589] dump_stack+0xf4/0x134
[242178.097598] warn_alloc+0xd8/0x144
[242178.097603] __alloc_pages_nodemask+0x1364/0x1384
[242178.097608] kmalloc_order+0x2c/0x510
[242178.097612] kmalloc_order_trace+0x40/0x16c
[242178.097618] __kmalloc+0x360/0x408
[242178.097624] load_alloc_bitmap+0x160/0x284
[242178.097628] exfat_fill_super+0xa3c/0xe7c
[242178.097635] mount_bdev+0x2e8/0x3a0
[242178.097638] exfat_fs_mount+0x40/0x50
[242178.097643] mount_fs+0x138/0x2e8
[242178.097649] vfs_kern_mount+0x90/0x270
[242178.097655] do_mount+0x798/0x173c
[242178.097659] ksys_mount+0x114/0x1ac
[242178.097665] __arm64_sys_mount+0x24/0x34
[242178.097671] el0_svc_common+0xb8/0x1b8
[242178.097676] el0_svc_handler+0x74/0x90
[242178.097681] el0_svc+0x8/0x340

By analyzing the exfat code,we found that continuous physical memory
is not required here,so kvmalloc_array is used can solve this problem.

Cc: stable@vger.kernel.org
Signed-off-by: gaoming <gaoming20@hihonor.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>


# 64ba4b15 16-May-2022 Tadeusz Struk <tadeusz.struk@linaro.org>

exfat: check if cluster num is valid

Syzbot reported slab-out-of-bounds read in exfat_clear_bitmap.
This was triggered by reproducer calling truncute with size 0,
which causes the following trace:

BUG: KASAN: slab-out-of-bounds in exfat_clear_bitmap+0x147/0x490 fs/exfat/balloc.c:174
Read of size 8 at addr ffff888115aa9508 by task syz-executor251/365

Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack_lvl+0x1e2/0x24b lib/dump_stack.c:118
print_address_description+0x81/0x3c0 mm/kasan/report.c:233
__kasan_report mm/kasan/report.c:419 [inline]
kasan_report+0x1a4/0x1f0 mm/kasan/report.c:436
__asan_report_load8_noabort+0x14/0x20 mm/kasan/report_generic.c:309
exfat_clear_bitmap+0x147/0x490 fs/exfat/balloc.c:174
exfat_free_cluster+0x25a/0x4a0 fs/exfat/fatent.c:181
__exfat_truncate+0x99e/0xe00 fs/exfat/file.c:217
exfat_truncate+0x11b/0x4f0 fs/exfat/file.c:243
exfat_setattr+0xa03/0xd40 fs/exfat/file.c:339
notify_change+0xb76/0xe10 fs/attr.c:336
do_truncate+0x1ea/0x2d0 fs/open.c:65

Move the is_valid_cluster() helper from fatent.c to a common
header to make it reusable in other *.c files. And add is_valid_cluster()
to validate if cluster number is within valid range in exfat_clear_bitmap()
and exfat_set_bitmap().

Link: https://syzkaller.appspot.com/bug?id=50381fc73821ecae743b8cf24b4c9a04776f767c
Reported-by: syzbot+a4087e40b9c13aad7892@syzkaller.appspotmail.com
Fixes: 1e49a94cf707 ("exfat: add bitmap operations")
Cc: stable@vger.kernel.org # v5.7+
Signed-off-by: Tadeusz Struk <tadeusz.struk@linaro.org>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>


# c71510b3 16-Dec-2021 Yuezhang.Mo <Yuezhang.Mo@sony.com>

exfat: remove argument 'sector' from exfat_get_dentry()

No any function uses argument 'sector', remove it.

Reviewed-by: Andy.Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama, Wataru <wataru.aoyama@sony.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Yuezhang.Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>


# 23befe49 14-Mar-2021 Hyeongseok Kim <hyeongseok@gmail.com>

exfat: improve write performance when dirsync enabled

Degradation of write speed caused by frequent disk access for cluster
bitmap update on every cluster allocation could be improved by
selective syncing bitmap buffer. Change to flush bitmap buffer only
for the directory related operations.

Signed-off-by: Hyeongseok Kim <hyeongseok@gmail.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>


# 654762df 03-Mar-2021 Hyeongseok Kim <hyeongseok@gmail.com>

exfat: add support ioctl and FITRIM function

Add FITRIM ioctl to enable discarding unused blocks while mounted.
As current exFAT doesn't have generic ioctl handler, add empty ioctl
function first, and add FITRIM handler.

Signed-off-by: Hyeongseok Kim <hyeongseok@gmail.com>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>


# 77edfc6e 03-Mar-2021 Hyeongseok Kim <hyeongseok@gmail.com>

exfat: fix erroneous discard when clear cluster bit

If mounted with discard option, exFAT issues discard command when clear
cluster bit to remove file. But the input parameter of cluster-to-sector
calculation is abnormally added by reserved cluster size which is 2,
leading to discard unrelated sectors included in target+2 cluster.
With fixing this, remove the wrong comments in set/clear/find bitmap
functions.

Fixes: 1e49a94cf707 ("exfat: add bitmap operations")
Cc: stable@vger.kernel.org # v5.7+
Signed-off-by: Hyeongseok Kim <hyeongseok@gmail.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>


# f728760a 31-Jan-2021 Hyeongseok Kim <hyeongseok@gmail.com>

exfat: improve performance of exfat_free_cluster when using dirsync mount option

There are stressful update of cluster allocation bitmap when using
dirsync mount option which is doing sync buffer on every cluster bit
clearing. This could result in performance degradation when deleting
big size file.
Fix to update only when the bitmap buffer index is changed would make
less disk access, improving performance especially for truncate operation.

Testing with Samsung 256GB sdcard, mounted with dirsync option
(mount -t exfat /dev/block/mmcblk0p1 /temp/mount -o dirsync)

Remove 4GB file, blktrace result.
[Before] : 39 secs.
Total (blktrace):
Reads Queued: 0, 0KiB Writes Queued: 32775, 16387KiB
Read Dispatches: 0, 0KiB Write Dispatches: 32775, 16387KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 32775, 16387KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
IO unplugs: 2 Timer unplugs: 0

[After] : 1 sec.
Total (blktrace):
Reads Queued: 0, 0KiB Writes Queued: 13, 6KiB
Read Dispatches: 0, 0KiB Write Dispatches: 13, 6KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 13, 6KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
IO unplugs: 1 Timer unplugs: 0

Signed-off-by: Hyeongseok Kim <hyeongseok@gmail.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>


# 2c7f8937 15-Jun-2020 Tetsuhiro Kohada <kohada.t2@gmail.com>

exfat: remove EXFAT_SB_DIRTY flag

This flag is set/reset in exfat_put_super()/exfat_sync_fs()
to avoid sync_blockdev().
- exfat_put_super():
Before calling this, the VFS has already called sync_filesystem(),
so sync is never performed here.
- exfat_sync_fs():
After calling this, the VFS calls sync_blockdev(), so, it is meaningless
to check EXFAT_SB_DIRTY or to bypass sync_blockdev() here.

Remove the EXFAT_SB_DIRTY check to ensure synchronization.
And remove the code related to the flag.

Signed-off-by: Tetsuhiro Kohada <kohada.t2@gmail.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>


# d1727d55 23-Apr-2020 Joe Perches <joe@perches.com>

exfat: Use a more common logging style

Remove the direct use of KERN_<LEVEL> in functions by creating
separate exfat_<level> macros.

Miscellanea:

o Remove several unnecessary terminating newlines in formats
o Realign arguments and fit to 80 columns where appropriate

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>


# b0516833 20-Apr-2020 Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>

exfat: Unify access to the boot sector

Unify access to boot sector via 'sbi->pbr_bh'.
This fixes vol_flags inconsistency at read failed in fs_set_vol_flags(),
and buffer_head leak in __exfat_fill_super().

Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>


# 1e49a94c 01-Mar-2020 Namjae Jeon <namjae.jeon@samsung.com>

exfat: add bitmap operations

This adds the implementation of bitmap operations for exfat.

Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: Sungjong Seo <sj1557.seo@samsung.com>
Reviewed-by: Pali Rohár <pali.rohar@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>