Skip to content

Commit 7b8b44e

Browse files
Trond Myklebustamschuma-ntap
authored andcommitted
NFSv4: Specify the type of ACL to cache
When caching a NFSv4 ACL, we want to specify whether we are caching an NFSv4.0 type acl, the NFSv4.1 dacl or the NFSv4.1 sacl. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 6949493 commit 7b8b44e

File tree

3 files changed

+49
-19
lines changed

3 files changed

+49
-19
lines changed

fs/nfs/nfs4proc.c

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

58155823
struct 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;
58795894
out:
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

76657686
static 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

76727693
static 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

include/linux/nfs4.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ enum lock_type4 {
451451
#define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
452452
#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
453453
#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23)
454+
#define FATTR4_WORD1_DACL (1UL << 26)
455+
#define FATTR4_WORD1_SACL (1UL << 27)
454456
#define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30)
455457
#define FATTR4_WORD2_LAYOUT_TYPES (1UL << 0)
456458
#define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1)

include/linux/nfs_xdr.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,13 @@ struct nfs_setattrargs {
800800
const struct nfs4_label *label;
801801
};
802802

803+
enum nfs4_acl_type {
804+
NFS4ACL_NONE = 0,
805+
NFS4ACL_ACL,
806+
NFS4ACL_DACL,
807+
NFS4ACL_SACL,
808+
};
809+
803810
struct nfs_setaclargs {
804811
struct nfs4_sequence_args seq_args;
805812
struct nfs_fh * fh;

0 commit comments

Comments
 (0)