Commit Graph

31 Commits

Author SHA1 Message Date
Ernesto A. Fernández a3c23dffc3 Don't reference page index in 6.16
The build is broken for the 6.16 release candidate:

  https://github.com/linux-apfs/linux-apfs-rw/issues/99

The problem is that the page struct no longer has a member called
"index". Use folios for this instead.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-07-01 20:45:23 -03:00
Ernesto A. Fernández e41b8f1f0e Handle page functions newly removed in 6.15
It seems that wait_for_stable_page(), page_has_buffers() and
grab_cache_page_write_begin() are no longer available, so put
implementations inside the driver.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-21 18:31:15 -03:00
Ernesto A. Fernández 3174e363ad Simplify ENOSPC checks before transactions
If a function throws ENOSPC halfway through an operation, the
transaction will get aborted so that the filesystem isn't left in an
inconsistent state. This means that the mount will go read-only, and
that the user will lose any uncommitted changes.

So, it's better if we detect ENOSPC before starting an operation. I
tried this before with commit a52b73ed97 ("Check free space before
starting a transaction"), but the code was messy and it would have
required constant updates, which I neglected of course. The problem was
that I wanted to be as accurate as possible with my calculations of
required space, but I'm not sure there is any point.

Instead, require a large fixed amount of space (512 KiB) for most
operations, and a much smaller but still almost certainly sufficient
amount of space (80 KiB) for deletions. Hopefully this will be enough
for users to maneuver around ENOSPC situations. It's not perfect, but no
CoW filesystem can be truly perfect in this regard.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-03-11 16:15:41 -03:00
Ernesto A. Fernández afe9bac8f2 Actually add support for RHEL 9
The build is still broken for redhat kernels:

  https://github.com/linux-apfs/linux-apfs-rw/issues/89#issuecomment-2691955523

Fix the remaining issues. For the previous patch I was just looking at
the source, but this time I set up a rhel vm and tried a build and a
mount for each of the 9.x kernels, so hopefully it's over. I didn't know
you could get rhel for free as a developer, I guess it makes sense.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-03-03 19:43:17 -03:00
Ernesto A. Fernández 412c4c8f9c Add support for RHEL 9
The build is broken for redhat kernels:

  https://github.com/linux-apfs/linux-apfs-rw/issues/89

This seems to have been the case for more than a year, but nobody had
reported it so far, so I guess the driver isn't getting much use over
there.

We had encountered a similar problem before in commit 1a0b9fb8af ("Fix
build for RHEL 9 kernels"), but back then I thought it was just a
one-off thing. I was wrong: redhat kernels often backport patches that
break internal apis. I don't know how other out-of-tree drivers handle
this, but for now I will have to rely on user reports.

So, go through all RHEL 9 kernels one by one, find out which api changes
were applied to each, and add the corresponding macro version checks to
the driver.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-02-28 19:45:33 -03:00
Woody Suwalski 60ef1e9991 Building on kernel 6.8
[eafer: moved bdev handle to the container superblock]
2024-03-10 20:58:42 -03:00
Woody Suwalski 5dc836ad96 Support for kernel 6.7
[eafer: fixed some issues with folios and timestamps]
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2024-01-07 16:27:45 -03:00
Ernesto A. Fernández 225a17aa77 Set splice read/write methods explicitly
Several of xfstests (generic/249 for example) are failing on kernel 6.6
because of sendfile issues. Starting with upstream commit 36e2c7421f02
("fs: don't allow splice read/write without explicit ops"), the
->splice_read() and ->splice_write() methods need to be set explicitly,
or else we just get EINVAL when sendfile needs them. This change
happened in the 5.10 release, but I never noticed because I usually only
run tests on 5.3.

So, set the methods as required, taking into consideration the kernel
version because there was another related change in commit 2cb1e08985e3
("splice: Use filemap_splice_read() instead of
generic_file_splice_read()").

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-10-27 22:13:05 -03:00
Ernesto A. Fernández 2d6cdba8f6 Fix trivial style issues
Some code that wasn't originally written by me has a style that differs
slightly from the rest of the module. Since I've been refactoring
compress.c quite a lot lately, I have made the inconsistencies more
visible, so I think it's a good time to switch everything to the typical
kernel style.

For this purpose I'm running checkpatch.pl for the first time in years,
and it has detected a handful of other issues that I introduced myself.
Fix most of the issues now, but I prefer to leave the zero-length array
stuff for a separate patch.

For the record, at the moment I'm choosing to ignore style inconsistency
in the compression libraries, even in libzbitmap which I wrote myself. I
prefer to keep them as close to upstream as possible.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-10-26 21:44:30 -03:00
Woody Suwalski 1bca725a63 Fix for the kernel 6.6 build errors
[eafer: removed unnecessary setting of some timestamps]
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-10-25 22:43:27 -03:00
Ernesto A. Fernández e99d7b4d51 Get rid of apfs_compress_file_mmap()
When compressed mmap was implemented, apfs_compress_file_mmap() was
added with the purpose of ignoring calls to ->page_mkwrite(). With the
last patch, I no longer allow compressed files to be opened for writing
at all, so I can just use regular ->mmap() for all files.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-10-06 20:18:31 -03:00
Ernesto A. Fernández b185ce13bd Fix builds before generic_copy_file_range()
Even with the previous patch, builds are still broken for all kernels
before 5.2. The problem is that generic_copy_file_range() wasn't
introduced until Linux 5.3. The good news is that we don't actually need
it for older kernels: as I explained in the commit message for the patch
that broke this, we can just returning an error code from
apfs_remap_file_range().

Fixes: 396650b056 ("Don't let copy_file_range() use clones")
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-05-19 18:31:51 -03:00
Ernesto A. Fernández 42d70a8997 Fix build for kernels with separate clone/dedupe
Luflosi reports that the build is broken once again for Linux 4.14 and
4.19:

  https://github.com/linux-apfs/linux-apfs-rw/issues/43

The problem here is that the clone and dedupe operations used to be
implemented with separate methods. Since Linux 4.20, they both use the
same ->remap_file_range(), with some flags passed to tell them apart.
So when I implemented clones I used this new version and broke the build
for the old ones. Fix it now.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-05-19 18:31:51 -03:00
Ernesto A. Fernández d4797823ea Improve error reporting
The driver is much closer to being usable, so I might start getting
subtler bug reports soon. To make them easier to handle, put error
messages all over the place. I should have done this from the beginning,
but I guess I didn't fully understand the need back then.

From now my general policy will be to use apfs_warn() for user errors or
unsupported features; apfs_err() for things that are probably corruption
or io errors; and apfs_alert() for things that are most likely bugs.
These last two should be rare, so the same error/alert will be thrown by
several layers in the callstack to provide as much information as
possible. Be careful and don't flood the console on normal situations.

Also, make messages with a log level lower than warning output their
function name and line number, which I think will help debugging more
than the actual messages.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-04-05 21:59:24 -03:00
Ernesto A. Fernández 7ea6920bc4 Give a clone its own dstream before mmap writes
Call apfs_inode_create_exclusive_dstream() during mkwrite(), just like
we do during write_begin(), or else things could get weird for cloned
files. This patch fixes generic/140 of xfstests.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-03-22 19:18:34 -03:00
Ernesto A. Fernández 1490bc7d36 Support FIEMAP for the 5.3 kernel
I'm trying to run the "clone" group of xfstests, but it seems that those
tests require the FIEMAP ioctl to confirm that clones share the same
physical extents. This doesn't seem trivial to implement for all kernel
versions, so for now only do it for 5.3, the one I use for testing.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-03-22 16:14:02 -03:00
Ernesto A. Fernández 396650b056 Don't let copy_file_range() use clones
I'm seeing a silly regression in generic/430: now that clones are
implemented, copy_file_range() has started to use them under the hood,
but it only wants to clone a portion of the file, and that's not
something I'm interested in supporting.

To avoid this on newer kernels, set ->copy_file_range() to the generic
implementation. For older kernels, start throwing errors if anything
calls apfs_remap_file_range() for partial ranges. This is the right
thing to do in general, since we don't support that.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-03-17 17:20:49 -03:00
Ernesto A. Fernández 573fe59e7f Implement basic file cloning functionality
Implement the FICLONE ioctl to be able to create clones of files. This
will never work the same as macos, because Linux requires that the user
first creates the target file, and only then it can be made into a
clone. A crash halfway throught would leave an empty file in place of
the clone.

This patch only duplicates the data stream, it does not deal with the
actual extents. Reads from clones should work correctly, but writes will
not. I'll get to that right away.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2023-03-08 22:22:18 -03:00
Ernesto A. Fernández ef2fd276bc Fix build for Linux 5.19
The build is broken for the 5.19 kernel:

  https://github.com/linux-apfs/linux-apfs-rw/issues/29

Pages have been replaced by folios in most interfaces, so start using
them. Also the 'flags' argument to grab_cache_page_write_begin() is
gone; instead use memalloc_nofs_save()/memalloc_nofs_restore() to
prevent recursion into the filesystem.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2022-08-14 18:57:23 -03:00
Ernesto A. Fernández dc1ed2cfe7 Rename SPDX license identifier
It seems that the license identifier currently in use (GPL-2.0) has been
deprecated:

  https://spdx.org/licenses/GPL-2.0.html

I don't know how important this is in practice, but I've received some
complaints about it:

  https://github.com/linux-apfs/linux-apfs-rw/issues/18

So, just run

  sed -i 's/2\.0/2.0-only/' *.{c,h}
  sed -i 's/2\.0/2.0-only/' Makefile

and change it to GPL-2.0-only.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-11-16 18:41:54 -03:00
Ernesto A. Fernández 039bdd5940 Don't commit transactions during ->write_inode()
Since last commit 0a48c4e603 ("Re-enable readahead"), ->write_inode()
has started to fire. I had noticed long ago that it wasn't working, but
I didn't know the reason, and it turns out that the problem was the same
that readahead had: the backing_dev_info.

Sadly, this has caused some problems. If ->write_inode() happens to
trigger a transaction commit, the commit will try to manipulate the same
inode and end with a deadlock. To prevent this, avoid commits during
->write_inode() using the existing APFS_NX_TRANS_DEFER_COMMIT
transaction state. Since it is now possible for the transaction to be
in both the DEFER_COMMIT and the COMMITTING states, rework the states to
be flags.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-10-18 18:59:50 -03:00
Ernesto A. Fernández 9c117a8126 Actually fix ->page_mkwrite() for before 4.11
Recent commit 7a94546cb7 ("Fix signature of ->page_mkwrite() for
before 4.11") attempted to support old kernels that didn't keep the
vm_area_struct as a field inside vm_fault. But I didn't realize that the
field was being accessed at several points of apfs_page_mkwrite(), so
the kernel is still not building. Fix this.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-09-14 13:47:35 -03:00
Ernesto A. Fernández 7a94546cb7 Fix signature of ->page_mkwrite() for before 4.11
On ->page_mkwrite(), newer kernels need to retrieve the vm_area_struct
pointer from the vm_fault. For older kernels this would not have been
possible, and the vm_area_struct was passed as an argument instead.
Use macros to get all versions to build.

This problem was reported by Luflosi here:

  https://github.com/linux-apfs/linux-apfs-rw/issues/19#issuecomment-918033297

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-09-13 13:29:42 -03:00
Ernesto A. Fernández f279e25de4 Provide vm_fault_t for older kernels
The vm_fault_t return type was only added for kernel 4.17. Before that,
->page_mkwrite() would just return an int, so fix the build with a
typedef. This problem was reported by Luflosi here:

  https://github.com/linux-apfs/linux-apfs-rw/issues/19#issuecomment-918033297

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-09-13 13:29:06 -03:00
Ernesto A. Fernández c340dfdee2 Fix SETFLAGS/GETFLAGS ioctls for newer kernels
Luflosi is reporting new build issues:

  https://github.com/linux-apfs/linux-apfs-rw/issues/19

These problems started when I implemented the FS_IOC_SETFLAGS and
FS_IOC_GETFLAGS ioctls. These ioctls have become officially supported by
the vfs recently, and then some of the helpers I was using got removed.
The proper way to implement this in newer kernels is through inode
methods ->apfs_fileattr_get() and ->apfs_fileattr_set().

So do that, and also fix a new instance of the typical build issue with
new namespace parameters. This time I've taken the trouble to build-test
this with a 5.13 kernel, and I even ran xfstests, so there shouldn't be
any more problems, at least not with that version.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2021-09-12 20:06:26 -03:00