Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

NFSD: Add nfsd4_encode_fattr4_posix_default_acl

The POSIX ACL extension to NFSv4 defines FATTR4_POSIX_DEFAULT_ACL
for retrieving a directory's default ACL. This patch adds the
XDR encoder for that attribute.

For directories, the default ACL is retrieved via get_inode_acl()
and each entry is encoded as a posixace4: tag type, permission
bits, and principal name (empty for structural entries like
USER_OBJ/GROUP_OBJ/MASK/OTHER, resolved via idmapping for
USER/GROUP entries).

Signed-off-by: Rick Macklem <rmacklem@uoguelph.ca>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

Rick Macklem and committed by
Chuck Lever
5e62c904 8093c31f

+128
+128
fs/nfsd/nfs4xdr.c
··· 43 43 #include <linux/sunrpc/addr.h> 44 44 #include <linux/xattr.h> 45 45 #include <linux/vmalloc.h> 46 + #include <linux/nfsacl.h> 46 47 47 48 #include <uapi/linux/xattr.h> 48 49 ··· 2850 2849 { return 0; } 2851 2850 #endif 2852 2851 2852 + #ifdef CONFIG_NFSD_V4_POSIX_ACLS 2853 + 2854 + static int nfsd4_posix_tagtotype(short tag) 2855 + { 2856 + switch (tag) { 2857 + case ACL_USER_OBJ: return POSIXACE4_TAG_USER_OBJ; 2858 + case ACL_GROUP_OBJ: return POSIXACE4_TAG_GROUP_OBJ; 2859 + case ACL_USER: return POSIXACE4_TAG_USER; 2860 + case ACL_GROUP: return POSIXACE4_TAG_GROUP; 2861 + case ACL_MASK: return POSIXACE4_TAG_MASK; 2862 + case ACL_OTHER: return POSIXACE4_TAG_OTHER; 2863 + default: return -EINVAL; 2864 + } 2865 + } 2866 + 2867 + static __be32 2868 + nfsd4_encode_posixace4(struct xdr_stream *xdr, struct svc_rqst *rqstp, 2869 + struct posix_acl_entry *acep) 2870 + { 2871 + __be32 status; 2872 + int type; 2873 + 2874 + type = nfsd4_posix_tagtotype(acep->e_tag); 2875 + if (type < 0) 2876 + return nfserr_resource; 2877 + if (!xdrgen_encode_posixacetag4(xdr, type)) 2878 + return nfserr_resource; 2879 + if (!xdrgen_encode_posixaceperm4(xdr, acep->e_perm)) 2880 + return nfserr_resource; 2881 + 2882 + /* who */ 2883 + switch (acep->e_tag) { 2884 + case ACL_USER_OBJ: 2885 + case ACL_GROUP_OBJ: 2886 + case ACL_MASK: 2887 + case ACL_OTHER: 2888 + if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT) 2889 + return nfserr_resource; 2890 + break; 2891 + case ACL_USER: 2892 + status = nfsd4_encode_user(xdr, rqstp, acep->e_uid); 2893 + if (status != nfs_ok) 2894 + return status; 2895 + break; 2896 + case ACL_GROUP: 2897 + status = nfsd4_encode_group(xdr, rqstp, acep->e_gid); 2898 + if (status != nfs_ok) 2899 + return status; 2900 + break; 2901 + default: 2902 + return nfserr_resource; 2903 + } 2904 + return nfs_ok; 2905 + } 2906 + 2907 + static __be32 2908 + nfsd4_encode_posixacl(struct xdr_stream *xdr, struct svc_rqst *rqstp, 2909 + struct posix_acl *acl) 2910 + { 2911 + __be32 status; 2912 + int i; 2913 + 2914 + if (!acl) { 2915 + if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT) 2916 + return nfserr_resource; 2917 + return nfs_ok; 2918 + } 2919 + 2920 + if (acl->a_count > NFS_ACL_MAX_ENTRIES) 2921 + return nfserr_resource; 2922 + if (xdr_stream_encode_u32(xdr, acl->a_count) != XDR_UNIT) 2923 + return nfserr_resource; 2924 + for (i = 0; i < acl->a_count; i++) { 2925 + status = nfsd4_encode_posixace4(xdr, rqstp, &acl->a_entries[i]); 2926 + if (status != nfs_ok) 2927 + return status; 2928 + } 2929 + 2930 + return nfs_ok; 2931 + } 2932 + 2933 + #endif /* CONFIG_NFSD_V4_POSIX_ACL */ 2934 + 2853 2935 static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32 *rdattr_err) 2854 2936 { 2855 2937 /* As per referral draft: */ ··· 3013 2929 u64 change_attr; 3014 2930 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL 3015 2931 struct lsm_context context; 2932 + #endif 2933 + #ifdef CONFIG_NFSD_V4_POSIX_ACLS 2934 + struct posix_acl *dpacl; 3016 2935 #endif 3017 2936 u32 rdattr_err; 3018 2937 bool contextsupport; ··· 3579 3492 return nfs_ok; 3580 3493 } 3581 3494 3495 + static __be32 nfsd4_encode_fattr4_posix_default_acl(struct xdr_stream *xdr, 3496 + const struct nfsd4_fattr_args *args) 3497 + { 3498 + return nfsd4_encode_posixacl(xdr, args->rqstp, args->dpacl); 3499 + } 3500 + 3582 3501 #endif /* CONFIG_NFSD_V4_POSIX_ACLS */ 3583 3502 3584 3503 static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = { ··· 3698 3605 #ifdef CONFIG_NFSD_V4_POSIX_ACLS 3699 3606 [FATTR4_ACL_TRUEFORM] = nfsd4_encode_fattr4_acl_trueform, 3700 3607 [FATTR4_ACL_TRUEFORM_SCOPE] = nfsd4_encode_fattr4_acl_trueform_scope, 3608 + [FATTR4_POSIX_DEFAULT_ACL] = nfsd4_encode_fattr4_posix_default_acl, 3701 3609 #else 3702 3610 [FATTR4_ACL_TRUEFORM] = nfsd4_encode_fattr4__noop, 3703 3611 [FATTR4_ACL_TRUEFORM_SCOPE] = nfsd4_encode_fattr4__noop, 3612 + [FATTR4_POSIX_DEFAULT_ACL] = nfsd4_encode_fattr4__noop, 3704 3613 #endif 3705 3614 }; 3706 3615 ··· 3743 3648 args.acl = NULL; 3744 3649 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL 3745 3650 args.context.context = NULL; 3651 + #endif 3652 + #ifdef CONFIG_NFSD_V4_POSIX_ACLS 3653 + args.dpacl = NULL; 3746 3654 #endif 3747 3655 3748 3656 /* ··· 3853 3755 } 3854 3756 #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ 3855 3757 3758 + #ifdef CONFIG_NFSD_V4_POSIX_ACLS 3759 + if (attrmask[2] & FATTR4_WORD2_POSIX_DEFAULT_ACL) { 3760 + struct inode *inode = d_inode(dentry); 3761 + struct posix_acl *dpacl; 3762 + 3763 + if (S_ISDIR(inode->i_mode)) { 3764 + dpacl = get_inode_acl(inode, ACL_TYPE_DEFAULT); 3765 + if (IS_ERR(dpacl)) { 3766 + switch (PTR_ERR(dpacl)) { 3767 + case -EOPNOTSUPP: 3768 + attrmask[2] &= ~FATTR4_WORD2_POSIX_DEFAULT_ACL; 3769 + break; 3770 + case -EINVAL: 3771 + status = nfserr_attrnotsupp; 3772 + goto out; 3773 + default: 3774 + err = PTR_ERR(dpacl); 3775 + goto out_nfserr; 3776 + } 3777 + } else { 3778 + args.dpacl = dpacl; 3779 + } 3780 + } 3781 + } 3782 + #endif /* CONFIG_NFSD_V4_POSIX_ACLS */ 3783 + 3856 3784 /* attrmask */ 3857 3785 status = nfsd4_encode_bitmap4(xdr, attrmask[0], attrmask[1], 3858 3786 attrmask[2]); ··· 3902 3778 status = nfs_ok; 3903 3779 3904 3780 out: 3781 + #ifdef CONFIG_NFSD_V4_POSIX_ACLS 3782 + if (args.dpacl) 3783 + posix_acl_release(args.dpacl); 3784 + #endif /* CONFIG_NFSD_V4_POSIX_ACLS */ 3905 3785 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL 3906 3786 if (args.context.context) 3907 3787 security_release_secctx(&args.context);