The driver is much closer to being usable, so I might start getting
subtler bug reports soon. To make them easier to handle, put error
messages all over the place. I should have done this from the beginning,
but I guess I didn't fully understand the need back then.
From now my general policy will be to use apfs_warn() for user errors or
unsupported features; apfs_err() for things that are probably corruption
or io errors; and apfs_alert() for things that are most likely bugs.
These last two should be rare, so the same error/alert will be thrown by
several layers in the callstack to provide as much information as
possible. Be careful and don't flood the console on normal situations.
Also, make messages with a log level lower than warning output their
function name and line number, which I think will help debugging more
than the actual messages.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Profiling has shown that the module spends too much time inside
apfs_lookup(). I had never really checked if the dentry cache was
working, so naturally that turned out to be the problem: I had always
assumed that the strings inside qstr structures were null-terminated,
but they may actually be a single component in a pathname, terminated by
a forward slash. The result was that we always searched the cache for
full pathnames, which were naturally never found.
To fix this, always pass the filename length from qstr to the unicode
handlers, and make them work without assuming a null-termination.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Luflosi is reporting new build issues:
https://github.com/linux-apfs/linux-apfs-rw/issues/19
These problems started when I implemented the FS_IOC_SETFLAGS and
FS_IOC_GETFLAGS ioctls. These ioctls have become officially supported by
the vfs recently, and then some of the helpers I was using got removed.
The proper way to implement this in newer kernels is through inode
methods ->apfs_fileattr_get() and ->apfs_fileattr_set().
So do that, and also fix a new instance of the typical build issue with
new namespace parameters. This time I've taken the trouble to build-test
this with a 5.13 kernel, and I even ran xfstests, so there shouldn't be
any more problems, at least not with that version.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
For reasons I ignore, dirty inodes never get written to disk unless I
call apfs_update_inode() myself. This is already done in ->setattr(),
but inode timestamp changes don't always go through that function.
Implement ->update_time() as well.
I really need to figure out what the root problem is here, but my main
priority right now is to have regression tests in place. This patch is
part of that effort, as it's required by generic/003 in xfstests.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Since kernel commit 549c7297717c ("fs: make helpers idmap mount aware")
extended the exisiting inode method to let filesystems be aware of
idmapped mounts, compiling apfs module with linux v5.12 failed:
========================================================================
make
make -C /lib/modules/5.12.0-custom/build M=/root/rw
make[1]: Entering directory '/root/linux'
CC [M] /root/linux-apfs-rw/dir.o
/root/linux-apfs-rw/dir.c:644:5: error: conflicting types for apfs_mknod
644 | int apfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
| ^~~~~~~~~~
In file included from /root/linux-apfs-rw/dir.c:8:
/root/linux-apfs-rw/apfs.h:642:12: note: previous declaration of apfs_mknod was here
642 | extern int apfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
| ^~~~~~~~~~
/root/linux-apfs-rw/dir.c:649:5: error: conflicting types for apfs_mkdir
649 | int apfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
| ^~~~~~~~~~
In file included from /root/linux-apfs-rw/dir.c:8:
/root/linux-apfs-rw/apfs.h:644:12: note: previous declaration of apfs_mkdir was here
644 | extern int apfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
| ^~~~~~~~~~
/root/linux-apfs-rw/dir.c:654:5: error: conflicting types for apfs_create
654 | int apfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
| ^~~~~~~~~~~
In file included from /root/linux-apfs-rw/dir.c:8:
/root/linux-apfs-rw/apfs.h:649:12: note: previous declaration of apfs_create was here
649 | extern int apfs_create(struct user_namespace *mnt_userns, struct inode *dir,
| ^~~~~~~~~~~
/root/linux-apfs-rw/dir.c:1197:5: error: conflicting types for apfs_rename
1197 | int apfs_rename(struct inode *old_dir, struct dentry *old_dentry,
| ^~~~~~~~~~~
In file included from /root/linux-apfs-rw/dir.c:8:
/root/linux-apfs-rw/apfs.h:646:12: note: previous declaration of apfs_rename was here
646 | extern int apfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
| ^~~~~~~~~~~
make[2]: *** [scripts/Makefile.build:271: /root/linux-apfs-rw/dir.o] Error 1
make[1]: *** [Makefile:1851: /root/rw] Error 2
make[1]: Leaving directory '/root/linux'
make: *** [Makefile:14: default] Error 2
========================================================================
Although keeping forward and backward compatibilities is painful,
add awful preprocessors to let compilation pass.
Signed-off-by: Su Yue <l@damenly.su>
If we run
touch aaa
rm aaa
touch AAA
on a case-insensitive filesystem, the result will be a file called
"aaa", instead of the expected "AAA". This happens because a negative
dentry for "aaa" still exists in the cache, and since it matches "AAA",
it gets reused for the creation.
The ->d_revalidate() method exists to deal with these situations, so
implement it.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
For reasons I ignore, ->write_inode() isn't actually being called to
persist mode or ownership changes. This is needed urgently so, while I
figure it out, solve the problem by just writing the inode immediately.
Also set ->setattr() for directories and special files.
[ernesto: changed cleanup, added comment and commit message]
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Add support for creating symbolic links, taking advantage of the
existing code for file creation and of the recently added inline xattr
support.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
Start a new out-of-tree repository, like linux-apfs-oot but with write
support.
To get the module to build independently, rewrite the Makefile and
add a definition for the APFS_SUPER_MAGIC macro. Since the intention is
to support a range of kernel versions, use preprocessor checks to handle
kernels without statx, without iversion, and without SB_RDONLY.
Provide a README file based on the original documentation, but with
additional build and mount instructions. Add a LICENSE file as well.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>