@@ -5772,9 +5772,17 @@ static int nfs4_proc_renew(struct nfs_client *clp, const struct cred *cred)
5772
5772
return 0 ;
5773
5773
}
5774
5774
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 )
5776
5777
{
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
+ }
5778
5786
}
5779
5787
5780
5788
/* 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,
5813
5821
}
5814
5822
5815
5823
struct nfs4_cached_acl {
5824
+ enum nfs4_acl_type type ;
5816
5825
int cached ;
5817
5826
size_t len ;
5818
5827
char data [];
@@ -5833,7 +5842,8 @@ static void nfs4_zap_acl_attr(struct inode *inode)
5833
5842
nfs4_set_cached_acl (inode , NULL );
5834
5843
}
5835
5844
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 )
5837
5847
{
5838
5848
struct nfs_inode * nfsi = NFS_I (inode );
5839
5849
struct nfs4_cached_acl * acl ;
@@ -5843,6 +5853,8 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_
5843
5853
acl = nfsi -> nfs4_acl ;
5844
5854
if (acl == NULL )
5845
5855
goto out ;
5856
+ if (acl -> type != type )
5857
+ goto out ;
5846
5858
if (buf == NULL ) /* user is just asking for length */
5847
5859
goto out_len ;
5848
5860
if (acl -> cached == 0 )
@@ -5858,7 +5870,9 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_
5858
5870
return ret ;
5859
5871
}
5860
5872
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 )
5862
5876
{
5863
5877
struct nfs4_cached_acl * acl ;
5864
5878
size_t buflen = sizeof (* acl ) + acl_len ;
@@ -5875,6 +5889,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size
5875
5889
goto out ;
5876
5890
acl -> cached = 0 ;
5877
5891
}
5892
+ acl -> type = type ;
5878
5893
acl -> len = acl_len ;
5879
5894
out :
5880
5895
nfs4_set_cached_acl (inode , acl );
@@ -5890,7 +5905,8 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size
5890
5905
* length. The next getxattr call will then produce another round trip to
5891
5906
* the server, this time with the input buf of the required size.
5892
5907
*/
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 )
5894
5910
{
5895
5911
struct page * * pages ;
5896
5912
struct nfs_getaclargs args = {
@@ -5947,7 +5963,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
5947
5963
ret = - ERANGE ;
5948
5964
goto out_free ;
5949
5965
}
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 );
5951
5968
if (buf ) {
5952
5969
if (res .acl_len > buflen ) {
5953
5970
ret = - ERANGE ;
@@ -5967,14 +5984,15 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
5967
5984
return ret ;
5968
5985
}
5969
5986
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 )
5971
5989
{
5972
5990
struct nfs4_exception exception = {
5973
5991
.interruptible = true,
5974
5992
};
5975
5993
ssize_t ret ;
5976
5994
do {
5977
- ret = __nfs4_get_acl_uncached (inode , buf , buflen );
5995
+ ret = __nfs4_get_acl_uncached (inode , buf , buflen , type );
5978
5996
trace_nfs4_get_acl (inode , ret );
5979
5997
if (ret >= 0 )
5980
5998
break ;
@@ -5983,27 +6001,29 @@ static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bufl
5983
6001
return ret ;
5984
6002
}
5985
6003
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 )
5987
6006
{
5988
6007
struct nfs_server * server = NFS_SERVER (inode );
5989
6008
int ret ;
5990
6009
5991
- if (!nfs4_server_supports_acls (server ))
6010
+ if (!nfs4_server_supports_acls (server , type ))
5992
6011
return - EOPNOTSUPP ;
5993
6012
ret = nfs_revalidate_inode (inode , NFS_INO_INVALID_CHANGE );
5994
6013
if (ret < 0 )
5995
6014
return ret ;
5996
6015
if (NFS_I (inode )-> cache_validity & NFS_INO_INVALID_ACL )
5997
6016
nfs_zap_acl_cache (inode );
5998
- ret = nfs4_read_cached_acl (inode , buf , buflen );
6017
+ ret = nfs4_read_cached_acl (inode , buf , buflen , type );
5999
6018
if (ret != - ENOENT )
6000
6019
/* -ENOENT is returned if there is no ACL or if there is an ACL
6001
6020
* but no cached acl data, just the acl length */
6002
6021
return ret ;
6003
- return nfs4_get_acl_uncached (inode , buf , buflen );
6022
+ return nfs4_get_acl_uncached (inode , buf , buflen , type );
6004
6023
}
6005
6024
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 )
6007
6027
{
6008
6028
struct nfs_server * server = NFS_SERVER (inode );
6009
6029
struct page * pages [NFS4ACL_MAXPAGES ];
@@ -6024,7 +6044,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
6024
6044
/* You can't remove system.nfs4_acl: */
6025
6045
if (buflen == 0 )
6026
6046
return - EINVAL ;
6027
- if (!nfs4_server_supports_acls (server ))
6047
+ if (!nfs4_server_supports_acls (server , type ))
6028
6048
return - EOPNOTSUPP ;
6029
6049
if (npages > ARRAY_SIZE (pages ))
6030
6050
return - ERANGE ;
@@ -6055,12 +6075,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
6055
6075
return ret ;
6056
6076
}
6057
6077
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 )
6059
6080
{
6060
6081
struct nfs4_exception exception = { };
6061
6082
int err ;
6062
6083
do {
6063
- err = __nfs4_proc_set_acl (inode , buf , buflen );
6084
+ err = __nfs4_proc_set_acl (inode , buf , buflen , type );
6064
6085
trace_nfs4_set_acl (inode , err );
6065
6086
if (err == - NFS4ERR_BADOWNER || err == - NFS4ERR_BADNAME ) {
6066
6087
/*
@@ -7659,19 +7680,19 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
7659
7680
const char * key , const void * buf ,
7660
7681
size_t buflen , int flags )
7661
7682
{
7662
- return nfs4_proc_set_acl (inode , buf , buflen );
7683
+ return nfs4_proc_set_acl (inode , buf , buflen , NFS4ACL_ACL );
7663
7684
}
7664
7685
7665
7686
static int nfs4_xattr_get_nfs4_acl (const struct xattr_handler * handler ,
7666
7687
struct dentry * unused , struct inode * inode ,
7667
7688
const char * key , void * buf , size_t buflen )
7668
7689
{
7669
- return nfs4_proc_get_acl (inode , buf , buflen );
7690
+ return nfs4_proc_get_acl (inode , buf , buflen , NFS4ACL_ACL );
7670
7691
}
7671
7692
7672
7693
static bool nfs4_xattr_list_nfs4_acl (struct dentry * dentry )
7673
7694
{
7674
- return nfs4_server_supports_acls (NFS_SERVER ( d_inode ( dentry )) );
7695
+ return nfs4_server_supports_acls (NFS_SB ( dentry -> d_sb ), NFS4ACL_ACL );
7675
7696
}
7676
7697
7677
7698
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
0 commit comments