diff options
Diffstat (limited to 'fs/nfsd/nfs2acl.c')
-rw-r--r-- | fs/nfsd/nfs2acl.c | 72 |
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) | |||
30 | static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, | 30 | static __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 | |||
128 | out: | ||
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; |
134 | out_drop_write: | ||
135 | fh_drop_write(fh); | ||
136 | out_errno: | ||
137 | nfserr = nfserrno(error); | ||
138 | goto out; | ||
131 | } | 139 | } |
132 | 140 | ||
133 | /* | 141 | /* |