mirror of
https://github.com/linux-apfs/linux-apfs-rw.git
synced 2026-08-18 02:19:59 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
628b6810e4 | ||
|
|
7aca589f9e | ||
|
|
36df7e0b35 | ||
|
|
ae381fbc3d | ||
|
|
f95bcc94c9 | ||
|
|
911bbe1743 | ||
|
|
6d54029be9 | ||
|
|
88b36a788e | ||
|
|
ef79bb1bee | ||
|
|
67eb48bb34 | ||
|
|
9aadac614c | ||
|
|
1158bd03a6 | ||
|
|
351c7cf826 | ||
|
|
61672f2caf | ||
|
|
0459ba0998 | ||
|
|
1db8a6d92a | ||
|
|
a3bca211bd | ||
|
|
de721cd995 | ||
|
|
0daf28cef7 | ||
|
|
c76aecff25 | ||
|
|
714202fefa | ||
|
|
44db9dc02e | ||
|
|
aefae5433f | ||
|
|
de4083a506 | ||
|
|
a3c23dffc3 |
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
|
||||
|
||||
@@ -380,6 +380,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 */
|
||||
|
||||
@@ -1021,8 +1022,13 @@ extern struct inode *apfs_new_inode(struct inode *dir, umode_t mode,
|
||||
extern int apfs_create_inode_rec(struct super_block *sb, struct inode *inode,
|
||||
struct dentry *dentry);
|
||||
extern int apfs_inode_create_exclusive_dstream(struct inode *inode);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
extern int __apfs_write_begin(const struct kiocb *iocb, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata);
|
||||
extern int __apfs_write_end(const struct kiocb *iocb, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata);
|
||||
#else
|
||||
extern int __apfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata);
|
||||
extern int __apfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata);
|
||||
#endif
|
||||
extern int apfs_dstream_adj_refcnt(struct apfs_dstream_info *dstream, u32 delta);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
|
||||
@@ -1035,7 +1041,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);
|
||||
@@ -1061,6 +1069,10 @@ extern int apfs_getattr(struct mnt_idmap *idmap,
|
||||
|
||||
extern int apfs_crypto_adj_refcnt(struct super_block *sb, u64 crypto_id, int delta);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
#define fileattr file_kattr
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) || RHEL_VERSION_GE(9, 6)
|
||||
extern int apfs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
|
||||
extern int apfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct fileattr *fa);
|
||||
@@ -1207,6 +1219,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
|
||||
|
||||
@@ -422,7 +422,11 @@ static int apfs_compress_readpage(struct file *filp, struct page *page)
|
||||
loff_t off;
|
||||
|
||||
/* Mostly copied from ext4_read_inline_page() */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
|
||||
off = page_folio(page)->index << PAGE_SHIFT;
|
||||
#else
|
||||
off = page->index << PAGE_SHIFT;
|
||||
#endif
|
||||
addr = kmap(page);
|
||||
ret = apfs_compress_file_read_page(filp, addr, off);
|
||||
flush_dcache_page(page);
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
PACKAGE_NAME="linux-apfs-rw"
|
||||
PACKAGE_VERSION="0.3.14"
|
||||
PACKAGE_VERSION="0.3.20"
|
||||
|
||||
BUILT_MODULE_NAME[0]="apfs"
|
||||
DEST_MODULE_LOCATION[0]="/extra"
|
||||
|
||||
@@ -72,7 +72,11 @@ static vm_fault_t apfs_page_mkwrite(struct vm_fault *vmf)
|
||||
}
|
||||
|
||||
size = i_size_read(inode);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
|
||||
if (page_folio(page)->index == size >> PAGE_SHIFT)
|
||||
#else
|
||||
if (page->index == size >> PAGE_SHIFT)
|
||||
#endif
|
||||
len = size & ~PAGE_MASK;
|
||||
else
|
||||
len = PAGE_SIZE;
|
||||
|
||||
@@ -470,7 +470,11 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
int __apfs_write_begin(const struct kiocb *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata)
|
||||
#else
|
||||
int __apfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int flags, struct page **pagep, void **fsdata)
|
||||
#endif
|
||||
{
|
||||
struct inode *inode = mapping->host;
|
||||
struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream;
|
||||
@@ -584,7 +588,11 @@ out_put_page:
|
||||
return err;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
static int apfs_write_begin(const struct kiocb *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned int len,
|
||||
struct folio **foliop, void **fsdata)
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
static int apfs_write_begin(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned int len,
|
||||
struct folio **foliop, void **fsdata)
|
||||
@@ -629,7 +637,11 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
int __apfs_write_end(const struct kiocb *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata)
|
||||
#else
|
||||
int __apfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, unsigned int copied, struct page *page, void *fsdata)
|
||||
#endif
|
||||
{
|
||||
struct inode *inode = mapping->host;
|
||||
struct apfs_dstream_info *dstream = &APFS_I(inode)->i_dstream;
|
||||
@@ -652,7 +664,11 @@ int __apfs_write_end(struct file *file, struct address_space *mapping, loff_t po
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
|
||||
static int apfs_write_end(const struct kiocb *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned int len, unsigned int copied,
|
||||
struct folio *folio, void *fsdata)
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
static int apfs_write_end(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned int len, unsigned int copied,
|
||||
struct folio *folio, void *fsdata)
|
||||
@@ -1021,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);
|
||||
@@ -1133,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;
|
||||
@@ -2093,7 +2109,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)
|
||||
@@ -2107,7 +2125,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);
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in new issue
Block a user