<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/fs/exfat, branch v6.15</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>exfat: call bh_read in get_block only when necessary</title>
<updated>2025-03-29T13:03:11+00:00</updated>
<author>
<name>Sungjong Seo</name>
<email>sj1557.seo@samsung.com</email>
</author>
<published>2025-03-26T15:01:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=c73e680d1f84059e1b1ea82a537f6ccc1c563eb4'/>
<id>c73e680d1f84059e1b1ea82a537f6ccc1c563eb4</id>
<content type='text'>
With commit 11a347fb6cef ("exfat: change to get file size from DataLength"),
exfat_get_block() can now handle valid_size. However, most partial
unwritten blocks that could be mapped with other blocks are being
inefficiently processed separately as individual blocks.

Except for partial unwritten blocks that require independent processing,
let's handle them simply as before.

Signed-off-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With commit 11a347fb6cef ("exfat: change to get file size from DataLength"),
exfat_get_block() can now handle valid_size. However, most partial
unwritten blocks that could be mapped with other blocks are being
inefficiently processed separately as individual blocks.

Except for partial unwritten blocks that require independent processing,
let's handle them simply as before.

Signed-off-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: fix potential wrong error return from get_block</title>
<updated>2025-03-29T13:03:07+00:00</updated>
<author>
<name>Sungjong Seo</name>
<email>sj1557.seo@samsung.com</email>
</author>
<published>2025-03-26T14:48:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=59c30e31425833385e6644ad33151420e37eabe1'/>
<id>59c30e31425833385e6644ad33151420e37eabe1</id>
<content type='text'>
If there is no error, get_block() should return 0. However, when bh_read()
returns 1, get_block() also returns 1 in the same manner.

Let's set err to 0, if there is no error from bh_read()

Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength")
Cc: stable@vger.kernel.org
Signed-off-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If there is no error, get_block() should return 0. However, when bh_read()
returns 1, get_block() also returns 1 in the same manner.

Let's set err to 0, if there is no error from bh_read()

Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength")
Cc: stable@vger.kernel.org
Signed-off-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: fix missing shutdown check</title>
<updated>2025-03-27T12:18:03+00:00</updated>
<author>
<name>Yuezhang Mo</name>
<email>Yuezhang.Mo@sony.com</email>
</author>
<published>2025-03-06T07:02:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=47e35366bc6fa3cf189a8305bce63992495f3efa'/>
<id>47e35366bc6fa3cf189a8305bce63992495f3efa</id>
<content type='text'>
xfstests generic/730 test failed because after deleting the device
that still had dirty data, the file could still be read without
returning an error. The reason is the missing shutdown check in
-&gt;read_iter.

I also noticed that shutdown checks were missing from -&gt;write_iter,
-&gt;splice_read, and -&gt;mmap. This commit adds shutdown checks to all
of them.

Fixes: f761fcdd289d ("exfat: Implement sops-&gt;shutdown and ioctl")
Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
xfstests generic/730 test failed because after deleting the device
that still had dirty data, the file could still be read without
returning an error. The reason is the missing shutdown check in
-&gt;read_iter.

I also noticed that shutdown checks were missing from -&gt;write_iter,
-&gt;splice_read, and -&gt;mmap. This commit adds shutdown checks to all
of them.

Fixes: f761fcdd289d ("exfat: Implement sops-&gt;shutdown and ioctl")
Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: fix the infinite loop in exfat_find_last_cluster()</title>
<updated>2025-03-27T12:18:03+00:00</updated>
<author>
<name>Yuezhang Mo</name>
<email>Yuezhang.Mo@sony.com</email>
</author>
<published>2025-03-17T02:53:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=b0522303f67255926b946aa66885a0104d1b2980'/>
<id>b0522303f67255926b946aa66885a0104d1b2980</id>
<content type='text'>
In exfat_find_last_cluster(), the cluster chain is traversed until
the EOF cluster. If the cluster chain includes a loop due to file
system corruption, the EOF cluster cannot be traversed, resulting
in an infinite loop.

If the number of clusters indicated by the file size is inconsistent
with the cluster chain length, exfat_find_last_cluster() will return
an error, so if this inconsistency is found, the traversal can be
aborted without traversing to the EOF cluster.

Reported-by: syzbot+f7d147e6db52b1e09dba@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f7d147e6db52b1e09dba
Tested-by: syzbot+f7d147e6db52b1e09dba@syzkaller.appspotmail.com
Fixes: 31023864e67a ("exfat: add fat entry operations")
Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In exfat_find_last_cluster(), the cluster chain is traversed until
the EOF cluster. If the cluster chain includes a loop due to file
system corruption, the EOF cluster cannot be traversed, resulting
in an infinite loop.

If the number of clusters indicated by the file size is inconsistent
with the cluster chain length, exfat_find_last_cluster() will return
an error, so if this inconsistency is found, the traversal can be
aborted without traversing to the EOF cluster.

Reported-by: syzbot+f7d147e6db52b1e09dba@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f7d147e6db52b1e09dba
Tested-by: syzbot+f7d147e6db52b1e09dba@syzkaller.appspotmail.com
Fixes: 31023864e67a ("exfat: add fat entry operations")
Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: fix random stack corruption after get_block</title>
<updated>2025-03-27T12:18:02+00:00</updated>
<author>
<name>Sungjong Seo</name>
<email>sj1557.seo@samsung.com</email>
</author>
<published>2025-03-21T06:34:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=1bb7ff4204b6d4927e982cd256286c09ed4fd8ca'/>
<id>1bb7ff4204b6d4927e982cd256286c09ed4fd8ca</id>
<content type='text'>
When get_block is called with a buffer_head allocated on the stack, such
as do_mpage_readpage, stack corruption due to buffer_head UAF may occur in
the following race condition situation.

     &lt;CPU 0&gt;                      &lt;CPU 1&gt;
mpage_read_folio
  &lt;&lt;bh on stack&gt;&gt;
  do_mpage_readpage
    exfat_get_block
      bh_read
        __bh_read
	  get_bh(bh)
          submit_bh
          wait_on_buffer
                              ...
                              end_buffer_read_sync
                                __end_buffer_read_notouch
                                   unlock_buffer
          &lt;&lt;keep going&gt;&gt;
        ...
      ...
    ...
  ...
&lt;&lt;bh is not valid out of mpage_read_folio&gt;&gt;
   .
   .
another_function
  &lt;&lt;variable A on stack&gt;&gt;
                                   put_bh(bh)
                                     atomic_dec(bh-&gt;b_count)
  * stack corruption here *

This patch returns -EAGAIN if a folio does not have buffers when bh_read
needs to be called. By doing this, the caller can fallback to functions
like block_read_full_folio(), create a buffer_head in the folio, and then
call get_block again.

Let's do not call bh_read() with on-stack buffer_head.

Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength")
Cc: stable@vger.kernel.org
Tested-by: Yeongjin Gil &lt;youngjin.gil@samsung.com&gt;
Signed-off-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When get_block is called with a buffer_head allocated on the stack, such
as do_mpage_readpage, stack corruption due to buffer_head UAF may occur in
the following race condition situation.

     &lt;CPU 0&gt;                      &lt;CPU 1&gt;
mpage_read_folio
  &lt;&lt;bh on stack&gt;&gt;
  do_mpage_readpage
    exfat_get_block
      bh_read
        __bh_read
	  get_bh(bh)
          submit_bh
          wait_on_buffer
                              ...
                              end_buffer_read_sync
                                __end_buffer_read_notouch
                                   unlock_buffer
          &lt;&lt;keep going&gt;&gt;
        ...
      ...
    ...
  ...
&lt;&lt;bh is not valid out of mpage_read_folio&gt;&gt;
   .
   .
another_function
  &lt;&lt;variable A on stack&gt;&gt;
                                   put_bh(bh)
                                     atomic_dec(bh-&gt;b_count)
  * stack corruption here *

This patch returns -EAGAIN if a folio does not have buffers when bh_read
needs to be called. By doing this, the caller can fallback to functions
like block_read_full_folio(), create a buffer_head in the folio, and then
call get_block again.

Let's do not call bh_read() with on-stack buffer_head.

Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength")
Cc: stable@vger.kernel.org
Tested-by: Yeongjin Gil &lt;youngjin.gil@samsung.com&gt;
Signed-off-by: Sungjong Seo &lt;sj1557.seo@samsung.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: remove count used cluster from exfat_statfs()</title>
<updated>2025-03-27T12:18:02+00:00</updated>
<author>
<name>Yuezhang Mo</name>
<email>Yuezhang.Mo@sony.com</email>
</author>
<published>2025-02-19T19:00:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=f6369ae1f088cb6d18d7a07eec95d7c10c2a2a5e'/>
<id>f6369ae1f088cb6d18d7a07eec95d7c10c2a2a5e</id>
<content type='text'>
The callback function statfs() is called only after the file
system is mounted. During the process of mounting the exFAT
file system, the number of used clusters has been counted, so
the condition "sbi-&gt;used_clusters == EXFAT_CLUSTERS_UNTRACKED"
is always false and should be deleted.

Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The callback function statfs() is called only after the file
system is mounted. During the process of mounting the exFAT
file system, the number of used clusters has been counted, so
the condition "sbi-&gt;used_clusters == EXFAT_CLUSTERS_UNTRACKED"
is always false and should be deleted.

Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: support batch discard of clusters when freeing clusters</title>
<updated>2025-03-27T12:18:02+00:00</updated>
<author>
<name>Yuezhang Mo</name>
<email>Yuezhang.Mo@sony.com</email>
</author>
<published>2025-02-12T06:18:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=a36e0ab44cb344728f7c0fdc34edcbae64739c16'/>
<id>a36e0ab44cb344728f7c0fdc34edcbae64739c16</id>
<content type='text'>
If the discard mount option is enabled, the file's clusters are
discarded when the clusters are freed. Discarding clusters one by
one will significantly reduce performance. Poor performance may
cause soft lockup when lots of clusters are freed.

This commit improves performance by discarding contiguous clusters
in batches.

Measure the performance by:

  # truncate -s 80G /mnt/file
  # time rm /mnt/file

Without this commit:

  real    4m46.183s
  user    0m0.000s
  sys     0m12.863s

With this commit:

  real    0m1.661s
  user    0m0.000s
  sys     0m0.017s

Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If the discard mount option is enabled, the file's clusters are
discarded when the clusters are freed. Discarding clusters one by
one will significantly reduce performance. Poor performance may
cause soft lockup when lots of clusters are freed.

This commit improves performance by discarding contiguous clusters
in batches.

Measure the performance by:

  # truncate -s 80G /mnt/file
  # time rm /mnt/file

Without this commit:

  real    4m46.183s
  user    0m0.000s
  sys     0m12.863s

With this commit:

  real    0m1.661s
  user    0m0.000s
  sys     0m0.017s

Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge tag 'vfs-6.15-rc1.async.dir' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs</title>
<updated>2025-03-24T17:47:14+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2025-03-24T17:47:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=26d8e430796e7e110c656e87be8d9d3d3a90a305'/>
<id>26d8e430796e7e110c656e87be8d9d3d3a90a305</id>
<content type='text'>
Pull vfs async dir updates from Christian Brauner:
 "This contains cleanups that fell out of the work from async directory
  handling:

   - Change kern_path_locked() and user_path_locked_at() to never return
     a negative dentry. This simplifies the usability of these helpers
     in various places

   - Drop d_exact_alias() from the remaining place in NFS where it is
     still used. This also allows us to drop the d_exact_alias() helper
     completely

   - Drop an unnecessary call to fh_update() from nfsd_create_locked()

   - Change i_op-&gt;mkdir() to return a struct dentry

     Change vfs_mkdir() to return a dentry provided by the filesystems
     which is hashed and positive. This allows us to reduce the number
     of cases where the resulting dentry is not positive to very few
     cases. The code in these places becomes simpler and easier to
     understand.

   - Repack DENTRY_* and LOOKUP_* flags"

* tag 'vfs-6.15-rc1.async.dir' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  doc: fix inline emphasis warning
  VFS: Change vfs_mkdir() to return the dentry.
  nfs: change mkdir inode_operation to return alternate dentry if needed.
  fuse: return correct dentry for -&gt;mkdir
  ceph: return the correct dentry on mkdir
  hostfs: store inode in dentry after mkdir if possible.
  Change inode_operations.mkdir to return struct dentry *
  nfsd: drop fh_update() from S_IFDIR branch of nfsd_create_locked()
  nfs/vfs: discard d_exact_alias()
  VFS: add common error checks to lookup_one_qstr_excl()
  VFS: change kern_path_locked() and user_path_locked_at() to never return negative dentry
  VFS: repack LOOKUP_ bit flags.
  VFS: repack DENTRY_ flags.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pull vfs async dir updates from Christian Brauner:
 "This contains cleanups that fell out of the work from async directory
  handling:

   - Change kern_path_locked() and user_path_locked_at() to never return
     a negative dentry. This simplifies the usability of these helpers
     in various places

   - Drop d_exact_alias() from the remaining place in NFS where it is
     still used. This also allows us to drop the d_exact_alias() helper
     completely

   - Drop an unnecessary call to fh_update() from nfsd_create_locked()

   - Change i_op-&gt;mkdir() to return a struct dentry

     Change vfs_mkdir() to return a dentry provided by the filesystems
     which is hashed and positive. This allows us to reduce the number
     of cases where the resulting dentry is not positive to very few
     cases. The code in these places becomes simpler and easier to
     understand.

   - Repack DENTRY_* and LOOKUP_* flags"

* tag 'vfs-6.15-rc1.async.dir' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  doc: fix inline emphasis warning
  VFS: Change vfs_mkdir() to return the dentry.
  nfs: change mkdir inode_operation to return alternate dentry if needed.
  fuse: return correct dentry for -&gt;mkdir
  ceph: return the correct dentry on mkdir
  hostfs: store inode in dentry after mkdir if possible.
  Change inode_operations.mkdir to return struct dentry *
  nfsd: drop fh_update() from S_IFDIR branch of nfsd_create_locked()
  nfs/vfs: discard d_exact_alias()
  VFS: add common error checks to lookup_one_qstr_excl()
  VFS: change kern_path_locked() and user_path_locked_at() to never return negative dentry
  VFS: repack LOOKUP_ bit flags.
  VFS: repack DENTRY_ flags.
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: add a check for invalid data size</title>
<updated>2025-03-05T12:53:20+00:00</updated>
<author>
<name>Yuezhang Mo</name>
<email>Yuezhang.Mo@sony.com</email>
</author>
<published>2025-02-08T09:16:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=13940cef95491472760ca261b6713692ece9b946'/>
<id>13940cef95491472760ca261b6713692ece9b946</id>
<content type='text'>
Add a check for invalid data size to avoid corrupted filesystem
from being further corrupted.

Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add a check for invalid data size to avoid corrupted filesystem
from being further corrupted.

Signed-off-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>exfat: short-circuit zero-byte writes in exfat_file_write_iter</title>
<updated>2025-03-05T12:53:20+00:00</updated>
<author>
<name>Eric Sandeen</name>
<email>sandeen@redhat.com</email>
</author>
<published>2025-02-11T20:14:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=fda94a9919fd632033979ad7765a99ae3cab9289'/>
<id>fda94a9919fd632033979ad7765a99ae3cab9289</id>
<content type='text'>
When generic_write_checks() returns zero, it means that
iov_iter_count() is zero, and there is no work to do.

Simply return success like all other filesystems do, rather than
proceeding down the write path, which today yields an -EFAULT in
generic_perform_write() via the
(fault_in_iov_iter_readable(i, bytes) == bytes) check when bytes
== 0.

Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength")
Reported-by: Noah &lt;kernel-org-10@maxgrass.eu&gt;
Signed-off-by: Eric Sandeen &lt;sandeen@redhat.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When generic_write_checks() returns zero, it means that
iov_iter_count() is zero, and there is no work to do.

Simply return success like all other filesystems do, rather than
proceeding down the write path, which today yields an -EFAULT in
generic_perform_write() via the
(fault_in_iov_iter_readable(i, bytes) == bytes) check when bytes
== 0.

Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength")
Reported-by: Noah &lt;kernel-org-10@maxgrass.eu&gt;
Signed-off-by: Eric Sandeen &lt;sandeen@redhat.com&gt;
Reviewed-by: Yuezhang Mo &lt;Yuezhang.Mo@sony.com&gt;
Signed-off-by: Namjae Jeon &lt;linkinjeon@kernel.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
