Starting with the 7.2 kernel, buffer heads no longer lose a reference
during the submit-wait procedure. I didn't notice that change, so now I
would expect all buffer heads to be leaking. The fact that I still can't
tell the difference makes me believe, like I mentioned before, that
somehow the kernel is still disposing of the buffer heads. Either way,
fix this.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
This is the last of the three leaks discovered by Valgrind in the
userland port. During the loop that writes ephemeral objects to disk,
checkpoint mapping blocks are created and kept around for multiple
iterations until they are full. At that point, the cpm buffer head gets
released and we get a new one. All that looks correct, but no release
happens after the final loop. Fix it.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
This is the second bug discovered by valgrind in the userland tool. The
buffer head for the ip bitmap gets nulled after joining the transaction,
but we still hold a reference to it (the transactions takes a new one).
Fix it.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Work on the userland port with valgrind has reavealed a number of
longstanding leaks in the kernel driver. For some reason I always
assumed that kmemleak would eventually notice issues with buffer heads,
but it clearly doesn't. This bug in particular must have been around
since the very beginning: all buffer heads for checkpoint descriptor
blocks get leaked during mount.
Since nobody noticed the problem so far, I'm guessing that the kernel
somehow disposes of abandoned buffer heads. Perhaps it has something to
do with the old issue from patch 517dd221df ("Forcefully free buffer
heads on transaction commit")? Either way, fix the leak and get the code
to match the userland port.
One thing to note: before pushing this patch I tried asking Github
Copilot to look for leaks in the super.c file and it spotted the problem
immediately. It seems to have become far more useful since the last time
I tried it, so once I'm done fixing the current crop of leaks I should
try and see what it can find.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
The build is broken for the 7.2 release candidate. The reason is that
submit_bh() is gone now, replaced with a new bh_submit() that also takes
the I/O end handler as an argument. Adjust apfs_submit_bh() to these
changes.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
I've been trying to build the driver for userland lately. Most of the
code can be left as it is as long as I spoof the kernel headers and
everything else that the kernel provides. The one exception is my
uintmax_t typedef, because macos is very determined to provide its own
definition for that type. I guess that makes sense, given that the lzfse
code came from Apple in the first place.
Anyway, none of this is a problem for the driver, but since I want to
keep both codebases identical, put the same macro guards in here.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
I notice a lot of traffic to the following issue:
https://github.com/linux-apfs/linux-apfs-rw/issues/96
Recent distro kernels seem to ship with a built-in libcrc32c, so the
modprobe step described in the README is not necessary and will fail. I
assumed it would be clear to the users that they can just keep going
when that happens, but some of them are being extra careful, which is
probably the right attitude to have when dealing with a filesystem.
Rephrase the README to make it clear that the modprobe step is not
usually needed anymore.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
This quick release adds support for the fsconfig() syscall, otherwise
newer versions of the mount tool won't accept any options.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
SergDL reports that mounts seem broken for the 7.0 kernel:
https://github.com/linux-apfs/linux-apfs-rw/issues/119
I never encountered this problem during testing, probably because my
version of the mount tool is older. It seems that mount options are now
set one by one using the fsconfig() syscall, and that's not possible if
we parse them all at once with ->parse_monolithic().
Implement ->parse_param() instead, at least for the latest kernel. I do
wonder if this issue won't pop up with older kernels though, since the
fsconfig() syscall has been around since 5.2. I guess I'll wait to see
if somebody complains about it.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Instead of setting the default mount options right before parsing the
actual options, set them on the superblock as soon as it gets allocated.
This will allow the parsing code to be called more than once by the new
mount api.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
The new mount api forces me to make one function call for each option to
parse. This change means that the default options will need to get set
elsewhere, otherwise each new call would reset to default.
As a first step, move that code from parse_options() into a new
apfs_set_default_opts().
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
This release adds support for the upcoming 7.0 kernel version, with a
patch by Alessio Faina. Aditya Garg also contributes a fix for a build
issue caused by the makefile.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Reorganize the version check in the out_free_sbi label to better match
the simpler one at out_unmap_super.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Following the previous patch, which made parse_options() always run
right after preparse_options(), merge both functions into one.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Since the mount api conversion, kernel version 7.0 and above parse all
the options at once before moving on to the rest of the mount process.
There is no reason that other kernel versions can't do the same; in fact
that was originally my intention, as explained in the commit message for
af2ee526c0 ("Avoid double parsing of mount options"). So always call
parse_options() right after preparse_options(). The plan is to unify
these functions next.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Inside parse_options(), some kernel versions retrieve the superblock
info from the vfs superblock, while others retrieve it from the
filesystem context. Instead just pass the info as an argument and
simplify the version checks.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
I seem to have missed a few whitespace issues during my review of the
recent mount api conversion. Fix them now.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
At this point, the nx_flags variable only exists to get copied into
s_mount_opt of the superblock. Just work with s_mount_opt directly and
get rid of the goto label.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
I'm trying to unify mount option processing across kernel versions as
much as possible. Instead of calling parse_options_set_flags() directly
from parse_options() whenever possible, always set the new s_mount_opt
and use it to call parse_options_set_flags() later.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Move s_uid/s_gid initialization inside parse_options() for all kernel
versions, getting rid of a version check for kernels 7.0 and above.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
As all the in-tree modules has been ported to the new Kernel 7
fs mount API, the old API has been removed.
This patch add the support for the new set of APIs, while
keeping previous kernel support intact.
The code is in review on the Canonical Launchpad bug
https://launchpad.net/bugs/2142837 as well
Signed-off-by: Alessio Faina <alessio.faina@canonical.com>