mirror of
https://github.com/linux-apfs/linux-apfs-rw.git
synced 2026-08-18 02:19:59 -07:00
Compare commits
26
Commits
v0.3.17
...
development
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a10279ce66 | ||
|
|
7711c4704e | ||
|
|
9619c53686 | ||
|
|
f5b71842e6 | ||
|
|
83205caaad | ||
|
|
8a37600293 | ||
|
|
f0e88ca368 | ||
|
|
96d5614d04 | ||
|
|
b2418aaaa7 | ||
|
|
628b6810e4 | ||
|
|
7aca589f9e | ||
|
|
36df7e0b35 | ||
|
|
ae381fbc3d | ||
|
|
f95bcc94c9 | ||
|
|
911bbe1743 | ||
|
|
6d54029be9 | ||
|
|
88b36a788e | ||
|
|
ef79bb1bee | ||
|
|
67eb48bb34 | ||
|
|
9aadac614c | ||
|
|
1158bd03a6 | ||
|
|
351c7cf826 | ||
|
|
61672f2caf | ||
|
|
0459ba0998 | ||
|
|
1db8a6d92a | ||
|
|
a3bca211bd |
No files matched your search
@@ -14,9 +14,9 @@ apfs-y := btree.o compress.o dir.o extents.o file.o inode.o key.o libzbitmap.o \
|
||||
spaceman.o super.o symlink.o transaction.o unicode.o xattr.o xfield.o
|
||||
|
||||
# If you want mounts to be writable by default, run the build as:
|
||||
# make CONFIG=-DCONFIG_APFS_RW_ALWAYS
|
||||
# make APFS_CONFIG=-DCONFIG_APFS_RW_ALWAYS
|
||||
# This is risky and not generally recommended.
|
||||
ccflags-y += $(CONFIG)
|
||||
ccflags-y += $(APFS_CONFIG)
|
||||
|
||||
default:
|
||||
./genver.sh
|
||||
|
||||
+7
-2
@@ -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
|
||||
=====
|
||||
|
||||
@@ -44,10 +44,33 @@ 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 { \
|
||||
put_bh(bh); \
|
||||
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
|
||||
|
||||
/*
|
||||
@@ -380,6 +403,7 @@ struct apfs_sb_info {
|
||||
unsigned int s_vol_nr; /* Index of the volume in the sb list */
|
||||
kuid_t s_uid; /* uid to override on-disk uid */
|
||||
kgid_t s_gid; /* gid to override on-disk gid */
|
||||
unsigned int s_mount_opt;
|
||||
|
||||
struct apfs_crypto_state_val *s_dflt_pfk; /* default per-file key */
|
||||
|
||||
@@ -1040,7 +1064,9 @@ extern int apfs_setattr(struct mnt_idmap *idmap,
|
||||
struct dentry *dentry, struct iattr *iattr);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 0, 0)
|
||||
extern int apfs_update_time(struct inode *inode, enum fs_update_time time, unsigned int flags);
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
extern int apfs_update_time(struct inode *inode, struct timespec64 *time, int flags);
|
||||
#else
|
||||
extern int apfs_update_time(struct inode *inode, int flags);
|
||||
@@ -1216,6 +1242,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
|
||||
@@ -1294,7 +1347,7 @@ __apfs_getblk(struct super_block *sb, sector_t block)
|
||||
block -= nxi->nx_tier2_bno;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 7, 0) && !RHEL_VERSION_GE(9, 8)
|
||||
return __getblk_gfp(info->blki_bdev, block, sb->s_blocksize, __GFP_MOVABLE);
|
||||
#else
|
||||
return bdev_getblk(info->blki_bdev, block, sb->s_blocksize, __GFP_MOVABLE);
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
PACKAGE_NAME="linux-apfs-rw"
|
||||
PACKAGE_VERSION="0.3.17"
|
||||
PACKAGE_VERSION="0.3.21"
|
||||
|
||||
BUILT_MODULE_NAME[0]="apfs"
|
||||
DEST_MODULE_LOCATION[0]="/extra"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
@@ -1037,7 +1036,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);
|
||||
@@ -2109,7 +2108,9 @@ fail:
|
||||
}
|
||||
|
||||
/* TODO: this only seems to be necessary because ->write_inode() isn't firing */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 0, 0)
|
||||
int apfs_update_time(struct inode *inode, enum fs_update_time time, unsigned int flags)
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
|
||||
int apfs_update_time(struct inode *inode, struct timespec64 *time, int flags)
|
||||
#else
|
||||
int apfs_update_time(struct inode *inode, int flags)
|
||||
@@ -2123,7 +2124,9 @@ int apfs_update_time(struct inode *inode, int flags)
|
||||
return err;
|
||||
apfs_inode_join_transaction(sb, inode);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && !RHEL_VERSION_GE(9, 6)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 0, 0)
|
||||
generic_update_time(inode, time, flags);
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && !RHEL_VERSION_GE(9, 6)
|
||||
generic_update_time(inode, time, flags);
|
||||
#else
|
||||
generic_update_time(inode, flags);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -308,6 +308,7 @@ static int apfs_write_single_ip_bitmap(struct super_block *sb, char *bitmap, u32
|
||||
err = apfs_transaction_join(sb, bh);
|
||||
if (err)
|
||||
goto fail;
|
||||
put_bh(bh);
|
||||
bh = NULL;
|
||||
|
||||
spaceman->sm_ip_bmaps[idx].dirty = false;
|
||||
|
||||
+4
-2
@@ -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
|
||||
@@ -640,6 +640,9 @@ static int apfs_write_ephemeral_objects(struct super_block *sb)
|
||||
}
|
||||
data_len += obj_blkcnt;
|
||||
}
|
||||
brelse(cpm_bh);
|
||||
cpm = NULL;
|
||||
cpm_bh = NULL;
|
||||
|
||||
/*
|
||||
* The checkpoint superblock can't be set until the very end of the
|
||||
@@ -721,7 +724,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) {
|
||||
|
||||
Reference in new issue
Block a user