| From: |
| Artem Blagodarenko <artem.blagodarenko-AT-gmail.com> |
| To: |
| linux-ext4-AT-vger.kernel.org |
| Subject: |
| [PATCH v3 00/10] Data in direntry (dirdata) feature |
| Date: |
| Fri, 19 Jun 2026 15:10:04 -0400 |
| Message-ID: |
| <20260619191022.27008-1-ablagodarenko@thelustrecollective.com> |
| Cc: |
| adilger.kernel-AT-dilger.ca, Artem Blagodarenko <ablagodarenko-AT-thelustrecollective.com>, syzbot-AT-syzkaller.appspotmail.com |
| Archive-link: |
| Article |
EXT4 currently stores a hash in the directory entry
(dirent) immediately after the file name to support
simultaneous fscrypt and casefold functionality.
It has been discussed within the EXT4 community that
this hash could instead be stored in dirdata. This
would make it the second (or third, in the case of
64-bit inode counts) user of dirdata.
At the same time, the existing format—where the hash
is placed after the file name—must continue to be
supported. With these patches, EXT4 can handle the
hash in both formats.
The first user of this feature is LUFID -
Locally Unique File ID.
Support for fscrypt and case-insensitive directories
with dirdata enabled has been verified using a
dedicated xfstest submitted to the xfstests list as
a separate patch.
e2fsprogs support is provided in a separate patches
series.
Changes in v3:
- Fixed issues reported by automated review of v2:
- dx_get_dx_info() and get_dx_countlimit() called
ext4_dir_entry_len() with the directory inode
hardcoded to NULL, forcing its blocksize fallback
to 4096 regardless of the real filesystem blocksize.
Both now pass the real inode through, and
dx_get_dx_info() also rejects results that fall
outside the directory block.
- ext4_dirdata_get() declared a local "dfid" that
shadowed the function's own "dfid" output parameter,
so a requested LUFID copy never reached the caller's
buffer. Renamed the local and fixed the copy.
- ext4_dirdata_get()/ext4_dirdata_set() compared
offsets against the raw on-disk rec_len instead of
decoding it via ext4_rec_len_from_disk(), which is
incorrect on big-endian hosts and mishandles the
"0/65535 means full block" sentinel. Both now decode
rec_len once and use the decoded value throughout.
- EXT4_IOC_SET_LUFID deleted the existing directory
entry before re-adding it with the new LUFID data;
if the re-add failed, the inode was left with no
directory entry at all. It now attempts to restore
the original entry on failure, and loudly flags
inode corruption if that also fails.
- syzbot ci tested the fix for these issues; per its
request, this is being submitted with the corresponding
Tested-by tag below.
- Rebased onto the latest codebase.
Artem Blagodarenko (10):
ext4: replace ext4_dir_entry with ext4_dir_entry_2
ext4: add ext4_dir_entry_is_tail()
ext4: refactor dx_root to support variable dirent sizes
ext4: add dirdata format definitions and access helpers
ext4: preserve dirdata bits in get_dtype()
ext4: add ext4_dir_entry_len() and harden dirdata parsing
ext4: rename ext4_dir_rec_len() and clarify dirdata usage
ext4: dirdata feature
ext4: add dirdata set/get helpers
ext4: Add EXT4_IOC_SET_LUFID ioctl for setting LUFID on directory
entries
foofile.txt | 0
fs/ext4/dir.c | 9 +-
fs/ext4/ext4.h | 205 +++++++++++-
fs/ext4/inline.c | 37 ++-
fs/ext4/ioctl.c | 62 ++++
fs/ext4/namei.c | 650 ++++++++++++++++++++++++++++----------
fs/ext4/sysfs.c | 2 +
include/uapi/linux/ext4.h | 13 +
8 files changed, 780 insertions(+), 198 deletions(-)
create mode 100644 foofile.txt
Tested-by: syzbot@syzkaller.appspotmail.com
--
2.43.7