aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs2acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs2acl.c')
-rw-r--r--fs/nfsd/nfs2acl.c72
1 files changed, 40 insertions, 32 deletions
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 95d76dc6c5da..11c1fba29312 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -30,8 +30,9 @@ nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
30static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, 30static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
31 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) 31 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
32{ 32{
33 svc_fh *fh;
34 struct posix_acl *acl; 33 struct posix_acl *acl;
34 struct inode *inode;
35 svc_fh *fh;
35 __be32 nfserr = 0; 36 __be32 nfserr = 0;
36 37
37 dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 38 dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
@@ -41,6 +42,8 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
41 if (nfserr) 42 if (nfserr)
42 RETURN_STATUS(nfserr); 43 RETURN_STATUS(nfserr);
43 44
45 inode = fh->fh_dentry->d_inode;
46
44 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) 47 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
45 RETURN_STATUS(nfserr_inval); 48 RETURN_STATUS(nfserr_inval);
46 resp->mask = argp->mask; 49 resp->mask = argp->mask;
@@ -50,21 +53,13 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
50 goto fail; 53 goto fail;
51 54
52 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) { 55 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
53 acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS); 56 acl = get_acl(inode, ACL_TYPE_ACCESS);
54 if (IS_ERR(acl)) { 57 if (IS_ERR(acl)) {
55 int err = PTR_ERR(acl); 58 nfserr = nfserrno(PTR_ERR(acl));
56 59 goto fail;
57 if (err == -ENODATA || err == -EOPNOTSUPP)
58 acl = NULL;
59 else {
60 nfserr = nfserrno(err);
61 goto fail;
62 }
63 } 60 }
64 if (acl == NULL) { 61 if (acl == NULL) {
65 /* Solaris returns the inode's minimum ACL. */ 62 /* Solaris returns the inode's minimum ACL. */
66
67 struct inode *inode = fh->fh_dentry->d_inode;
68 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 63 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
69 } 64 }
70 resp->acl_access = acl; 65 resp->acl_access = acl;
@@ -72,17 +67,10 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
72 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) { 67 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
73 /* Check how Solaris handles requests for the Default ACL 68 /* Check how Solaris handles requests for the Default ACL
74 of a non-directory! */ 69 of a non-directory! */
75 70 acl = get_acl(inode, ACL_TYPE_DEFAULT);
76 acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
77 if (IS_ERR(acl)) { 71 if (IS_ERR(acl)) {
78 int err = PTR_ERR(acl); 72 nfserr = nfserrno(PTR_ERR(acl));
79 73 goto fail;
80 if (err == -ENODATA || err == -EOPNOTSUPP)
81 acl = NULL;
82 else {
83 nfserr = nfserrno(err);
84 goto fail;
85 }
86 } 74 }
87 resp->acl_default = acl; 75 resp->acl_default = acl;
88 } 76 }
@@ -103,31 +91,51 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp,
103 struct nfsd3_setaclargs *argp, 91 struct nfsd3_setaclargs *argp,
104 struct nfsd_attrstat *resp) 92 struct nfsd_attrstat *resp)
105{ 93{
94 struct inode *inode;
106 svc_fh *fh; 95 svc_fh *fh;
107 __be32 nfserr = 0; 96 __be32 nfserr = 0;
97 int error;
108 98
109 dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 99 dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
110 100
111 fh = fh_copy(&resp->fh, &argp->fh); 101 fh = fh_copy(&resp->fh, &argp->fh);
112 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR); 102 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR);
103 if (nfserr)
104 goto out;
113 105
114 if (!nfserr) { 106 inode = fh->fh_dentry->d_inode;
115 nfserr = nfserrno( nfsd_set_posix_acl( 107 if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) {
116 fh, ACL_TYPE_ACCESS, argp->acl_access) ); 108 error = -EOPNOTSUPP;
117 } 109 goto out_errno;
118 if (!nfserr) {
119 nfserr = nfserrno( nfsd_set_posix_acl(
120 fh, ACL_TYPE_DEFAULT, argp->acl_default) );
121 }
122 if (!nfserr) {
123 nfserr = fh_getattr(fh, &resp->stat);
124 } 110 }
125 111
112 error = fh_want_write(fh);
113 if (error)
114 goto out_errno;
115
116 error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS);
117 if (error)
118 goto out_drop_write;
119 error = inode->i_op->set_acl(inode, argp->acl_default,
120 ACL_TYPE_DEFAULT);
121 if (error)
122 goto out_drop_write;
123
124 fh_drop_write(fh);
125
126 nfserr = fh_getattr(fh, &resp->stat);
127
128out:
126 /* argp->acl_{access,default} may have been allocated in 129 /* argp->acl_{access,default} may have been allocated in
127 nfssvc_decode_setaclargs. */ 130 nfssvc_decode_setaclargs. */
128 posix_acl_release(argp->acl_access); 131 posix_acl_release(argp->acl_access);
129 posix_acl_release(argp->acl_default); 132 posix_acl_release(argp->acl_default);
130 return nfserr; 133 return nfserr;
134out_drop_write:
135 fh_drop_write(fh);
136out_errno:
137 nfserr = nfserrno(error);
138 goto out;
131} 139}
132 140
133/* 141/*