Darrick J. Wong [Wed, 30 Jul 2025 17:23:24 +0000 (10:23 -0700)]
fuse2fs: fix block parameter truncation on 32-bit
Use the blk64_t variants of the io channel read/write methods when we
have to do partial block zeroing for hole punching because otherwise
we corrupt large 64-bit filesystems on 32-bit fuse2fs due to integer
truncation.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250730172324.GR2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Sat, 26 Jul 2025 16:28:48 +0000 (09:28 -0700)]
fuse2fs: fix punching post-EOF blocks during truncate
ext2fs_punch() can update the inode that's passed in, so we need to
write it back. This should fix some fstests failures where the test
file system ends up with inodes where all extent records fit within the
inode but inexplicably have extents beyond EOF. While we're at it, add
the fuse2fs prefix to the two helper functions.
Cc: linux-ext4@vger.kernel.org # v1.47.3 Fixes: 4581ac60eb53ec ("fuse2fs: fix post-EOF preallocation clearing on truncation") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250726162848.GQ2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Fri, 25 Jul 2025 15:56:10 +0000 (08:56 -0700)]
fuse2fs: don't record every errno in the superblock as an fs failure
fstests just blew up because somewhere in the fuse iomap code we
returned an ESTALE, which was then passed to translate_error. That
function decided it was a Serious Error and wrote it to the superblock,
so every subsequent mount attempt failed.
I should go figure out why the iomap cache upsert operation returned
ESTALE, but that's not a sign that the *ondisk* filesystem is corrupt.
Prior to commit 71f046a788adba we wouldn't have written that to the
superblock either.
Fix this by isolating the handful of errno that usually mean corruption
problems in filesystems and writing those to the superblock; the other
errno are merely operational errors that can be passed back to the
kernel and up to userspace.
I'm not sure why e2fsck doesn't flag when s_error_count > 0. That might
be an error on its own.
Cc: linux-ext4@vger.kernel.org # v1.47.3 Fixes: 71f046a788adba ("fuse2fs: correctly handle system errno values in __translate_error()") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250725155610.GP2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Tue, 22 Jul 2025 19:40:53 +0000 (12:40 -0700)]
fuse2fs: fix logging redirection
Someone pointed out that you can't just go around reassigning stdout and
stderr because section 7.23.1 paragraph 4 of a recent C2y draft says
that stdin, stdout, and stderr “are expressions of type "pointer to
FILE" that point to the FILE objects associated, respectively, with the
standard error, input, and output streams.”
The use of the word "expression" should have been the warning sign that
a symbol that can be mostly used as a pointer is not simply a pointer.
Seven pages later, footnote 318 of the C2y draft clarifies that stdin,
stdout, and stderr “need not be modifiable lvalues to which the value
returned by the fopen function could be assigned.”
"need not be" is the magic phrasing that means that glibc, musl, and
mingw (for example) have very different declarations of stdout:
glibc:
extern FILE *stdout; /* Standard output stream. */
musl:
extern FILE *const stdout;
mingw:
#define stdout (&_iob[STDOUT_FILENO])
All three are following the specification, yet you can write C code that
fails to compile what otherwise looks like a normal assignment on two of
the libraries:
int main(int argc, char *argv[])
{
fark = NULL;
crows = NULL;
stupid = NULL;
}
/tmp/a.c: In function ‘main’:
/tmp/a.c:20:14: error: assignment of read-only variable ‘fark’
20 | fark = NULL;
| ^
/tmp/a.c:21:15: error: lvalue required as left operand of assignment
21 | crows = NULL;
| ^
What a useless specification! You don't even get the same error!
Unfortunately, this leadership vacuum means that each implementation of
a so-called standard C library is perfectly within its right to do this.
IOWs, the authors decided that every C programmer must divert some of
the brainpower they could spend on their program's core algorithms to be
really smart about this quirk.
A whole committee of very smart programmers collectively decided this
was a good way to run things decades ago so that C library authors in
the 1980s wouldn't have to change their code, and subsequent gatherings
have reaffirmed this "practical" decision. Their suggestion to reassign
stdout and stderr is to use freopen, but that walks the specified path,
which is racy if you want both streams to point to the same file. You
could pass /dev/fd/XX to solve the race, but then you lose portability.
In other words, they "engineered" an incomplete solution with problems
to achieve a short term goal that nobody should care about 40 years
later.
Fix fuse2fs by rearranging the code to change STD{OUT,ERR}_FILENO to
point to the same open logfile via dup2 and then try to use freopen on
/dev/fd/XX to capture any stdout/err usage by the libraries that fuse2fs
depends on.
Note that we must do the whole thing over again in op_init because
libfuse will dup2 STD{OUT,ERR}_FILE to /dev/null as part of daemonizing
the server.
start and end are both zero, so we call ext2fs_punch with those
arguments. ext2fs_punch interprets [start, end] as a closed interval
and removes block 0, which is not what we asked for!
The computation of end is also too subtle -- the dividend is the
expression (0 + 1 - 4096) which produces a negative number because off_t
is defined to be long long, at least on amd64 Linux. We rely on the
behavior that dividing a negative dividend by a positive divisor
produces a quotient of zero.
Really what we should do here is round offset up to the next fsblock
and offset+len down to the nearest fsblock. The first quantity is the
first byte of the range to punch and the second quantity is the next
byte past the range to punch. Using those as the basis to compute start
and end, the punch should only happen if start < end, and we should pass
[start, end - 1] to ext2fs_punch because it expects a closed interval.
Improve the comments here so that I don't have to work all this out
again the next time I read through here.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Here we can clearly see that the first byte of the block has not been
zeroed, even though that's what the caller wanted us to do. This is due
to an incorrect check of the residue variable that was most likely copy
pasted from clean_block_edge years ago.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Darrick J. Wong [Thu, 17 Jul 2025 14:59:50 +0000 (07:59 -0700)]
libext2fs: fix data corruption when writing to inline data files
Fix various bugs in ext2fs_file_write_inline_data:
- "count = nbytes - pos" makes no sense since nbytes is already a
length value and results in short writes if pos > 0.
- Pass the correct file size to ext2fs_inline_data_set because count
will not be the file size if pos > 0.
- Simplify the decision to increase the file size.
- Don't let a huge write corrupt memory beyond file->buf.
- Zero the buffer between isize and pos if we're doing a sparse write
past EOF.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 54e880b870f7fe ("libext2fs: handle inline data in read/write function") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250717145950.GJ2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Thu, 17 Jul 2025 14:59:33 +0000 (07:59 -0700)]
libext2fs: fix data read corruption in ext2fs_file_read_inline_data
Fix numerous problems in the function that reads data from an inlinedata
file:
- Reads starting after isize should be returned as short reads.
- Reads past the end of the inline data should return zeroes.
- Reads from the inline data buffer must not exceed isize.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 54e880b870f7fe ("libext2fs: handle inline data in read/write function") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250717145933.GI2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Thu, 17 Jul 2025 14:59:10 +0000 (07:59 -0700)]
fuse2fs: fix ST_RDONLY setting
Only set ST_RDONLY if the filesystem isn't writable.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250717145910.GH2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Wed, 9 Jul 2025 16:51:52 +0000 (09:51 -0700)]
fuse2fs: fix race condition in op_destroy
On a regular fuse server (i.e. one not running in fuseblk mode), libfuse
synthesizes and dispatches a FUSE_DESTROY command as soon as the event
dispatch loop terminates after the kernel disconnects /dev/fuse.
Unfortunately, this is done without coordinating with any other threads
that may have already received a real FUSE command from the kernel.
In other words, FUSE_DESTROY can run in parallel with other
fuse_operations. Therefore, we must guard the body of this function
with the BKL just like any other fuse operation or risk races within
libext2fs. If we're lucky, we trash the ext2_filsys state and
generic/488 will crash.
If we're not lucky, it corrupts the ondisk filesystem resulting in a
e2fsck complaining as well.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250709165152.GE2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
and the second mount attempt succeeds where it really shouldn't. This
is due to the use of fopen(..., "w"), because "w" means "truncate or
create". It does /not/ imply O_CREAT | O_EXCL, which fails if the file
already exists. Theoretically that could have been done with mode
string "wx", but that's a glibc extension.
Fix this by calling open() directly with the O_ modes that we want.
Cc: linux-ext4@vger.kernel.org # v1.47.3-rc3 Fixes: e50fbaa4d156a6 ("fuse2fs: clean up the lockfile handling") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250708173333.GD2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Mon, 7 Jul 2025 16:05:25 +0000 (09:05 -0700)]
fuse2fs: fix relatime comparisons
generic/192 fails like this even before we start adding iomap code:
--- tests/generic/192.out 2025-04-30 16:20:44.512675591 -0700
+++ tests/generic/192.out.bad 2025-07-06 22:26:11.666015735 -0700
@@ -1,5 +1,6 @@
QA output created by 192
sleep for 5 seconds
test
-delta1 is in range
+delta1 has value of 0
+delta1 is NOT in range 5 .. 7
delta2 is in range
The cause of this regression is that the timestamp comparisons account
only for seconds, not nanoseconds. If a write came in 100ms after the
last read but still in the same second, then we fail to update atime on
a subsequent read.
Fix this by converting the timespecs to doubles so that we can include
the nanoseconds component, and then perform the comparison in floating
point mode.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250707160525.GC2672022@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Sun, 6 Jul 2025 18:32:34 +0000 (11:32 -0700)]
fuse2fs: fix incorrect unit conversion at the end of FITRIM
generic/260 also points out that the bytes cleared are in the wrong
units -- they're supposed to be in bytes, but the "cleared" variable is
in units of fsblocks. Fix that.
Darrick J. Wong [Thu, 31 Jul 2025 14:38:21 +0000 (10:38 -0400)]
fuse2fs: fix incorrect EOFS input handling in FITRIM
FITRIM isn't well documented, which means that I missed that
len == -1ULL always means "trim to end of filesystem". generic/260 has
been failing with:
--- a/tests/generic/260.out 2025-04-30 16:20:44.532797310 -0700
+++ b/tests/generic/260.out.bad 2025-07-03 11:44:26.946394170 -0700
@@ -11,4 +11,5 @@
[+] Default length with start set (should succeed)
[+] Length beyond the end of fs (should succeed)
[+] Length beyond the end of fs with start set (should succeed)
+After the full fs discard 0 bytes were discarded however the file system is 10401542144 bytes long.
Test done
because the addition used to compute end suffered an integer overflow,
resulting in end < start, which meant nothing happened. Fix this by
explicitly checking for -1ULL.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Darrick J. Wong [Sun, 6 Jul 2025 18:31:47 +0000 (11:31 -0700)]
fuse2fs: fix gid inheritance on sgid parent directories
When a child file is created inside a setgid parent directory, the child
is supposed to inherit the gid of the parent, not the fsgid of the
creating process. Fix this error, which was discovered by generic/633,
generic/696, and generic/697.
Darrick J. Wong [Sun, 6 Jul 2025 18:31:16 +0000 (11:31 -0700)]
libext2fs: fix arguments passed to ->block_alloc_stats_range
In ext2fs_block_alloc_stats_range, we use @num as the loop counter but
then pass it to the callback and @blk as the loop cursor. This means
that the range passed to e2fsck_block_alloc_stats_range starts beyond
the range that was actually freed and has a length of zero, which is not
at all correct.
Fix this by saving the original values and passing those instead.
Darrick J. Wong [Sun, 6 Jul 2025 18:31:00 +0000 (11:31 -0700)]
libext2fs: fix off-by-one bug in punch_extent_blocks
punch_extent_blocks tries to validate its input parameters to make sure
that the physical range of blocks being punched do not go past the end
of the filesystem. Unfortunately, there's an off-by-one bug in the
valiation, because start==0 count==10 is a perfectly valid range on a
10-block filesystem.
fuse2fs: fix normal (non-kernel) permissions checking
Commit 9f69dfc4e275 ("fuse2fs: implement O_APPEND correctly") defined
a new flag, A_OK, to add support for testing whether the file is valid
for append operations. This is relevant for the check_iflags_access()
function, but when are later testing operations mask against the inode
permissions, this new flag gets in the way and causes non-root users
attempting to create new inodes in a directory to fail. Fix this by
masking off A_OK before doing these tests.
Avoid redefining CACHE_LINE_SIZE if system provides it.
FreeBSD 14.3 complains about our trying to redefine
the CACHE_LINE_SIZE, which happens to be 1 << 6 == 64
on amd64 but not arm64.
Just check and only #define unless it's already:
../../../lib/ext2fs/unix_io.c:563: warning: "CACHE_LINE_SIZE" redefined
563 | #define CACHE_LINE_SIZE 64
|
In file included from /usr/include/sys/param.h:163,
from /usr/include/bsm/audit.h:41,
from /usr/include/sys/ucred.h:42,
from /usr/include/sys/mount.h:37,
from ../../../lib/ext2fs/unix_io.c:53:
/usr/include/machine/param.h:92: note: this is the location of the previous definition
92 | #define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT)
|
On FreeBSD 14.3, machine/param.h
- for arm64 and powerpc define CACHE_LINE_SIZE to (128),
- for i386, amd64, arm (32) and riscv define (64).
Care was taken to make sure where to quote and where not to; variable
assignments with EGREP=@EGREP@ need quoting in order not to split the
variable into tokens; expansions in places where we used to invoke egrep
need not because they actually need to split $EGREP contents in case
it's "grep -E".
This fixes "egrep is obsolescent" warnings on newer coreutils.
Samuel Smith [Sat, 28 Jun 2025 05:14:15 +0000 (00:14 -0500)]
e2scrub: honor fstrim setting in e2scrub.conf
The systemd service unconditionally passes -t to e2scrub, forcing
fstrim to run after every scrub regardless of the fstrim setting
in /etc/e2scrub.conf. Removing the hardcoded flag will allow users to
control the behavior via the configuration file.
Matthias Andree [Thu, 26 Jun 2025 20:28:40 +0000 (22:28 +0200)]
m_offset: make self-test reliable with non-GNU yes(1)
m_offset has been failing sporadically on FreeBSD, and always because
crc_exp(ected) was different from all other CRC values (which were
mutually equal, first1, first2, last).
The test scrsipt uses yes(1) to write into dd(1),
but FreeBSD's "yes a" use sizes of 8192 - length-of-pattern, meaning
8190 with "a\n" (meaning a + LF).
GNU yes from coreutils 9.1 instead dispatches 1024-sized writes.
The peculiar thing is that dd bs=1k count=512 will dispatch 512 read
attempts of 1 k each, but due to yes and dd running concurrently, dd
will sometimes see a short read block, resulting in an overall shorter
output file fed into crcsum, leading to a mismatched crc_exp value.
Fix: Add iflag=fullblock to ensure the proper output size will be fed
into crcsum, even if that means doing more than 512 reads internally.
Darrick J. Wong [Mon, 16 Jun 2025 15:06:14 +0000 (08:06 -0700)]
fuse2fs: clean up the lockfile handling
Fix various problems with the new lockfile code in fuse2fs: the printfs
should use the actual logging function err_printf, the messages should
be looked up in gettext, we should actually exit main properly on
error instead of calling exit(), and the error message printing for the
final lockfile unlink is broken.
debian: use dpkg-shlibdeps for library dependency calculation
* Drop old shlibs.local. The file is not needed and "This file should
normally not be used" according to:
https://www.debian.org/doc/debian-policy/ch-sharedlibs.html#the-shlibs-files-present-on-the-system
* Remove manual dependency on libcom-err2 as dpkg-shlibdeps will compute
and add it to ${shlibs:Depends}.
Theodore Ts'o [Sun, 15 Jun 2025 10:30:05 +0000 (06:30 -0400)]
Use static linking for libarchive by default on MacOS
Apparently dlopen() path searching doesn't work or is unreliable on
MacOS; it appears to not search LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, or
DYLD_FALLBACK_LIBRARY_PATH as documented by the dlopen(3) man page.
Furthmore setting any of these variables to include /opt/local/lib,
which is where MacPort drops libarchive.13.dylib, can cause all manner
of warnings when running other dynamically linked programs, such as
"grep". What a mess. It appears dlopen(2) support in MacOS is a
disaster, and it's not really needed since we don't care about the
size of mke2fs on installation media on non-Linux systems. So default
to using --with-libarchive=direct for MacOS.
Theodore Ts'o [Sat, 14 Jun 2025 20:47:26 +0000 (16:47 -0400)]
Use the fuse3 libraries reported by pkg-config
It used to be that PKG_CHECK_MODULES would set foo_LDFLAGS; not it
just sets the foo_LIBS with the required -L and -l options. Fix this
up for fuse3 support.
Darrick J. Wong [Thu, 12 Jun 2025 22:18:26 +0000 (15:18 -0700)]
libext2fs: fix bounding error in the extent fallocate code
generic/361 popped up this weird error:
generic/361 [failed, exit status 1]- output mismatch (see /var/tmp/fstests/generic/361.out.bad)
--- tests/generic/361.out 2025-04-30 16:20:44.563589363 -0700
+++ /var/tmp/fstests/generic/361.out.bad 2025-06-11 10:40:07.475036412 -0700
@@ -1,2 +1,2 @@
QA output created by 361
-Silence is golden
+mkfs.fuse.ext4: Input/output error while writing out and closing file system
...
(Run 'diff -u /run/fstests/bin/tests/generic/361.out /var/tmp/fstests/generic/361.out.bad' to see the entire diff)
The test formats a small filesystem, creates a larger sparse file, loop
mounts it, and tries to format an ext4 filesystem on the loopdev. The
loop driver sends fallocate zero_range requests to fuse2fs, but stumbles
over this extent tree layout when fallocating 16 blocks at offset 145:
EXTENTS:
(262128-262143[u]):2127-2142
fallocate goes to offset 145, and sees the right-extent at 262128.
Oddly, it then tries to allocate 262128-145 blocks instead of the 16
that were asked for, so it tries to allocate a huge number of blocks
but then crashes and burns when it runs out of space.
Fix this by constraining the len parameter to ext_falloc_helper to the
correct value.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 5aad5b8e0e3cfa ("libext2fs: implement fallocate") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20250612221826.GE6134@frogsfrogsfrogs Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Wed, 11 Jun 2025 16:44:01 +0000 (09:44 -0700)]
fuse2fs: fix error bailout in op_create
Tim Woodall pointed out that op_create returns garbage error codes if
the ext2fs_extent_open2 in op_create fails. Worse than that, it also
neglects to drop the bfl and leaks temp_path. Let's fix all that.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Reported-by: Tim Woodall <debianbugs@woodall.me.uk> Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Darrick J. Wong [Wed, 11 Jun 2025 16:43:45 +0000 (09:43 -0700)]
libext2fs: fix spurious warnings from fallocate
generic/522 routinely produces error messages from fuse2fs like this:
FUSE2FS (sde): Illegal block number passed to ext2fs_test_block_bitmap #9321 for block bitmap for /dev/sde
Curiously, these don't actually result in errors being thrown up to the
kernel. Digging into the program (which was more difficult than it
needed to be because of the weird bitmap base + errcode weirdness)
produced a left record:
e_lblk = 16
e_pblk = 9293
e_len = 6
e_flags = 0
and a right record:
e_lblk = 45
e_pblk = 9321
e_len = 6
e_flags = 0
Thus we end up in the "Merge both extents together, perhaps?" section of
ext_falloc_helper. Unfortunately, the merge selection code isn't smart
enough to notice that the two mappings aren't actually physically
contiguous, so it scans the bitmap with a negative length, which is why
the assertion trips.
The simple fix here is not to try to merge the adjacent extents if
they're not actually physically contiguous.
Cc: linux-ext4@vger.kernel.org # v1.43 Fixes: 5aad5b8e0e3cfa ("libext2fs: implement fallocate") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Theodore Ts'o [Thu, 12 Jun 2025 16:33:44 +0000 (14:03 -0230)]
fuse2fs: correctly handle system errno values in __translate_error()
Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Reported-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Theodore Ts'o [Tue, 10 Jun 2025 17:04:08 +0000 (13:04 -0400)]
debian: fix typo in fuse2fs.postrm which breaks a /usr-move mitigation
A space was accidenally introduced into the fuse2fs.postrm which
breaks the /usr-move replacement of fusext2 from an older legacy
package that had been abandoned upstream. Specifically, what was
broken was the cleanup of the protective diversions:
Theodore Ts'o [Fri, 6 Jun 2025 22:52:13 +0000 (18:52 -0400)]
libext2fs: fix ext2fs_link() when the directory has an extent tree depth > 1
Ext2fs_link() was passing the wrong inode number to ext2fs_bmap(); as
a result, when a directory inode was using extents and the extent tree
depth was greater than 1, the extent tree checksum would be
incorrectly calculated resulting in a error that the extent tree block
checksum was incorrect.
Fixes: 53aa6c54224f ("libext2fs: add the EXT2FS_LINK_APPEND flag ...)
Addresses-Debian-Bug: #1106854 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Theodore Ts'o [Fri, 6 Jun 2025 13:07:11 +0000 (09:07 -0400)]
libext2fs: fix a extent tree corruption bug in ext2fs_extent_set_bmap()
In the case where we are moving a particular logical block mapping
from a particular extent tree entry, to the immediately precending
entry (when the physical block or uninitialized flag is changing so it
can be coalesced with the precending entry) and the precending entry
is in a different extent tree block, the resulting extent tree can get
corrupted.
Fix this by removing the original logical block mapping before adding
the new logical block mapping. Per the warning in the comments before
ext2fs_extents_fix_parents():
Note a subtlety of this function -- if there happen to be two extents
mapping the same lblk and someone calls fix_parents on the second of
the two extents, the position of the extent handle after the call will
be the second extent if nothing happened, or the first extent if
something did. A caller in this situation must use
ext2fs_extent_goto() after calling this function. Or simply don't map
the same lblk with two extents, ever.
Theodore Ts'o [Wed, 4 Jun 2025 00:16:30 +0000 (00:16 +0000)]
misc: define alternative errno if OS doesn't provide ENODATA
FreeBSD doesn't define ENODATA, and uses ENOATTR when an extended
attribute is not found. So map ENODATA to ENOATTR to fix a build
failure for platforms that don't define ENODATA.
Theodore Ts'o [Tue, 3 Jun 2025 23:06:37 +0000 (23:06 +0000)]
debian: add a Built-Using field to the e2fsck-static package
We will probably want to eventually revert this commit and replace it
with a change using dh-builtusing, such as can be found in [1], but
dh-builtusing is only available in Debian 13 (trixie) and we don't
want to make life difficult for people who need to backport to Debian
Stable or Ubuntu LTS.
Theodore Ts'o [Mon, 26 May 2025 14:09:59 +0000 (10:09 -0400)]
libe2p: avoid potential integer overflow in interate_on_dir()
Overflows won't happen if the OS's implementation of pathconf()
returns reasonable values, but we can make it a bit more hardened
against maliciou implementations.
Theodore Ts'o [Mon, 26 May 2025 02:20:36 +0000 (22:20 -0400)]
e2fsck: fix e2fsck -E unshare_blocks when there are no shared blocks
If there are no shared blocks in a ext4 file system, e2fsck -E
unshare_blocks will not actually clear the shared_blocks feature flag
since e2fsck_pass1_dupblocks() is never called. Fix this by adding a
check in e2fsck_pass1() to clear the shared blocks flag.
Theodore Ts'o [Sun, 25 May 2025 16:51:36 +0000 (12:51 -0400)]
mke2fs: propagate some chattr flags into the fs image when using mke2fs -d
When copying files from a source directory, propagate chattr flags
such as the immutable, append-only, nodump, etc. into the files in the
destination file system. Flags in directory inodes are also propagated.
Theodore Ts'o [Sun, 25 May 2025 21:38:49 +0000 (17:38 -0400)]
libext2fs: fix ext2fs_link() for EXT2FS_LINK_APPEND and non-regular files
Fix the incorrect flag being passed to ext2fs_process_dir_block().
This bug was masked because EXT2_FT_REG_FILE has the same code point
as DIRENT_FLAG_INCLUDE_EMPTY which was the flag that was needed and
mke2fs -d was only use ext2fs_lik() for regular files.
Fixes: 53aa6c54224f ("libext2fs: add the EXT2FS_LINK_APPEND flag ...) Signed-off-by: Theodore Ts'o <tytso@mit.edu>