4 Commits
Author SHA1 Message Date
Ernesto A. Fernández 8a37600293 0.3.21
This release adds support for the upcoming 7.2 kernel version.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2026-08-12 15:42:53 -03:00
Ernesto A. Fernández f0e88ca368 Switch to bh_submit() for kernel 7.2
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>
2026-07-14 19:38:12 -03:00
Ernesto A. Fernández 96d5614d04 Put macos macro guards around uintmax_t typedef
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>
2026-06-24 17:41:11 -03:00
Ernesto A. Fernández b2418aaaa7 Clarify the modprobe situation in the README
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>
2026-05-27 16:58:08 -03:00
7 changed files with 35 additions and 10 deletions

No files matched your search

+7 -2
View File
@@ -57,10 +57,15 @@ Now you can just cd to the linux-apfs-rw directory and run::
make
The resulting module is the apfs.ko file. Before you can use it you must insert
it into the kernel, as well as its dependencies. Again as root::
it into the kernel. Again as root::
insmod apfs.ko
If you get an "unknown symbol in module" error, run::
modprobe libcrc32c
insmod apfs.ko
and then try the insmod command again.
Mount
=====
+25 -3
View File
@@ -44,10 +44,32 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags
#endif
/* Compatibility wrapper around submit_bh() */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || RHEL_VERSION_GE(9, 2)
#define apfs_submit_bh(op, op_flags, bh) submit_bh(op | op_flags, bh)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
#define apfs_submit_bh(op, op_flags, bh) \
do { \
if (op == REQ_OP_READ) \
bh_submit(bh, op | op_flags, bh_end_read); \
else \
bh_submit(bh, op | op_flags, bh_end_write); \
} while (0)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || RHEL_VERSION_GE(9, 2)
#define apfs_submit_bh(op, op_flags, bh) \
do { \
if (op == REQ_OP_READ) \
bh->b_end_io = end_buffer_read_sync; \
else \
bh->b_end_io = end_buffer_write_sync; \
submit_bh(op | op_flags, bh); \
} while (0)
#else
#define apfs_submit_bh(op, op_flags, bh) submit_bh(op, op_flags, bh)
#define apfs_submit_bh(op, op_flags, bh) \
do { \
if (op == REQ_OP_READ) \
bh->b_end_io = end_buffer_read_sync; \
else \
bh->b_end_io = end_buffer_write_sync; \
submit_bh(op, op_flags, bh); \
} while (0)
#endif
/*
+1 -1
View File
@@ -1,5 +1,5 @@
PACKAGE_NAME="linux-apfs-rw"
PACKAGE_VERSION="0.3.20"
PACKAGE_VERSION="0.3.21"
BUILT_MODULE_NAME[0]="apfs"
DEST_MODULE_LOCATION[0]="/extra"
-2
View File
@@ -2298,7 +2298,6 @@ int apfs_nonsparse_dstream_read(struct apfs_dstream_info *dstream, void *buf, si
if (!buffer_uptodate(bh)) {
get_bh(bh);
lock_buffer(bh);
bh->b_end_io = end_buffer_read_sync;
apfs_submit_bh(REQ_OP_READ, 0, bh);
}
}
@@ -2365,7 +2364,6 @@ void apfs_nonsparse_dstream_preread(struct apfs_dstream_info *dstream)
if (!buffer_uptodate(bh)) {
get_bh(bh);
lock_buffer(bh);
bh->b_end_io = end_buffer_read_sync;
apfs_submit_bh(REQ_OP_READ, 0, bh);
}
brelse(bh);
-1
View File
@@ -556,7 +556,6 @@ int __apfs_write_begin(struct file *file, struct address_space *mapping, loff_t
if (buffer_mapped(bh) && !buffer_uptodate(bh)) {
get_bh(bh);
lock_buffer(bh);
bh->b_end_io = end_buffer_read_sync;
apfs_submit_bh(REQ_OP_READ, 0, bh);
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
+2
View File
@@ -70,7 +70,9 @@ typedef int64_t lzfse_offset;
typedef int32_t lzfse_offset;
#endif
#if !defined(__APPLE__) || !defined(__MACH__)
typedef uint64_t uintmax_t;
#endif
/*! @abstract Decoder state object for lzfse compressed blocks. */
typedef struct {
-1
View File
@@ -721,7 +721,6 @@ static int apfs_transaction_commit_nx(struct super_block *sb)
clear_buffer_dirty(bh);
get_bh(bh);
lock_buffer(bh);
bh->b_end_io = end_buffer_write_sync;
apfs_submit_bh(REQ_OP_WRITE, REQ_SYNC, bh);
}
list_for_each_entry_safe(bhi, tmp, &nx_trans->t_buffers, list) {