Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from namjaejeon:master #11

Open
wants to merge 141 commits into
base: master
Choose a base branch
from

Conversation

pull[bot]
Copy link

@pull pull bot commented Mar 18, 2022

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.1)

Can you help keep this open source service alive? 💖 Please sponsor : )

 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 <[email protected]>
Signed-off-by: Vasant Karasulli <[email protected]>
Co-developed-by: David Disseldorp <[email protected]>
Signed-off-by: David Disseldorp <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
@pull pull bot added ⤵️ pull merge-conflict Resolve conflicts manually labels Mar 18, 2022
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 <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Signed-off-by: Yuezhang Mo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
YuezhangMo and others added 16 commits April 4, 2022 12:08
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: [email protected] # v5.7+
Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Andy Wu <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
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 <[email protected]>
Acked-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
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 <[email protected]>
Reviewed-by: Andy Wu <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Acked-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Remove the CONFIG_BLOCK default to __set_page_dirty_buffers and just wire
that method up for the missing instances.

[[email protected]: ecryptfs: add a ->set_page_dirty cludge]
  Link: https://lkml.kernel.org/r/[email protected]

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Greg Kroah-Hartman <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Matthew Wilcox (Oracle) <[email protected]>
Cc: Tyler Hicks <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Remove special-casing of a NULL invalidatepage, since there is no
more block_invalidatepage.

Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
Tested-by: Damien Le Moal <[email protected]>
Acked-by: Damien Le Moal <[email protected]>
Tested-by: Mike Marshall <[email protected]> # orangefs
Tested-by: David Howells <[email protected]> # afs
Signed-off-by: Namjae Jeon <[email protected]>
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) <[email protected]>
Tested-by: Damien Le Moal <[email protected]>
Acked-by: Damien Le Moal <[email protected]>
Tested-by: Mike Marshall <[email protected]> # orangefs
Tested-by: David Howells <[email protected]> # afs
Signed-off-by: Namjae Jeon <[email protected]>
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/[email protected]
Signed-off-by: Muchun Song <[email protected]>
Acked-by: Theodore Ts'o <[email protected]>[ext4]
Acked-by: Roman Gushchin <[email protected]>
Cc: Alex Shi <[email protected]>
Cc: Anna Schumaker <[email protected]>
Cc: Chao Yu <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Fam Zheng <[email protected]>
Cc: Jaegeuk Kim <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Kari Argillander <[email protected]>
Cc: Matthew Wilcox (Oracle) <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Qi Zheng <[email protected]>
Cc: Shakeel Butt <[email protected]>
Cc: Trond Myklebust <[email protected]>
Cc: Vladimir Davydov <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Wei Yang <[email protected]>
Cc: Xiongchun Duan <[email protected]>
Cc: Yang Shi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
rw flags agrument in write_dirty_buffer() and __sync_dirty_buffer() was
changed since linux 4.8 kernels.

Reported-by: kuehnelth <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
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: [email protected]
Fixes: 1e49a94cf707 ("exfat: add bitmap operations")
Cc: [email protected] # v5.7+
Signed-off-by: Tadeusz Struk <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
`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 <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
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 <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
__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 <[email protected]>
Reviewed-by: Andy Wu <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
YuezhangMo and others added 4 commits July 22, 2022 11:43
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 <[email protected]>
Reviewed-by: Andy Wu <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
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 <[email protected]>
Reviewed-by: Andy Wu <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
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 <[email protected]>
Reviewed-by: Martin K. Petersen <[email protected]>
Acked-by: Christoph Böhmwalder <[email protected]> [drbd]
Acked-by: Jan Höppner <[email protected]> [s390]
Acked-by: Coly Li <[email protected]> [bcache]
Acked-by: David Sterba <[email protected]> [btrfs]
Reviewed-by: Chaitanya Kulkarni <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Abstract away implementation details from file systems by providing a
block_device based helper to retrieve the discard granularity.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Martin K. Petersen <[email protected]>
Acked-by: Christoph Böhmwalder <[email protected]> [drbd]
Acked-by: Ryusuke Konishi <[email protected]>
Acked-by: David Sterba <[email protected]> [btrfs]
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
@namjaejeon namjaejeon force-pushed the master branch 2 times, most recently from dd3a59a to 0cfa8e9 Compare August 7, 2024 13:35
mjeanson and others added 2 commits August 7, 2024 22:37
Pass the idmapped mount information to the different helper
functions. Adapt the uid/gid checks in exfat_setattr to use the
vfsuid/vfsgid helpers.

Based on the fat implementation in commit 4b7899368108
("fat: handle idmapped mounts") by Christian Brauner.

Signed-off-by: Michael Jeanson <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
When accessing a file with more entries than ES_MAX_ENTRY_NUM, the bh-array
is allocated in __exfat_get_entry_set. The problem is that the bh-array is
allocated with GFP_KERNEL. It does not make sense. In the following cases,
a deadlock for sbi->s_lock between the two processes may occur.

       CPU0                CPU1
       ----                ----
  kswapd
   balance_pgdat
    lock(fs_reclaim)
                      exfat_iterate
                       lock(&sbi->s_lock)
                       exfat_readdir
                        exfat_get_uniname_from_ext_entry
                         exfat_get_dentry_set
                          __exfat_get_dentry_set
                           kmalloc_array
                            ...
                            lock(fs_reclaim)
    ...
    evict
     exfat_evict_inode
      lock(&sbi->s_lock)

To fix this, let's allocate bh-array with GFP_NOFS.

Fixes: a3ff29a95fde ("exfat: support dynamic allocate bh for exfat_entry_set_cache")
Cc: [email protected] # v6.2+
Reported-by: [email protected]
Closes: https://lore.kernel.org/lkml/[email protected]
Signed-off-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
@namjaejeon namjaejeon force-pushed the master branch 2 times, most recently from 24a6384 to 0b16b18 Compare August 7, 2024 13:47
namjaejeon and others added 19 commits August 8, 2024 09:31
->i_size_ondisk is no longer used by exfat_write_begin() after
commit(11a347fb6cef exfat: change to get file size from DataLength),
drop it.

Signed-off-by: Yuezhang Mo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
After commit(11a347fb6cef exfat: change to get file size from
DataLength), the remaining area or hole had been filled with
zeros before calling exfat_direct_IO(), so there is no need to
fallback to buffered write, and ->i_size_aligned is no longer
needed, drop it.

Signed-off-by: Yuezhang Mo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
We found that when writing a large file through buffer write, if the
disk is inaccessible, exFAT does not return an error normally, which
leads to the writing process not stopping properly.

To easily reproduce this issue, you can follow the steps below:

1. format a device to exFAT and then mount (with a full disk erase)
2. dd if=/dev/zero of=/exfat_mount/test.img bs=1M count=8192
3. eject the device

You may find that the dd process does not stop immediately and may
continue for a long time.

The root cause of this issue is that during buffer write process,
exFAT does not need to access the disk to look up directory entries
or the FAT table (whereas FAT would do) every time data is written.
Instead, exFAT simply marks the buffer as dirty and returns,
delegating the writeback operation to the writeback process.

If the disk cannot be accessed at this time, the error will only be
returned to the writeback process, and the original process will not
receive the error, so it cannot be returned to the user side.

When the disk cannot be accessed normally, an error should be returned
to stop the writing process.

Implement sops->shutdown and ioctl to shut down the file system
when underlying block device is marked dead.

Signed-off-by: Dongliang Cui <[email protected]>
Signed-off-by: Zhiguo Niu <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
If the first directory entry in the root directory is not a bitmap
directory entry, 'bh' will not be released and reassigned, which
will cause a memory leak.

Fixes: 1e49a94cf707 ("exfat: add bitmap operations")
Cc: [email protected]
Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Most callers have a folio, and most implementations operate on a folio,
so remove the conversion from folio->page->folio to fit through this
interface.

Reviewed-by: Josef Bacik <[email protected]>
Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
Signed-off-by: Christian Brauner <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Convert all callers from working on a page to working on one page
of a folio (support for working on an entire folio can come later).
Removes a lot of folio->page->folio conversions.

Reviewed-by: Josef Bacik <[email protected]>
Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
Signed-off-by: Christian Brauner <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
It is not a good way to extend valid_size to the end of the
mmap area by writing zeros in mmap. Because after calling mmap,
no data may be written, or only a small amount of data may be
written to the head of the mmap area.

This commit moves extending valid_size to exfat_page_mkwrite().
In exfat_page_mkwrite() only extend valid_size to the starting
position of new data writing, which reduces unnecessary writing
of zeros.

If the block is not mapped and is marked as new after being
mapped for writing, block_write_begin() will zero the page
cache corresponding to the block, so there is no need to call
zero_user_segment() in exfat_file_zeroed_range(). And after moving
extending valid_size to exfat_page_mkwrite(), the data written by
mmap will be copied to the page cache but the page cache may be
not mapped to the disk. Calling zero_user_segment() will cause
the data written by mmap to be cleared. So this commit removes
calling zero_user_segment() from exfat_file_zeroed_range() and
renames exfat_file_zeroed_range() to exfat_extend_valid_size().

Signed-off-by: Yuezhang Mo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
If exfat_load_upcase_table reaches end and returns -EINVAL,
allocated memory doesn't get freed and while
exfat_load_default_upcase_table allocates more memory, leading to a
memory leak.

Here's link to syzkaller crash report illustrating this issue:
https://syzkaller.appspot.com/text?tag=CrashReport&x=1406c201980000

Reported-by: [email protected]
Fixes: a13d1a4de3b0 ("exfat: move freeing sbi, upcase table and dropping nls into rcu-delayed helper")
Cc: [email protected]
Signed-off-by: Daniel Yang <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
asm/unaligned.h is always an include of asm-generic/unaligned.h;
might as well move that thing to linux/unaligned.h and include
that - there's nothing arch-specific in that header.

auto-generated by the following:

for i in cache.c
fatent.c
nls.c; do
sed -i -e s/asm/unaligned.h/linux/unaligned.h/
done
for i in ; do
sed -i -e s/asm-generic/unaligned.h/linux/unaligned.h/
done
git mv include/asm-generic/unaligned.h include/linux/unaligned.h
git mv tools/include/asm-generic/unaligned.h tools/include/linux/unaligned.h
sed -i -e /unaligned.h/d include/asm-generic/Kbuild
sed -i -e s/__ASM_GENERIC/__LINUX/ include/linux/unaligned.h tools/include/linux/unaligned.h

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
In the case of the directory size is greater than or equal to
the cluster size, if start_clu becomes an EOF cluster(an invalid
cluster) due to file system corruption, then the directory entry
where ei->hint_femp.eidx hint is outside the directory, resulting
in an out-of-bounds access, which may cause further file system
corruption.

This commit adds a check for start_clu, if it is an invalid cluster,
the file or directory will be treated as empty.

Cc: [email protected]
Signed-off-by: Yuezhang Mo <[email protected]>
Co-developed-by: Namjae Jeon <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
There is no check if stream size and start_clu are invalid.
If start_clu is EOF cluster and stream size is 4096, It will
cause uninit value access. because ei->hint_femp.eidx could
be 128(if cluster size is 4K) and wrong hint will allocate
next cluster. and this cluster will be same with the cluster
that is allocated by exfat_extend_valid_size(). The previous
patch will check invalid start_clu, but for clarity, initialize
hint_femp.eidx to zero.

Cc: [email protected]
Reported-by: [email protected]
Tested-by: [email protected]
Reviewed-by: Yuezhang Mo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
To determine whether it is a directory, there is no need to read its
directory entry, just use S_ISDIR(inode->i_mode).

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
In this exfat implementation, the relationship between inode and ei
is ei=EXFAT_I(inode). However, in the arguments of exfat_move_file()
and exfat_rename_file(), argument 'inode' indicates the parent
directory, but argument 'ei' indicates the target file to be renamed.
They do not have the above relationship, which is not friendly to code
readers.

So this commit renames 'inode' to 'parent_inode', making the argument
name match its role.

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
This helper gets the directory entry set of the file for the exfat
inode which has been created.

It's used to remove all the instances of the pattern it replaces
making the code cleaner, it's also a preparation for changing ->dir
to record the cluster where the directory entry set is located and
changing ->entry to record the index of the directory entry within
the cluster.

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
__exfat_resolve_path() mixes two functions. The first one is to
resolve and check if the path is valid. The second one is to output
the cluster assigned to the directory.

The second one is only needed when need to traverse the directory
entries, and calling exfat_chain_set() so early causes p_dir to be
passed as an argument multiple times, increasing the complexity of
the code.

This commit moves the call to exfat_chain_set() before traversing
directory entries.

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
The output of argument 'p_dir' of exfat_add_entry() is not used
in either exfat_mkdir() or exfat_create(), remove the argument.

Code refinement, no functional changes.

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
For the root directory and other directories, the clusters
allocated to them can be obtained from exfat_inode_info, and
there is no need to distinguish them.

And there is no need to initialize atime/ctime/mtime/size in
exfat_readdir(), because exfat_iterate() does not use them.

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Before this commit, ->dir and ->entry of exfat_inode_info record the
first cluster of the parent directory and the directory entry index
starting from this cluster.

The directory entry set will be gotten during write-back-inode/rmdir/
unlink/rename. If the clusters of the parent directory are not
continuous, the FAT chain will be traversed from the first cluster of
the parent directory to find the cluster where ->entry is located.

After this commit, ->dir records the cluster where the first directory
entry in the directory entry set is located, and ->entry records the
directory entry index in the cluster, so that there is almost no need
to access the FAT when getting the directory entry set.

Signed-off-by: Yuezhang Mo <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Reviewed-by: Daniel Palmer <[email protected]>
Reviewed-by: Sungjong Seo <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⤵️ pull merge-conflict Resolve conflicts manually
Projects
None yet
Development

Successfully merging this pull request may close these issues.