@@ -5772,9 +5772,17 @@ static int nfs4_proc_renew(struct nfs_client *clp, const struct cred *cred)
57725772 return 0 ;
57735773}
57745774
5775- static inline int nfs4_server_supports_acls (struct nfs_server * server )
5775+ static bool nfs4_server_supports_acls (const struct nfs_server * server ,
5776+ enum nfs4_acl_type type )
57765777{
5777- return server -> caps & NFS_CAP_ACLS ;
5778+ switch (type ) {
5779+ default :
5780+ return server -> attr_bitmask [0 ] & FATTR4_WORD0_ACL ;
5781+ case NFS4ACL_DACL :
5782+ return server -> attr_bitmask [1 ] & FATTR4_WORD1_DACL ;
5783+ case NFS4ACL_SACL :
5784+ return server -> attr_bitmask [1 ] & FATTR4_WORD1_SACL ;
5785+ }
57785786}
57795787
57805788/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that
@@ -5813,6 +5821,7 @@ int nfs4_buf_to_pages_noslab(const void *buf, size_t buflen,
58135821}
58145822
58155823struct nfs4_cached_acl {
5824+ enum nfs4_acl_type type ;
58165825 int cached ;
58175826 size_t len ;
58185827 char data [];
@@ -5833,7 +5842,8 @@ static void nfs4_zap_acl_attr(struct inode *inode)
58335842 nfs4_set_cached_acl (inode , NULL );
58345843}
58355844
5836- static inline ssize_t nfs4_read_cached_acl (struct inode * inode , char * buf , size_t buflen )
5845+ static ssize_t nfs4_read_cached_acl (struct inode * inode , char * buf ,
5846+ size_t buflen , enum nfs4_acl_type type )
58375847{
58385848 struct nfs_inode * nfsi = NFS_I (inode );
58395849 struct nfs4_cached_acl * acl ;
@@ -5843,6 +5853,8 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_
58435853 acl = nfsi -> nfs4_acl ;
58445854 if (acl == NULL )
58455855 goto out ;
5856+ if (acl -> type != type )
5857+ goto out ;
58465858 if (buf == NULL ) /* user is just asking for length */
58475859 goto out_len ;
58485860 if (acl -> cached == 0 )
@@ -5858,7 +5870,9 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_
58585870 return ret ;
58595871}
58605872
5861- static void nfs4_write_cached_acl (struct inode * inode , struct page * * pages , size_t pgbase , size_t acl_len )
5873+ static void nfs4_write_cached_acl (struct inode * inode , struct page * * pages ,
5874+ size_t pgbase , size_t acl_len ,
5875+ enum nfs4_acl_type type )
58625876{
58635877 struct nfs4_cached_acl * acl ;
58645878 size_t buflen = sizeof (* acl ) + acl_len ;
@@ -5875,6 +5889,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size
58755889 goto out ;
58765890 acl -> cached = 0 ;
58775891 }
5892+ acl -> type = type ;
58785893 acl -> len = acl_len ;
58795894out :
58805895 nfs4_set_cached_acl (inode , acl );
@@ -5890,7 +5905,8 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size
58905905 * length. The next getxattr call will then produce another round trip to
58915906 * the server, this time with the input buf of the required size.
58925907 */
5893- static ssize_t __nfs4_get_acl_uncached (struct inode * inode , void * buf , size_t buflen )
5908+ static ssize_t __nfs4_get_acl_uncached (struct inode * inode , void * buf ,
5909+ size_t buflen , enum nfs4_acl_type type )
58945910{
58955911 struct page * * pages ;
58965912 struct nfs_getaclargs args = {
@@ -5947,7 +5963,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
59475963 ret = - ERANGE ;
59485964 goto out_free ;
59495965 }
5950- nfs4_write_cached_acl (inode , pages , res .acl_data_offset , res .acl_len );
5966+ nfs4_write_cached_acl (inode , pages , res .acl_data_offset , res .acl_len ,
5967+ type );
59515968 if (buf ) {
59525969 if (res .acl_len > buflen ) {
59535970 ret = - ERANGE ;
@@ -5967,14 +5984,15 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
59675984 return ret ;
59685985}
59695986
5970- static ssize_t nfs4_get_acl_uncached (struct inode * inode , void * buf , size_t buflen )
5987+ static ssize_t nfs4_get_acl_uncached (struct inode * inode , void * buf ,
5988+ size_t buflen , enum nfs4_acl_type type )
59715989{
59725990 struct nfs4_exception exception = {
59735991 .interruptible = true,
59745992 };
59755993 ssize_t ret ;
59765994 do {
5977- ret = __nfs4_get_acl_uncached (inode , buf , buflen );
5995+ ret = __nfs4_get_acl_uncached (inode , buf , buflen , type );
59785996 trace_nfs4_get_acl (inode , ret );
59795997 if (ret >= 0 )
59805998 break ;
@@ -5983,27 +6001,29 @@ static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bufl
59836001 return ret ;
59846002}
59856003
5986- static ssize_t nfs4_proc_get_acl (struct inode * inode , void * buf , size_t buflen )
6004+ static ssize_t nfs4_proc_get_acl (struct inode * inode , void * buf , size_t buflen ,
6005+ enum nfs4_acl_type type )
59876006{
59886007 struct nfs_server * server = NFS_SERVER (inode );
59896008 int ret ;
59906009
5991- if (!nfs4_server_supports_acls (server ))
6010+ if (!nfs4_server_supports_acls (server , type ))
59926011 return - EOPNOTSUPP ;
59936012 ret = nfs_revalidate_inode (inode , NFS_INO_INVALID_CHANGE );
59946013 if (ret < 0 )
59956014 return ret ;
59966015 if (NFS_I (inode )-> cache_validity & NFS_INO_INVALID_ACL )
59976016 nfs_zap_acl_cache (inode );
5998- ret = nfs4_read_cached_acl (inode , buf , buflen );
6017+ ret = nfs4_read_cached_acl (inode , buf , buflen , type );
59996018 if (ret != - ENOENT )
60006019 /* -ENOENT is returned if there is no ACL or if there is an ACL
60016020 * but no cached acl data, just the acl length */
60026021 return ret ;
6003- return nfs4_get_acl_uncached (inode , buf , buflen );
6022+ return nfs4_get_acl_uncached (inode , buf , buflen , type );
60046023}
60056024
6006- static int __nfs4_proc_set_acl (struct inode * inode , const void * buf , size_t buflen )
6025+ static int __nfs4_proc_set_acl (struct inode * inode , const void * buf ,
6026+ size_t buflen , enum nfs4_acl_type type )
60076027{
60086028 struct nfs_server * server = NFS_SERVER (inode );
60096029 struct page * pages [NFS4ACL_MAXPAGES ];
@@ -6024,7 +6044,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
60246044 /* You can't remove system.nfs4_acl: */
60256045 if (buflen == 0 )
60266046 return - EINVAL ;
6027- if (!nfs4_server_supports_acls (server ))
6047+ if (!nfs4_server_supports_acls (server , type ))
60286048 return - EOPNOTSUPP ;
60296049 if (npages > ARRAY_SIZE (pages ))
60306050 return - ERANGE ;
@@ -6055,12 +6075,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
60556075 return ret ;
60566076}
60576077
6058- static int nfs4_proc_set_acl (struct inode * inode , const void * buf , size_t buflen )
6078+ static int nfs4_proc_set_acl (struct inode * inode , const void * buf ,
6079+ size_t buflen , enum nfs4_acl_type type )
60596080{
60606081 struct nfs4_exception exception = { };
60616082 int err ;
60626083 do {
6063- err = __nfs4_proc_set_acl (inode , buf , buflen );
6084+ err = __nfs4_proc_set_acl (inode , buf , buflen , type );
60646085 trace_nfs4_set_acl (inode , err );
60656086 if (err == - NFS4ERR_BADOWNER || err == - NFS4ERR_BADNAME ) {
60666087 /*
@@ -7659,19 +7680,19 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
76597680 const char * key , const void * buf ,
76607681 size_t buflen , int flags )
76617682{
7662- return nfs4_proc_set_acl (inode , buf , buflen );
7683+ return nfs4_proc_set_acl (inode , buf , buflen , NFS4ACL_ACL );
76637684}
76647685
76657686static int nfs4_xattr_get_nfs4_acl (const struct xattr_handler * handler ,
76667687 struct dentry * unused , struct inode * inode ,
76677688 const char * key , void * buf , size_t buflen )
76687689{
7669- return nfs4_proc_get_acl (inode , buf , buflen );
7690+ return nfs4_proc_get_acl (inode , buf , buflen , NFS4ACL_ACL );
76707691}
76717692
76727693static bool nfs4_xattr_list_nfs4_acl (struct dentry * dentry )
76737694{
7674- return nfs4_server_supports_acls (NFS_SERVER ( d_inode ( dentry )) );
7695+ return nfs4_server_supports_acls (NFS_SB ( dentry -> d_sb ), NFS4ACL_ACL );
76757696}
76767697
76777698#ifdef CONFIG_NFS_V4_SECURITY_LABEL
0 commit comments