2022-10-19 13:07:58

by Ondrej Valousek

[permalink] [raw]
Subject: Patch nfs4 server to advertise usage of v4 ACLs

Hi list,
I was trying to address an issue described in
https://bugzilla.redhat.com/show_bug.cgi?id=767584
basically AFAIK RFC7530 instructs v4 NFS server to send a fake ACLs even when the there is actually no ACLs (aside of standard Unix attrs) defined.
This means the v4 client has no easy way to figure out if there are ACLs on the file/directory or not, hence tools like 'ls -l' can't display the '+' character in front of file/directory much like on FS mounted with NFSv3.

I was trying this address this issue with this (sort of naive) patch:

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1da721515b61..ad9324b25b7e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3182,7 +3182,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
p = xdr_reserve_space(xdr, 4);
if (!p)
goto out_resource;
- *p++ = cpu_to_be32(stat.mode & S_IALLUGO);
+ *p++ = cpu_to_be32((stat.mode & (S_IALLUGO | S_IFACL)));
}
if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
p = xdr_reserve_space(xdr, 4);
diff --git a/fs/stat.c b/fs/stat.c
index 28d2020ba1f4..da5b8bfbcd0f 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -20,6 +20,7 @@

#include <linux/uaccess.h>
#include <asm/unistd.h>
+#include <linux/posix_acl.h>

#include "internal.h"
#include "mount.h"
@@ -43,9 +44,15 @@
void generic_fillattr(struct user_namespace *mnt_userns, struct inode *inode,
struct kstat *stat)
{
+ struct posix_acl *pacl = get_acl(inode, ACL_TYPE_ACCESS);
+
stat->dev = inode->i_sb->s_dev;
stat->ino = inode->i_ino;
stat->mode = inode->i_mode;
+ if(pacl){ /* ACL of some kind is present */
+ stat->mode |= S_IFACL;
+ posix_acl_release(pacl);
+ }
stat->nlink = inode->i_nlink;
stat->uid = i_uid_into_mnt(mnt_userns, inode);
stat->gid = i_gid_into_mnt(mnt_userns, inode);
diff --git a/include/uapi/linux/stat.h b/include/uapi/linux/stat.h
index 1500a0f58041..2ab453ed8bfb 100644
--- a/include/uapi/linux/stat.h
+++ b/include/uapi/linux/stat.h
@@ -6,6 +6,7 @@

#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)

+#define S_IFACL 00200000 /* ACL of some kind is present */
#define S_IFMT 00170000
#define S_IFSOCK 0140000
#define S_IFLNK 0120000

... which aims to inform the remote nfs client about that no real ACLs are present.
Question - is something similar possible or doable?

Many thanks.