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>
Theodore Ts'o [Sun, 25 May 2025 04:39:13 +0000 (00:39 -0400)]
Add a support for new flag (EXT2FS_LINK_EXPAND) for ext2fs_link()
Many calls to ext2fs_link() checks for EXT2_ET_DIR_NO_SPACE and if so,
calls ext2fs_expand_dir() and then retries the ext2fs_link(). We can
simplify a lot of code by adding support for a flag which does the
retry into the ext2fs_link() function.
Similar to 64-bit support, fs-verity support requires extents, so don't
allow to create a filesystem that has -O verity unless it also supports
extents.
When creating a filesystem with `mke2fs -O verity` and populating
content via `-d`, check if that content is fs-verity enabled, and if it
is, copy the fs-verity metadata from the host-native filesystem into the
created filesystem.
When writing data to an inode (with mke2fs -d) we need to do the typical
loop to handle partial writes to make sure all of the data gets written.
Move that code to its own function. This function also takes an offset
parameter, which makes it feel a bit like pwrite() (except that it does
modify the file offset).
Right now we jump to the end as soon as we've found a method that works.
This is a reasonable approach because it's the last operation in the
function, but soon it won't be. Switch to a logically-equivalent
alternative approach: keep trying until we find the approach that works,
dropping the `goto out`. Now we can add code after this.
Darrick J. Wong [Wed, 21 May 2025 22:42:30 +0000 (15:42 -0700)]
fuse2fs: fix group membership checking in op_chmod
In the decade or so since I touched fuse2fs, libfuse3 has grown the
ability to read the group ids of a process making a chmod request. So
now we actually /can/ determine if a file's gid is a in the group list
of the process that initiated a fuse request. Let's implement that too.
Darrick J. Wong [Wed, 21 May 2025 22:41:43 +0000 (15:41 -0700)]
fuse2fs: fix post-EOF preallocation clearing on truncation
generic/092 shows that truncating a file to its current size does not
clean out post-eof preallocations like the kernel does. Adopt the
kernel's behavior for consistency.
Darrick J. Wong [Wed, 21 May 2025 22:41:26 +0000 (15:41 -0700)]
fuse2fs: fix removing ea inodes when freeing a file
If the filesystem has ea_inode set, then each file that has xattrs might
have stored an xattr value in a separate inode. These inodes also need
to be freed, so create a library function to do that, and call it from
the fuse2fs unlink method. Seen by ext4/026.
Darrick J. Wong [Wed, 21 May 2025 22:41:11 +0000 (15:41 -0700)]
fuse2fs: fix return value handling
For the xattr functions, don't obliterate the return value of the file
system operation with an error code coming from ext2fs_xattrs_close
failing. Granted, it doesn't ever fail (right now!) so this is mostly
just preening.
Also fix the obsolete op_truncate not to squash error returns.
Darrick J. Wong [Wed, 21 May 2025 22:40:23 +0000 (15:40 -0700)]
fuse2fs: decode fuse_main error codes
Translate the fuse_main return values into actual mount(8) style error
codes instead of returning 0 all the time, and print something to the
original stderr if something went wrong so that the user will know what
to do next.