Closed fulalas closed 5 months ago
fulalas:
However, with NTFS partitions using ntfs3 driver (kernel
6.9.0
native), which allows POSIX compatibility, this doesn't seem to apply. In this case, a given mounted NTFS folder becomes read-only and I can no longer edit anything inside it in union. If I change the mount option torw
it becomes writable but then it gets whiteouts and all the mess I don't want.
I'm afraid you might be misunderstanding the branch permision 'rr'. 'rr' stands for 'Real Read-only' and it is for the natively read-only filesystems such as iso9660, cramfs, romfs, or squashfs. It never affects the behaviour of the branch filesystem if you set 'rr' to your branch fs. If the branch fs is mounted as 'rw' (out of aufs mount), then the branch fs is still 'rw' after adding it into aufs mount and you can freely modify the files on it directly. For NTFS, 'rr' is equivalent to 'ro' since NTFS is not natively read-only.
If you do understand 'rr' correctly, then I'd ask you explain "I can no longer edit anything inside it in union" you wrote. Do you mean copy-up doesn't work?
J. R. Okajima
@sfjro, thanks for your reply.
So you're saying that once mounted the result in AUFS filesystem is always going to be rw
regardless?
What I'm facing here is odd because if I mount during boot the mounted folder is ro
, but if I mount it after boot it's rw
. Not sure what's happening tbh.
fulalas:
So you're saying that once mounted the result in AUFS filesystem is always going to be
rw
regardless?
No. As long as you specify the branch attribute is RO at mounting aufs, it should keep RO.
What I'm facing here is odd because if I mount during boot the mounted folder is
ro
, but if I mount it after boot it'srw
. Not sure what's happening tbh.
Still I don't understand yout situation. How is your /sys/fs/aufs/si_XXXX/brN? Does it show "=rw"? Do you mean
J. R. Okajima
No. As long as you specify the branch attribute is RO at mounting aufs, it should keep RO.
My distro is mounting some squashfs files using this command:
mount -no remount,add=1:/memory/images/"$NAME"=rr aufs /union
The result in AUFS filesystem (union) is that I can edit/remove files normally -- of course, the squashfs files won't change.
How is your /sys/fs/aufs/si_XXXX/brN? Does it show "=rw"?
If I run this command cat /sys/fs/aufs/*/br*
I get this:
/mnt/live/memory/changes=rw
/mnt/live/memory/images/firefox-esr-latest-115.10.0esr-x86_64-1.xzm=rr
/mnt/live/memory/images/003-xfce-4.18-current-20240505.xzm=rr
/mnt/live/memory/images/002-xtra-current-20240505.xzm=rr
/mnt/live/memory/images/002-gui-current-20240505.xzm=rr
/mnt/live/memory/images/001-core-current-20240505-ntfs3.xzm=rr
/mnt/live/memory/images/000-kernel-6.9.1.xzm=rr
As you can see, all squashfs (.xzm files) are set to read-only, however I can freely edit/delete them in AUFS. This has been like this since forever, and I never thought it would a problem. The actual problem I'm facing is that NTFS partitions don't behave the same way, as their mounted result in AUFS are read-only, which is not what I want.
fulalas:
As you can see, all squashfs (.xzm files) are set to read-only, however I can freely edit/delete them in AUFS. This has been like this since forever, and I never thought it would a problem. The actual problem I'm facing is that NTFS partitions don't behave the same way, as their mounted result in AUFS are read-only, which is not what I want.
Hmm, it might be better to take a specific simple case to understand your situation.
"Permissions" here includes all the ordinary permission bits, acl/xattrs, and LSM settings. What is the failed command you tried? Can you strace and find which systemcall returned the error?
J. R. Okajima
I'm attaching 2 strace logs:
when I can execute mkdir build
inside ~/
folder because I'm not mounting it from a NTFS partition: normal.txt
when this same call results in an error because I'm mounting ~/
from a NTFS folder (during boot time): ntfs.txt
fulalas:
I'm attaching 2 strace logs:
Ok, the error happened at mkdir("build", 0777) = -1 EOPNOTSUPP (Operation not supported)
Let's try finding out the kernel internals.
J. R. Okajima
diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c index 3430838e0bc4..948ca4e2ee09 100644 --- a/fs/aufs/i_op_add.c +++ b/fs/aufs/i_op_add.c @@ -871,6 +871,9 @@ int aufs_mkdir(struct mnt_idmap idmap, struct inode dir, };
IMustLock(dir);
+AuDbgInode(dir); +AuDbgDentry(dentry); +AuDbg("idmap %p, mode 0%o\n", idmap, mode);
err = -ENOMEM;
a = kmalloc(sizeof(*a), GFP_NOFS);
@@ -878,9 +881,11 @@ int aufs_mkdir(struct mnt_idmap idmap, struct inode dir, goto out;
err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
+AuTraceErr(err); if (unlikely(err)) goto out_free; err = au_d_may_add(dentry); +AuTraceErr(err); if (unlikely(err)) goto out_unlock;
@@ -888,6 +893,7 @@ int aufs_mkdir(struct mnt_idmap idmap, struct inode dir, di_write_lock_parent(parent); wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /src_dentry/NULL, &a->pin, &wr_dir_args); +AuTraceErrPtr(wh_dentry); err = PTR_ERR(wh_dentry); if (IS_ERR(wh_dentry)) goto out_parent; @@ -897,6 +903,7 @@ int aufs_mkdir(struct mnt_idmap idmap, struct inode dir, h_path.dentry = au_h_dptr(dentry, bindex); h_path.mnt = au_sbr_mnt(sb, bindex); err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); +AuTraceErr(err); if (unlikely(err)) goto out_unpin;
@@ -908,6 +915,7 @@ int aufs_mkdir(struct mnt_idmap idmap, struct inode dir, inode_lock_nested(h_inode, AuLsc_I_CHILD); opq_dentry = au_diropq_create(dentry, bindex); inode_unlock(h_inode); +AuTraceErrPtr(opq_dentry); err = PTR_ERR(opq_dentry); if (IS_ERR(opq_dentry)) goto out_dir; @@ -916,6 +924,7 @@ int aufs_mkdir(struct mnt_idmap idmap, struct inode dir, }
err = epilog(dir, bindex, wh_dentry, dentry);
+AuTraceErr(err); if (!err) { inc_nlink(dir); goto out_unpin; / success / diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c index 62368b3e2730..19b475e5a65b 100644 --- a/fs/aufs/vfsub.c +++ b/fs/aufs/vfsub.c @@ -463,9 +463,11 @@ int vfsub_mkdir(struct inode dir, struct path path, int mode) goto out; idmap = mnt_idmap(path->mnt);
+AuDbg("dir->i_op->mkdir %pf\n", dir->i_op->mkdir); lockdep_off(); err = vfs_mkdir(idmap, dir, path->dentry, mode); lockdep_on(); +AuTraceErr(err); if (!err) { struct path tmp = *path; int did;
I failed to build kernel with -DDEBUG
, but at least CONFIG_AUFS_DEBUG
is enabled. This is what I have after mkdir build
:
fulalas:
I failed to build kernel with
-DDEBUG
, but at leastCONFIG_AUFS_DEBUG
is enabled. This is what I have aftermkdir build
:
ok, good. Even without -DDEBUG, the log is good expectedly. But I made a mistake in the debug patch. Plz correct like this and run again.
fs/aufs/vfsub.c:vfsub_mkdir
466: AuDbgInode(dir); 467: AuDbg("dir->i_op->mkdir %ps\n", dir->i_op->mkdir); 468: lockdep_off(); 469: err = vfs_mkdir(idmap, dir, path->dentry, mode); 470: lockdep_on(); 471: AuTraceErr(err);
J. R. Okajima
Sorry, it's not clear. Is this correct?
int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
{
int err;
struct dentry *d;
struct mnt_idmap *idmap;
AuDbgInode(dir);
AuDbg("dir->i_op->mkdir %ps\n", dir->i_op->mkdir);
lockdep_off();
err = vfs_mkdir(idmap, dir, path->dentry, mode);
lockdep_on();
AuTraceErr(err);
d = path->dentry;
path->dentry = d->d_parent;
err = security_path_mkdir(path, d, mode);
path->dentry = d;
if (unlikely(err))
goto out;
idmap = mnt_idmap(path->mnt);
AuDbg("dir->i_op->mkdir %ps\n", dir->i_op->mkdir);
lockdep_off();
err = vfs_mkdir(idmap, dir, path->dentry, mode);
lockdep_on();
AuTraceErr(err);
if (!err) {
struct path tmp = *path;
int did;
vfsub_update_h_iattr(&tmp, &did);
if (did) {
tmp.dentry = path->dentry->d_parent;
vfsub_update_h_iattr(&tmp, /*did*/NULL);
}
/*ignore*/
}
out:
return err;
}
fulalas:
Sorry, it's not clear. Is this correct?
No. Plz use this.
int vfsub_mkdir(struct inode dir, struct path path, int mode) { int err; struct dentry d; struct mnt_idmap idmap;
IMustLock(dir);
d = path->dentry;
path->dentry = d->d_parent;
err = security_path_mkdir(path, d, mode);
path->dentry = d;
if (unlikely(err))
goto out;
idmap = mnt_idmap(path->mnt);
AuDbgInode(dir); AuDbg("dir->i_op->mkdir %ps\n", dir->i_op->mkdir); lockdep_off(); err = vfs_mkdir(idmap, dir, path->dentry, mode); lockdep_on(); AuTraceErr(err); if (!err) { struct path tmp = *path; int did;
vfsub_update_h_iattr(&tmp, &did);
if (did) {
tmp.dentry = path->dentry->d_parent;
vfsub_update_h_iattr(&tmp, /*did*/NULL);
}
/*ignore*/
}
out: return err; }
Here we go :)
fulalas:
Here we go :)
Xattr/Acl seems the trigger. Here is my currect guess.
If this guess is right, then there are some approaches to fix. Choose one you like. You don't have to take all of them.
icexsec' means to ignore an error on copying\-up/down XATTR categorized as "security" (for LSM and capability). And
icexsys,' icextr,' and
icexusr,' are for "system" (for posix ACL), "trusted" and "user"
categories individually.
icexoth' is for any other category. To be convenient,
icex` sets them
all.
See also linux/Documentation/filesystems/aufs/design/06xattr.txt.To know which xattr/acl caused the error, this debug patch may help.
diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c index 6c83908fb380..26452f39404b 100644 --- a/fs/aufs/xattr.c +++ b/fs/aufs/xattr.c @@ -61,7 +61,10 @@ static int au_do_cpup_xattr(struct path h_dst, struct path h_src, struct mnt_idmap h_dst_idmap, h_src_idmap; struct posix_acl *acl;
+AuDbgDentry(h_src->dentry); +AuDbgDentry(h_dst->dentry); is_acl = !!is_posix_acl_xattr(name); +AuDbg("name %s, is_acl %d\n", name, is_acl); h_src_idmap = mnt_idmap(h_src->mnt); h_src_dentry = h_src->dentry; if (is_acl) { @@ -113,6 +116,7 @@ static int au_do_cpup_xattr(struct path h_dst, struct path h_src, }
out: +AuTraceErr(err); return err; }
J. R. Okajima
To know which xattr/acl caused the error, this debug patch may help.
Using your suggested patch in combination with the other one (from previous debug log) resulted in a frozen boot. Here's the file, maybe I did something wrong:
Gonna take a look at the documentation. Thanks a lot!
fulalas:
Using your suggested patch in combination with the other one (from previous debug log) resulted in a frozen boot. Here's the file, maybe I did something wrong:
Then I'd suggest you to
J. R. Okajima
@sfjro, using 'icex' in the mount command seems to fix the issue.
I guess ntfs3
is not 100% POSIX compatible, but tbh I don't have time/energy to investigate why and report upstream. Let's hope ntfs3
gets better in the future. There are many issues still, which make it not suitable for production usage, in my opinion.
Thanks a loooot for your help and patience :)
When using ext partitions or squashfs files I can mount to union as read-only (
rr
) so that files can be edited in the union just fine (of course all changes are lost after reboot).However, with NTFS partitions using ntfs3 driver (kernel
6.9.0
native), which allows POSIX compatibility, this doesn't seem to apply. In this case, a given mounted NTFS folder becomes read-only and I can no longer edit anything inside it in union. If I change the mount option torw
it becomes writable but then it gets whiteouts and all the mess I don't want.That's the command I'm using:
mount -no remount,add=1:"$NTFS_FOLDER"=rr aufs /union
I wonder why there's this difference between ext/squashfs and NTFS. Any workaround?
Thanks!