Since struct exfat_entry_set_cache is allocated from stack,
no need to free, so rename exfat_free_dentry_set() to
exfat_put_dentry_set(). After renaming, the new function pair
is exfat_get_dentry_set()/exfat_put_dentry_set().
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
The size of struct exfat_entry_set_cache is only 56 bytes on
64-bit system, and allocating from stack is more efficient than
allocating from heap.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
In special cases, a file or a directory may occupied more than 19
directory entries, pre-allocating 3 bh is not enough. Such as
- Support vendor secondary directory entry in the future.
- Since file directory entry is damaged, the SecondaryCount
field is bigger than 18.
So this commit supports dynamic allocation of bh.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
In normal, there are 19 directory entries at most for a file or
a directory.
- A file directory entry
- A stream extension directory entry
- 1~17 file name directory entry
So the directory entries are in 3 sectors at most, it is enough
for struct exfat_entry_set_cache to pre-allocate 3 bh.
This commit changes the size of struct exfat_entry_set_cache as:
Before After
32-bit system 88 32 bytes
64-bit system 168 48 bytes
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
After traversing all directory entries, hint the empty directory
entry no matter whether or not there are enough empty directory
entries.
After this commit, hint the empty directory entries like this:
1. Hint the deleted directory entries if enough;
2. Hint the deleted and unused directory entries which at the
end of the cluster chain no matter whether enough or not(Add
by this commit);
3. If no any empty directory entries, hint the empty directory
entries in the new cluster(Add by this commit).
This avoids repeated traversal of directory entries, reduces CPU
usage, and improves the performance of creating files and
directories(especially on low-performance CPUs).
Test create 5000 files in a class 4 SD card on imx6q-sabrelite
with:
for ((i=0;i<5;i++)); do
sync
time (for ((j=1;j<=1000;j++)); do touch file$((i*1000+j)); done)
done
The more files, the more performance improvements.
Before After Improvement
1~1000 25.360s 22.168s 14.40%
1001~2000 38.242s 28.72ss 33.15%
2001~3000 49.134s 35.037s 40.23%
3001~4000 62.042s 41.624s 49.05%
4001~5000 73.629s 46.772s 57.42%
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit adds exfat_set_empty_hint()/exfat_reset_empty_hint()
to reduce code complexity and make code more readable.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This version number is sync with linux mainline.
Major changes are:
- Use updated exfat_chain directly instead of snapshot values in rename.
- fix the error code of rename syscall.
- cleanup and suppress the superfluous error messages.
- remove duplicate directory entry update.
- fix integer overflow on large partition.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Using int type for sector index, there will be overflow in a large
capacity partition.
For example, if storage with sector size of 512 bytes and partition
capacity is larger than 2TB, there will be overflow.
Fixes: 1b6138385499 ("exfat: reduce block requests when zeroing a cluster")
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
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: Namjae Jeon <linkinjeon@kernel.org>
When backporting mainline exfat patch, there are build issue from low
kernel version. This patch add auto build-test for exfat with 4.1
kernel and simple tests.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
exfat_err() adds the new line at the end of the message by itself,
hence the passed string shouldn't contain a new line. Drop the
superfluous newline letters in the error messages in a few places that
have been put mistakenly.
Reported-by: Joe Perches <joe@perches.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
The ENAMETOOLONG error message is printed at each time when user tries
to operate with a too long name, and this can flood the kernel logs
easily, as every user can trigger this. Let's downgrade this error
message level to a debug message for suppressing the superfluous
logs.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1201725
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Currently the error and info messages handled by exfat_err() and co
are tossed to exfat_msg() function that does nothing but passes the
strings with printk() invocation. Not only that this is more overhead
by the indirect calls, but also this makes harder to extend for the
debug print usage; because of the direct printk() call, you cannot
make it for dynamic debug or without debug like the standard helpers
such as pr_debug() or dev_dbg().
For addressing the problem, this patch replaces exfat_*() macro to
expand to pr_*() directly. Along with it, add the new exfat_debug()
macro that is expanded to pr_debug() (which output can be gracefully
suppressed via dyndbg).
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
NLS_NAME_* are bit flags although they are currently defined as enum;
it's casually working so far (from 0 to 2), but it's error-prone and
may bring a problem when we want to add more flag.
This patch changes the definitions of NLS_NAME_* explicitly being bit
flags.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
LTP has a test for oversized file path renames and it expects the
return value to be ENAMETOOLONG. However, exfat returns EINVAL
unexpectedly in some cases, hence LTP test fails. The further
investigation indicated that the problem happens only when iocharset
isn't set to utf8.
The difference comes from that, in the case of utf8,
exfat_utf8_to_utf16() returns the error -ENAMETOOLONG directly and
it's treated as the final error code. Meanwhile, on other iocharsets,
exfat_nls_to_ucs2() returns the max path size but it sets
NLS_NAME_OVERLEN to lossy flag instead; the caller side checks only
whether lossy flag is set or not, resulting in always -EINVAL
unconditionally.
This patch aligns the return code for both cases by checking the lossy
flag bit and returning ENAMETOOLONG when NLS_NAME_OVERLEN bit is set.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1201725
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
mpage_readpage still works in terms of pages, and has not been audited
for correctness with large folios, so include an assertion that the
filesystem is not passing it large folios. Convert all the filesystems
to call mpage_read_folio() instead of mpage_readpage().
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
There are no more aop flags left, so remove the parameter.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
There are no more aop flags left, so remove the parameter.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Abstract away implementation details from file systems by providing a
block_device based helper to retrieve the discard granularity.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com> [drbd]
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Acked-by: David Sterba <dsterba@suse.com> [btrfs]
Link: https://lore.kernel.org/r/20220415045258.199825-26-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Just use a non-zero max_discard_sectors as an indicator for discard
support, similar to what is done for write zeroes.
The only places where needs special attention is the RAID5 driver,
which must clear discard support for security reasons by default,
even if the default stacking rules would allow for it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com> [drbd]
Acked-by: Jan Höppner <hoeppner@linux.ibm.com> [s390]
Acked-by: Coly Li <colyli@suse.de> [bcache]
Acked-by: David Sterba <dsterba@suse.com> [btrfs]
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Link: https://lore.kernel.org/r/20220415045258.199825-25-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Since the timestamps need to be updated, the directory entries
will be updated by mark_inode_dirty() whether or not a new
cluster is allocated for the file or directory, so there is no
need to use __exfat_write_inode() to update the directory entries
when allocating a new cluster for a file or directory.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Daniel Palmer <daniel.palmer@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit moves updating file attributes and timestamps before
calling __exfat_write_inode(), so that all updates of the inode
had been written by __exfat_write_inode(), mark_inode_dirty() is
unneeded.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Daniel Palmer <daniel.palmer@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
__exfat_write_inode() is used to update file and stream directory
entries, except for file->start_clu and stream->flags.
This commit moves update file->start_clu and stream->flags to
__exfat_write_inode() and reuse __exfat_write_inode() to update
directory entries.
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Daniel Palmer <daniel.palmer@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
In order for a file to access its own directory entry set,
exfat_inode_info(ei) has two copied values. One is ei->dir, which is
a snapshot of exfat_chain of the parent directory, and the other is
ei->entry, which is the offset of the start of the directory entry set
in the parent directory.
Since the parent directory can be updated after the snapshot point,
it should be used only for accessing one's own directory entry set.
However, as of now, during renaming, it could try to traverse or to
allocate clusters via snapshot values, it does not make sense.
This potential problem has been revealed when exfat_update_parent_info()
was removed by commit d8dad2588add ("exfat: fix referencing wrong parent
directory information after renaming"). However, I don't think it's good
idea to bring exfat_update_parent_info() back.
Instead, let's use the updated exfat_chain of parent directory diectly.
Signed-off-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Major changes are:
- fix referencing wrong parent directory information during rename.
- introduce a sys_tz mount option to use system timezone.
- improve performance while zeroing a cluster with dirsync mount option.
- fix slab-out-bounds in exat_clear_bitmap() reported from syzbot.
- Add keep_last_dots mount option to allow access to paths with trailing dots.
- Avoid repetitive volume dirty bit set/clear to improve storage life time.
- Fix ->i_blocks truncation issue that still exists elsewhere.
- 4 cleanups & typos fixes.
- Move super block magic number to magic.h
- Fix missing REQ_SYNC in exfat_update_bhs().
- Fix ->i_blocks truncation issue caused by wrong 32bit mask.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
sync_blockdev_range will be added to linux 5.19 kernel. So, do directly
call filemap_write_and_wait_range() instead of sync_blockdev_range() on
lower kernel version than 5.19 kernel.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Make sure to include the header file that defines this function.
Fixes: 19b7087 ("exfat: fix build on x86 with 4.19 kernel")
Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
`i_blocksize` did not exist on kernel 4.4 until 4.4.72 was released [1].
1. https://lwn.net/Articles/725371/
Signed-off-by: Tianling Shen <i@cnsztl.eu.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
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>
rw flags agrument in write_dirty_buffer() and __sync_dirty_buffer() was
changed since linux 4.8 kernels.
Reported-by: kuehnelth <kuehnelth@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
The inode allocation is supposed to use alloc_inode_sb(), so convert
kmem_cache_alloc() of all filesystems to alloc_inode_sb().
Link: https://lkml.kernel.org/r/20220228122126.37293-5-songmuchun@bytedance.com
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Acked-by: Theodore Ts'o <tytso@mit.edu>[ext4]
Acked-by: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Alex Shi <alexs@kernel.org>
Cc: Anna Schumaker <Anna.Schumaker@Netapp.com>
Cc: Chao Yu <chao@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Fam Zheng <fam.zheng@bytedance.com>
Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kari Argillander <kari.argillander@gmail.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Qi Zheng <zhengqi.arch@bytedance.com>
Cc: Shakeel Butt <shakeelb@google.com>
Cc: Trond Myklebust <trond.myklebust@hammerspace.com>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Wei Yang <richard.weiyang@gmail.com>
Cc: Xiongchun Duan <duanxiongchun@bytedance.com>
Cc: Yang Shi <shy828301@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Convert all callers; mostly this is just changing the aops to point
at it, but a few implementations need a little more work.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Tested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Acked-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Tested-by: Mike Marshall <hubcap@omnibond.com> # orangefs
Tested-by: David Howells <dhowells@redhat.com> # afs
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Remove special-casing of a NULL invalidatepage, since there is no
more block_invalidatepage.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Tested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Acked-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Tested-by: Mike Marshall <hubcap@omnibond.com> # orangefs
Tested-by: David Howells <dhowells@redhat.com> # afs
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Remove the CONFIG_BLOCK default to __set_page_dirty_buffers and just wire
that method up for the missing instances.
[hch@lst.de: ecryptfs: add a ->set_page_dirty cludge]
Link: https://lkml.kernel.org/r/20210624125250.536369-1-hch@lst.de
Link: https://lkml.kernel.org/r/20210614061512.3966143-4-hch@lst.de
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Tyler Hicks <code@tyhicks.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
If 'dirsync' is enabled, when zeroing a cluster, submitting
sector by sector will generate many block requests, will
cause the block device to not fully perform its performance.
This commit makes the sectors in a cluster to be submitted in
once, it will reduce the number of block requests. This will
make the block device to give full play to its performance.
Test create 1000 directories on SD card with:
$ time (for ((i=0;i<1000;i++)); do mkdir dir${i}; done)
Performance has been improved by more than 73% on imx6q-sabrelite.
Cluster size Before After Improvement
64 KBytes 3m34.036s 0m56.052s 73.8%
128 KBytes 6m2.644s 1m13.354s 79.8%
256 KBytes 11m22.202s 1m39.451s 85.4%
imx6q-sabrelite:
- CPU: 792 MHz x4
- Memory: 1GB DDR3
- SD Card: SanDisk 8GB Class 4
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
EXFAT_TZ_VALID bit in {create,modify,access}_tz is corresponding to
OffsetValid field in exfat specification [1]. When this bit isn't
set, timestamps should be treated as having the same UTC offset as
the current local time.
Currently, there is an option 'time_offset' for users to specify the
UTC offset for this issue. This patch introduces a new mount option
'sys_tz' to use system timezone as time offset.
Link: [1] https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#74102-offsetvalid-field
Signed-off-by: Chung-Chiang Cheng <cccheng@synology.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
During renaming, the parent directory information maybe
updated. But the file/directory still references to the
old parent directory information.
This bug will cause 2 problems.
(1) The renamed file can not be written.
[10768.175172] exFAT-fs (sda1): error, failed to bmap (inode : 7afd50e4 iblock : 0, err : -5)
[10768.184285] exFAT-fs (sda1): Filesystem has been set read-only
ash: write error: Input/output error
(2) Some dentries of the renamed file/directory are not set
to deleted after removing the file/directory.
exfat_update_parent_info() is a workaround for the wrong parent
directory information being used after renaming. Now that bug is
fixed, this is no longer needed, so remove it.
Fixes: 5f2aa075070c ("exfat: add inode operations")
Cc: stable@vger.kernel.org # v5.7+
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Reviewed-by: Daniel Palmer <daniel.palmer@sony.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Before this commit, VolumeDirty will be cleared first in
writeback if 'dirsync' or 'sync' is not enabled. If the power
is suddenly cut off after cleaning VolumeDirty but other
updates are not written, the exFAT filesystem will not be able
to detect the power failure in the next mount.
And VolumeDirty will be set again but not cleared when updating
the parent directory. It means that BootSector will be written at
least once in each write-back, which will shorten the life of the
device.
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
exfat currently unconditionally strips trailing
periods '.' when performing path lookup, but allows them in the filenames
during file creation. This is done intentionally, loosely following
Windows behaviour and specifications which state:
#exFAT
The concatenated file name has the same set of illegal characters as
other FAT-based file systems (see Table 31).
#FAT
...
Leading and trailing spaces in a long name are ignored.
Leading and embedded periods are allowed in a name and are stored in
the long name. Trailing periods are ignored.
Note: Leading and trailing space ' ' characters are currently retained
by Linux kernel exfat, in conflict with the above specification.
On Windows 10, trailing and leading space ' ' characters are stripped
from the filenames
.
Some implementations, such as fuse-exfat, don't perform path trailer
removal. When mounting images which contain trailing-dot paths, these
paths are unreachable, e.g.:
+ mount.exfat-fuse /dev/zram0 /mnt/test/
FUSE exfat 1.3.0
+ cd /mnt/test/
+ touch fuse_created_dots... ' fuse_created_spaces '
+ ls -l
total 0
-rwxrwxrwx 1 root 0 0 Aug 18 09:45 ' fuse_created_spaces '
-rwxrwxrwx 1 root 0 0 Aug 18 09:45 fuse_created_dots...
+ cd /
+ umount /mnt/test/
+ mount -t exfat /dev/zram0 /mnt/test
+ cd /mnt/test
+ ls -l
ls: cannot access 'fuse_created_dots...': No such file or directory
total 0
-rwxr-xr-x 1 root 0 0 Aug 18 09:45 ' fuse_created_spaces '
-????????? ? ? ? ? ? fuse_created_dots...
+ touch kexfat_created_dots... ' kexfat_created_spaces '
+ ls -l
ls: cannot access 'fuse_created_dots...': No such file or directory
total 0
-rwxr-xr-x 1 root 0 0 Aug 18 09:45 ' fuse_created_spaces '
-rwxr-xr-x 1 root 0 0 Aug 18 09:45 ' kexfat_created_spaces '
-????????? ? ? ? ? ? fuse_created_dots...
-rwxr-xr-x 1 root 0 0 Aug 18 09:45 kexfat_created_dots
+ cd /
+ umount /mnt/test/
This commit adds "keep_last_dots" mount option that controls whether or
not trailing periods '.' are stripped
from path components during file lookup or file creation.
This mount option can be used to access
paths with trailing periods and disallow creating files with names with
trailing periods. E.g. continuing from the previous example:
+ mount -t exfat -o keep_last_dots /dev/zram0 /mnt/test
+ cd /mnt/test
+ ls -l
total 0
-rwxr-xr-x 1 root 0 0 Aug 18 10:32 ' fuse_created_spaces '
-rwxr-xr-x 1 root 0 0 Aug 18 10:32 ' kexfat_created_spaces '
-rwxr-xr-x 1 root 0 0 Aug 18 10:32 fuse_created_dots...
-rwxr-xr-x 1 root 0 0 Aug 18 10:32 kexfat_created_dots
+ echo > kexfat_created_dots_again...
sh: kexfat_created_dots_again...: Invalid argument
Link: https://bugzilla.suse.com/show_bug.cgi?id=1188964
Link: https://lore.kernel.org/linux-fsdevel/003b01d755e4$31fb0d80$95f12880$
@samsung.com/
Link: https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
Suggested-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Vasant Karasulli <vkarasulli@suse.de>
Co-developed-by: David Disseldorp <ddiss@suse.de>
Signed-off-by: David Disseldorp <ddiss@suse.de>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
If 'dirsync' is enabled, all directory updates within the
filesystem should be done synchronously. exfat_update_bh()
does as this, but exfat_update_bhs() does not.
Reviewed-by: Andy.Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama, Wataru <wataru.aoyama@sony.com>
Reviewed-by: Kobayashi, Kento <Kento.A.Kobayashi@sony.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Yuezhang.Mo <Yuezhang.Mo@sony.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
In exfat_truncate(), the computation of inode->i_blocks is wrong if
the file is larger than 4 GiB because a 32-bit variable is used as a
mask. This is fixed by casting the variable to loff_t which is 64-bit.
Also fix the same computation in exfat_read_root().
This commit is similar to Sungjong Seo's fix in exfat_fill_inode()
last month:
commit 0c336d6e33f4 ("exfat: fix incorrect loading of i_blocks for
large files")
Signed-off-by: Christophe Vu-Brugier <christophe.vu-brugier@seagate.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>