4 Commits
Author SHA1 Message Date
Ernesto A. Fernández 1db8a6d92a 0.3.18
This release adds support for the upcoming 6.19 kernel version.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2026-01-30 18:44:25 -03:00
Ernesto A. Fernández a3bca211bd Don't access inode state directly in 6.19
The build is broken for the 6.19 release candidate:

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

The problem is that the inode i_state field can no longer be accessed
directly. Switch to the new helpers, using a wrapper to keep the code
consistent for all kernel versions.

Note that I always use the *_raw version of the helpers to avoid a lockdep
check that will not pass. I can't tell for sure if this is a bug.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-12-30 20:51:14 -03:00
Ernesto A. Fernández de721cd995 0.3.17
This release adds support for the upcoming 6.18 kernel version.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-11-26 18:28:54 -03:00
Ernesto A. Fernández 0daf28cef7 Always treat ->d_name as const
The build is broken for the 6.18 release candidate:

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

The problem is that ->d_name has become const, and that qualifier gets
dropped when we pass it around in the driver. Just treat is as const for
all kernel versions.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-10-27 22:30:27 -03:00
5 changed files with 38 additions and 10 deletions

No files matched your search

+27
View File
@@ -1216,6 +1216,33 @@ static inline void apfs_assert_query_is_valid(const struct apfs_query *query)
#define page_has_buffers(page) folio_buffers(page_folio(page))
#endif
static inline int apfs_inode_state_read_once(struct inode *inode)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 19, 0)
return inode_state_read_once(inode);
#else
return inode->i_state;
#endif
}
static inline void apfs_inode_state_set_raw(struct inode *inode, int flags)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 19, 0)
inode_state_set_raw(inode, flags);
#else
inode->i_state |= flags;
#endif
}
static inline void apfs_inode_state_clear_raw(struct inode *inode, int flags)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 19, 0)
inode_state_clear_raw(inode, flags);
#else
inode->i_state &= ~flags;
#endif
}
/*
* TODO: the following are modified variants of buffer head functions that will
* work with the shared block device for the container. The correct approach
+7 -6
View File
@@ -261,7 +261,7 @@ const struct file_operations apfs_dir_operations = {
*
* Returns the length of the key, or a negative error code in case of failure.
*/
static int apfs_build_dentry_unhashed_key(struct qstr *qname, u64 parent_id,
static int apfs_build_dentry_unhashed_key(const struct qstr *qname, u64 parent_id,
struct apfs_drec_key **key_p)
{
struct apfs_drec_key *key;
@@ -290,7 +290,7 @@ static int apfs_build_dentry_unhashed_key(struct qstr *qname, u64 parent_id,
*
* Returns the length of the key, or a negative error code in case of failure.
*/
static int apfs_build_dentry_hashed_key(struct qstr *qname, u64 hash, u64 parent_id,
static int apfs_build_dentry_hashed_key(const struct qstr *qname, u64 hash, u64 parent_id,
struct apfs_drec_hashed_key **key_p)
{
struct apfs_drec_hashed_key *key;
@@ -363,7 +363,7 @@ static int apfs_build_dentry_val(struct inode *inode, u64 sibling_id,
*
* Returns 0 on success or a negative error code in case of failure.
*/
static int apfs_create_dentry_rec(struct inode *inode, struct qstr *qname,
static int apfs_create_dentry_rec(struct inode *inode, const struct qstr *qname,
u64 parent_id, u64 sibling_id)
{
struct super_block *sb = inode->i_sb;
@@ -426,7 +426,7 @@ static int apfs_build_sibling_val(struct dentry *dentry,
struct apfs_sibling_val **val_p)
{
struct apfs_sibling_val *val;
struct qstr *qname = &dentry->d_name;
const struct qstr *qname = &dentry->d_name;
u16 namelen = qname->len + 1; /* We count the null-termination */
struct inode *parent = d_inode(dentry->d_parent);
int val_len;
@@ -1255,9 +1255,10 @@ static void __apfs_undo_unlink(struct dentry *dentry)
{
struct inode *inode = d_inode(dentry);
inode->i_state |= I_LINKABLE; /* Silence warning about nlink 0->1 */
/* Silence warning about nlink 0->1 */
apfs_inode_state_set_raw(inode, I_LINKABLE);
inc_nlink(inode);
inode->i_state &= ~I_LINKABLE;
apfs_inode_state_clear_raw(inode, I_LINKABLE);
apfs_undo_delete_dentry(dentry);
}
+1 -1
View File
@@ -1,5 +1,5 @@
PACKAGE_NAME="linux-apfs-rw"
PACKAGE_VERSION="0.3.16"
PACKAGE_VERSION="0.3.18"
BUILT_MODULE_NAME[0]="apfs"
DEST_MODULE_LOCATION[0]="/extra"
+2 -2
View File
@@ -1037,7 +1037,7 @@ struct inode *apfs_iget(struct super_block *sb, u64 cnid)
inode = apfs_iget_locked(sb, cnid);
if (!inode)
return ERR_PTR(-ENOMEM);
if (!(inode->i_state & I_NEW))
if (!(apfs_inode_state_read_once(inode) & I_NEW))
return inode;
down_read(&nxi->nx_big_sem);
@@ -1149,7 +1149,7 @@ int apfs_getattr(struct mnt_idmap *idmap,
*
* Returns the length of the value, or a negative error code in case of failure.
*/
static int apfs_build_inode_val(struct inode *inode, struct qstr *qname,
static int apfs_build_inode_val(struct inode *inode, const struct qstr *qname,
struct apfs_inode_val **val_p)
{
struct apfs_inode_val *val;
+1 -1
View File
@@ -468,7 +468,7 @@ int apfs_transaction_flush_all_inodes(struct super_block *sb)
curr_err = apfs_update_inode(inode, NULL /* new_name */);
if (curr_err)
err = curr_err;
inode->i_state &= ~I_DIRTY_ALL;
apfs_inode_state_clear_raw(inode, I_DIRTY_ALL);
/*
* The same inode may get dirtied again as soon as we release