1- From 198c0dbea9c6f2e791cb253a4e5bae0b72bcf66a Mon Sep 17 00:00:00 2001
1+ From 062bd2be58d14b8bf8265e9bfdc5b5474211c145 Mon Sep 17 00:00:00 2001
22From: "github-actions[bot]"
33 <41898282+github-actions[bot]@users.noreply.github.com>
4- Date: Sat, 11 Apr 2026 19:12:14 +0000
4+ Date: Sat, 25 Apr 2026 19:27:39 +0000
55Subject: [PATCH] Add APFS driver
66
77---
@@ -31,15 +31,15 @@ Subject: [PATCH] Add APFS driver
3131 fs/apfs/object.c | 315 +++
3232 fs/apfs/snapshot.c | 687 +++++++
3333 fs/apfs/spaceman.c | 1479 ++++++++++++++
34- fs/apfs/super.c | 2190 ++++++++++++++++++++
34+ fs/apfs/super.c | 2263 + ++++++++++++++++++++
3535 fs/apfs/symlink.c | 80 +
3636 fs/apfs/transaction.c | 1034 ++++++++++
3737 fs/apfs/unicode.c | 3156 +++++++++++++++++++++++++++++
3838 fs/apfs/unicode.h | 27 +
3939 fs/apfs/version.h | 1 +
4040 fs/apfs/xattr.c | 914 +++++++++
4141 fs/apfs/xfield.c | 171 ++
42- 34 files changed, 27036 insertions(+)
42+ 34 files changed, 27109 insertions(+)
4343 create mode 100644 fs/apfs/Makefile
4444 create mode 100644 fs/apfs/apfs.h
4545 create mode 100644 fs/apfs/apfs_raw.h
@@ -19696,10 +19696,10 @@ index 000000000..31bf439e9
1969619696+}
1969719697diff --git a/fs/apfs/super.c b/fs/apfs/super.c
1969819698new file mode 100644
19699- index 000000000..0f8709ba7
19699+ index 000000000..bcc353a33
1970019700--- /dev/null
1970119701+++ b/fs/apfs/super.c
19702- @@ -0,0 +1,2190 @@
19702+ @@ -0,0 +1,2263 @@
1970319703+// SPDX-License-Identifier: GPL-2.0-only
1970419704+/*
1970519705+ * Copyright (C) 2018 Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com>
@@ -19719,6 +19719,7 @@ index 000000000..0f8709ba7
1971919719+#include "version.h"
1972019720+#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 0, 0)
1972119721+#include <linux/fs_context.h>
19722+ +#include <linux/fs_parser.h>
1972219723+#endif
1972319724+
1972419725+#define APFS_MODULE_ID_STRING "linux-apfs by eafer (" GIT_COMMIT ")"
@@ -20905,6 +20906,7 @@ index 000000000..0f8709ba7
2090520906+ Opt_readwrite, Opt_cknodes, Opt_uid, Opt_gid, Opt_vol, Opt_snap, Opt_tier2, Opt_err,
2090620907+};
2090720908+
20909+ +#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 0, 0)
2090820910+static const match_table_t tokens = {
2090920911+ {Opt_readwrite, "readwrite"},
2091020912+ {Opt_cknodes, "cknodes"},
@@ -20915,6 +20917,18 @@ index 000000000..0f8709ba7
2091520917+ {Opt_tier2, "tier2=%s"},
2091620918+ {Opt_err, NULL}
2091720919+};
20920+ +#else
20921+ +static const struct fs_parameter_spec apfs_param_spec[] = {
20922+ + fsparam_flag ("readwrite", Opt_readwrite),
20923+ + fsparam_flag ("cknodes", Opt_cknodes),
20924+ + fsparam_uid ("uid", Opt_uid),
20925+ + fsparam_gid ("gid", Opt_gid),
20926+ + fsparam_u32 ("vol", Opt_vol),
20927+ + fsparam_string ("snap", Opt_snap),
20928+ + fsparam_string ("tier2", Opt_tier2),
20929+ + {}
20930+ +};
20931+ +#endif
2091820932+
2091920933+/**
2092020934+ * apfs_set_nx_flags - Set the mount flags for the container, if allowed
@@ -20954,6 +20968,26 @@ index 000000000..0f8709ba7
2095420968+ }
2095520969+}
2095620970+
20971+ +/**
20972+ + * apfs_set_default_opts - Set the default mount options in the superblock
20973+ + * @sbi: in-memory superblock info
20974+ + */
20975+ +static void apfs_set_default_opts(struct apfs_sb_info *sbi)
20976+ +{
20977+ + sbi->s_vol_nr = 0;
20978+ + sbi->s_snap_name = NULL;
20979+ + sbi->s_tier2_path = NULL;
20980+ + sbi->s_mount_opt = 0;
20981+ +#ifdef CONFIG_APFS_RW_ALWAYS
20982+ + /* Still risky, but some packagers want writable mounts by default */
20983+ + sbi->s_mount_opt |= APFS_READWRITE;
20984+ +#endif
20985+ + sbi->s_uid = INVALID_UID;
20986+ + sbi->s_gid = INVALID_GID;
20987+ +}
20988+ +
20989+ +#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 0, 0)
20990+ +
2095720991+/*
2095820992+ * Many of the parse_options() functions in other file systems return 0
2095920993+ * on error. This one returns an error code, and 0 on success.
@@ -20968,20 +21002,6 @@ index 000000000..0f8709ba7
2096821002+ int option;
2096921003+ int err = 0;
2097021004+
20971- + /* Set default values before parsing */
20972- + sbi->s_vol_nr = 0;
20973- + sbi->s_snap_name = NULL;
20974- + sbi->s_tier2_path = NULL;
20975- + sbi->s_mount_opt = 0;
20976- +
20977- +#ifdef CONFIG_APFS_RW_ALWAYS
20978- + /* Still risky, but some packagers want writable mounts by default */
20979- + sbi->s_mount_opt |= APFS_READWRITE;
20980- +#endif
20981- +
20982- + sbi->s_uid = INVALID_UID;
20983- + sbi->s_gid = INVALID_GID;
20984- +
2098521005+ if (!options)
2098621006+ return 0;
2098721007+
@@ -21053,6 +21073,62 @@ index 000000000..0f8709ba7
2105321073+ return 0;
2105421074+}
2105521075+
21076+ +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(7, 0, 0) */
21077+ +
21078+ +static int apfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
21079+ +{
21080+ + struct apfs_sb_info *sbi = fc->s_fs_info;
21081+ + int opt;
21082+ + struct fs_parse_result result;
21083+ +
21084+ + opt = fs_parse(fc, apfs_param_spec, param, &result);
21085+ + if (opt < 0)
21086+ + return opt;
21087+ +
21088+ + switch (opt) {
21089+ + case Opt_readwrite:
21090+ + /*
21091+ + * Write support is not safe yet, so keep it disabled
21092+ + * unless the user requests it explicitly.
21093+ + */
21094+ + sbi->s_mount_opt |= APFS_READWRITE;
21095+ + break;
21096+ + case Opt_cknodes:
21097+ + /*
21098+ + * Right now, node checksums are too costly to enable
21099+ + * by default. TODO: try to improve this.
21100+ + */
21101+ + sbi->s_mount_opt |= APFS_CHECK_NODES;
21102+ + break;
21103+ + case Opt_uid:
21104+ + sbi->s_uid = result.uid;
21105+ + break;
21106+ + case Opt_gid:
21107+ + sbi->s_gid = result.gid;
21108+ + break;
21109+ + case Opt_vol:
21110+ + sbi->s_vol_nr = result.uint_32;
21111+ + break;
21112+ + case Opt_snap:
21113+ + kfree(sbi->s_snap_name);
21114+ + sbi->s_snap_name = kstrdup(param->string, GFP_KERNEL);
21115+ + if (!sbi->s_snap_name)
21116+ + return -ENOMEM;
21117+ + break;
21118+ + case Opt_tier2:
21119+ + kfree(sbi->s_tier2_path);
21120+ + sbi->s_tier2_path = kstrdup(param->string, GFP_KERNEL);
21121+ + if (!sbi->s_tier2_path)
21122+ + return -ENOMEM;
21123+ + break;
21124+ + default:
21125+ + return -EINVAL;
21126+ + }
21127+ + return 0;
21128+ +}
21129+ +
21130+ +#endif
21131+ +
2105621132+/**
2105721133+ * apfs_check_nx_features - Check for unsupported features in the container
2105821134+ * @sb: superblock structure
@@ -21626,6 +21702,7 @@ index 000000000..0f8709ba7
2162621702+ sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
2162721703+ if (!sbi)
2162821704+ return ERR_PTR(-ENOMEM);
21705+ + apfs_set_default_opts(sbi);
2162921706+ /* Set up the fields that sget() will need to id the superblock */
2163021707+ error = parse_options(sbi, data);
2163121708+ if (error)
@@ -21825,16 +21902,11 @@ index 000000000..0f8709ba7
2182521902+ }
2182621903+}
2182721904+
21828- +static int apfs_parse_monolithic(struct fs_context *fc, void *data)
21829- +{
21830- + return parse_options(fc->s_fs_info, data);
21831- +}
21832- +
2183321905+static const struct fs_context_operations apfs_context_ops = {
2183421906+ .get_tree = apfs_get_tree,
2183521907+ .reconfigure = apfs_reconfigure,
2183621908+ .free = apfs_free_fc,
21837- + .parse_monolithic = apfs_parse_monolithic ,
21909+ + .parse_param = apfs_parse_param ,
2183821910+};
2183921911+
2184021912+static int apfs_init_fs_context(struct fs_context *fc)
@@ -21845,6 +21917,7 @@ index 000000000..0f8709ba7
2184521917+ sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
2184621918+ if (!sbi)
2184721919+ return -ENOMEM;
21920+ + apfs_set_default_opts(sbi);
2184821921+
2184921922+ fc->s_fs_info = sbi;
2185021923+ fc->ops = &apfs_context_ops;
@@ -26213,11 +26286,11 @@ index 000000000..e3b7edc51
2621326286+#endif /* _APFS_UNICODE_H */
2621426287diff --git a/fs/apfs/version.h b/fs/apfs/version.h
2621526288new file mode 100644
26216- index 000000000..8fe4f14f1
26289+ index 000000000..e16b23c10
2621726290--- /dev/null
2621826291+++ b/fs/apfs/version.h
2621926292@@ -0,0 +1 @@
26220- +#define GIT_COMMIT "v0.3.19 "
26293+ +#define GIT_COMMIT ""
2622126294diff --git a/fs/apfs/xattr.c b/fs/apfs/xattr.c
2622226295new file mode 100644
2622326296index 000000000..c21b8e469
0 commit comments