diff options
-rw-r--r-- | fs/nfsd/nfs4acl.c | 147 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 43 | ||||
-rw-r--r-- | include/linux/nfs4.h | 3 | ||||
-rw-r--r-- | include/linux/nfs4_acl.h | 9 |
4 files changed, 66 insertions, 136 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6c52658e9a26..2797051cd2b4 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -128,74 +128,58 @@ struct ace_container { | |||
128 | }; | 128 | }; |
129 | 129 | ||
130 | static short ace2type(struct nfs4_ace *); | 130 | static short ace2type(struct nfs4_ace *); |
131 | static int _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, unsigned int); | 131 | static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, |
132 | int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t); | 132 | unsigned int); |
133 | void nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t); | ||
133 | 134 | ||
134 | struct nfs4_acl * | 135 | struct nfs4_acl * |
135 | nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl, | 136 | nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl, |
136 | unsigned int flags) | 137 | unsigned int flags) |
137 | { | 138 | { |
138 | struct nfs4_acl *acl; | 139 | struct nfs4_acl *acl; |
139 | int error = -EINVAL; | 140 | int size = 0; |
140 | 141 | ||
141 | if ((pacl != NULL && | 142 | if (pacl) { |
142 | (posix_acl_valid(pacl) < 0 || pacl->a_count == 0)) || | 143 | if (posix_acl_valid(pacl) < 0) |
143 | (dpacl != NULL && | 144 | return ERR_PTR(-EINVAL); |
144 | (posix_acl_valid(dpacl) < 0 || dpacl->a_count == 0))) | 145 | size += 2*pacl->a_count; |
145 | goto out_err; | ||
146 | |||
147 | acl = nfs4_acl_new(); | ||
148 | if (acl == NULL) { | ||
149 | error = -ENOMEM; | ||
150 | goto out_err; | ||
151 | } | 146 | } |
152 | 147 | if (dpacl) { | |
153 | if (pacl != NULL) { | 148 | if (posix_acl_valid(dpacl) < 0) |
154 | error = _posix_to_nfsv4_one(pacl, acl, | 149 | return ERR_PTR(-EINVAL); |
155 | flags & ~NFS4_ACL_TYPE_DEFAULT); | 150 | size += 2*dpacl->a_count; |
156 | if (error < 0) | ||
157 | goto out_acl; | ||
158 | } | 151 | } |
159 | 152 | ||
160 | if (dpacl != NULL) { | 153 | /* Allocate for worst case: one (deny, allow) pair each: */ |
161 | error = _posix_to_nfsv4_one(dpacl, acl, | 154 | acl = nfs4_acl_new(size); |
162 | flags | NFS4_ACL_TYPE_DEFAULT); | 155 | if (acl == NULL) |
163 | if (error < 0) | 156 | return ERR_PTR(-ENOMEM); |
164 | goto out_acl; | ||
165 | } | ||
166 | 157 | ||
167 | return acl; | 158 | if (pacl) |
159 | _posix_to_nfsv4_one(pacl, acl, flags & ~NFS4_ACL_TYPE_DEFAULT); | ||
168 | 160 | ||
169 | out_acl: | 161 | if (dpacl) |
170 | nfs4_acl_free(acl); | 162 | _posix_to_nfsv4_one(dpacl, acl, flags | NFS4_ACL_TYPE_DEFAULT); |
171 | out_err: | ||
172 | acl = ERR_PTR(error); | ||
173 | 163 | ||
174 | return acl; | 164 | return acl; |
175 | } | 165 | } |
176 | 166 | ||
177 | static int | 167 | static void |
178 | nfs4_acl_add_pair(struct nfs4_acl *acl, int eflag, u32 mask, int whotype, | 168 | nfs4_acl_add_pair(struct nfs4_acl *acl, int eflag, u32 mask, int whotype, |
179 | uid_t owner, unsigned int flags) | 169 | uid_t owner, unsigned int flags) |
180 | { | 170 | { |
181 | int error; | 171 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, |
182 | |||
183 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, | ||
184 | eflag, mask, whotype, owner); | 172 | eflag, mask, whotype, owner); |
185 | if (error < 0) | 173 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, |
186 | return error; | ||
187 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, | ||
188 | eflag, deny_mask(mask, flags), whotype, owner); | 174 | eflag, deny_mask(mask, flags), whotype, owner); |
189 | return error; | ||
190 | } | 175 | } |
191 | 176 | ||
192 | /* We assume the acl has been verified with posix_acl_valid. */ | 177 | /* We assume the acl has been verified with posix_acl_valid. */ |
193 | static int | 178 | static void |
194 | _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | 179 | _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, |
195 | unsigned int flags) | 180 | unsigned int flags) |
196 | { | 181 | { |
197 | struct posix_acl_entry *pa, *pe, *group_owner_entry; | 182 | struct posix_acl_entry *pa, *pe, *group_owner_entry; |
198 | int error = -EINVAL; | ||
199 | u32 mask, mask_mask; | 183 | u32 mask, mask_mask; |
200 | int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? | 184 | int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? |
201 | NFS4_INHERITANCE_FLAGS : 0); | 185 | NFS4_INHERITANCE_FLAGS : 0); |
@@ -211,23 +195,16 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
211 | pa = pacl->a_entries; | 195 | pa = pacl->a_entries; |
212 | BUG_ON(pa->e_tag != ACL_USER_OBJ); | 196 | BUG_ON(pa->e_tag != ACL_USER_OBJ); |
213 | mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER); | 197 | mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER); |
214 | error = nfs4_acl_add_pair(acl, eflag, mask, NFS4_ACL_WHO_OWNER, 0, flags); | 198 | nfs4_acl_add_pair(acl, eflag, mask, NFS4_ACL_WHO_OWNER, 0, flags); |
215 | if (error < 0) | ||
216 | goto out; | ||
217 | pa++; | 199 | pa++; |
218 | 200 | ||
219 | while (pa->e_tag == ACL_USER) { | 201 | while (pa->e_tag == ACL_USER) { |
220 | mask = mask_from_posix(pa->e_perm, flags); | 202 | mask = mask_from_posix(pa->e_perm, flags); |
221 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, | 203 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, |
222 | eflag, mask_mask, NFS4_ACL_WHO_NAMED, pa->e_id); | 204 | eflag, mask_mask, NFS4_ACL_WHO_NAMED, pa->e_id); |
223 | if (error < 0) | ||
224 | goto out; | ||
225 | 205 | ||
226 | 206 | nfs4_acl_add_pair(acl, eflag, mask, | |
227 | error = nfs4_acl_add_pair(acl, eflag, mask, | ||
228 | NFS4_ACL_WHO_NAMED, pa->e_id, flags); | 207 | NFS4_ACL_WHO_NAMED, pa->e_id, flags); |
229 | if (error < 0) | ||
230 | goto out; | ||
231 | pa++; | 208 | pa++; |
232 | } | 209 | } |
233 | 210 | ||
@@ -238,34 +215,25 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
238 | 215 | ||
239 | if (pacl->a_count > 3) { | 216 | if (pacl->a_count > 3) { |
240 | BUG_ON(pa->e_tag != ACL_GROUP_OBJ); | 217 | BUG_ON(pa->e_tag != ACL_GROUP_OBJ); |
241 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, | 218 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, |
242 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, | 219 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, |
243 | NFS4_ACL_WHO_GROUP, 0); | 220 | NFS4_ACL_WHO_GROUP, 0); |
244 | if (error < 0) | ||
245 | goto out; | ||
246 | } | 221 | } |
247 | group_owner_entry = pa; | 222 | group_owner_entry = pa; |
248 | mask = mask_from_posix(pa->e_perm, flags); | 223 | mask = mask_from_posix(pa->e_perm, flags); |
249 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, | 224 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, |
250 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, | 225 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, |
251 | NFS4_ACL_WHO_GROUP, 0); | 226 | NFS4_ACL_WHO_GROUP, 0); |
252 | if (error < 0) | ||
253 | goto out; | ||
254 | pa++; | 227 | pa++; |
255 | 228 | ||
256 | while (pa->e_tag == ACL_GROUP) { | 229 | while (pa->e_tag == ACL_GROUP) { |
257 | mask = mask_from_posix(pa->e_perm, flags); | 230 | mask = mask_from_posix(pa->e_perm, flags); |
258 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, | 231 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, |
259 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, | 232 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, |
260 | NFS4_ACL_WHO_NAMED, pa->e_id); | 233 | NFS4_ACL_WHO_NAMED, pa->e_id); |
261 | if (error < 0) | 234 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, |
262 | goto out; | ||
263 | |||
264 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, | ||
265 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, | 235 | NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, |
266 | NFS4_ACL_WHO_NAMED, pa->e_id); | 236 | NFS4_ACL_WHO_NAMED, pa->e_id); |
267 | if (error < 0) | ||
268 | goto out; | ||
269 | pa++; | 237 | pa++; |
270 | } | 238 | } |
271 | 239 | ||
@@ -273,19 +241,15 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
273 | 241 | ||
274 | pa = group_owner_entry; | 242 | pa = group_owner_entry; |
275 | mask = mask_from_posix(pa->e_perm, flags); | 243 | mask = mask_from_posix(pa->e_perm, flags); |
276 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, | 244 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, |
277 | NFS4_ACE_IDENTIFIER_GROUP | eflag, | 245 | NFS4_ACE_IDENTIFIER_GROUP | eflag, |
278 | deny_mask(mask, flags), NFS4_ACL_WHO_GROUP, 0); | 246 | deny_mask(mask, flags), NFS4_ACL_WHO_GROUP, 0); |
279 | if (error < 0) | ||
280 | goto out; | ||
281 | pa++; | 247 | pa++; |
282 | while (pa->e_tag == ACL_GROUP) { | 248 | while (pa->e_tag == ACL_GROUP) { |
283 | mask = mask_from_posix(pa->e_perm, flags); | 249 | mask = mask_from_posix(pa->e_perm, flags); |
284 | error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, | 250 | nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, |
285 | NFS4_ACE_IDENTIFIER_GROUP | eflag, | 251 | NFS4_ACE_IDENTIFIER_GROUP | eflag, |
286 | deny_mask(mask, flags), NFS4_ACL_WHO_NAMED, pa->e_id); | 252 | deny_mask(mask, flags), NFS4_ACL_WHO_NAMED, pa->e_id); |
287 | if (error < 0) | ||
288 | goto out; | ||
289 | pa++; | 253 | pa++; |
290 | } | 254 | } |
291 | 255 | ||
@@ -293,10 +257,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
293 | pa++; | 257 | pa++; |
294 | BUG_ON(pa->e_tag != ACL_OTHER); | 258 | BUG_ON(pa->e_tag != ACL_OTHER); |
295 | mask = mask_from_posix(pa->e_perm, flags); | 259 | mask = mask_from_posix(pa->e_perm, flags); |
296 | error = nfs4_acl_add_pair(acl, eflag, mask, NFS4_ACL_WHO_EVERYONE, 0, flags); | 260 | nfs4_acl_add_pair(acl, eflag, mask, NFS4_ACL_WHO_EVERYONE, 0, flags); |
297 | |||
298 | out: | ||
299 | return error; | ||
300 | } | 261 | } |
301 | 262 | ||
302 | static void | 263 | static void |
@@ -640,7 +601,7 @@ int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl, | |||
640 | if (ret) | 601 | if (ret) |
641 | goto out_estate; | 602 | goto out_estate; |
642 | ret = -EINVAL; | 603 | ret = -EINVAL; |
643 | list_for_each_entry(ace, &acl->ace_head, l_ace) { | 604 | for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { |
644 | if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && | 605 | if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && |
645 | ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) | 606 | ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) |
646 | goto out_dstate; | 607 | goto out_dstate; |
@@ -705,48 +666,22 @@ EXPORT_SYMBOL(nfs4_acl_posix_to_nfsv4); | |||
705 | EXPORT_SYMBOL(nfs4_acl_nfsv4_to_posix); | 666 | EXPORT_SYMBOL(nfs4_acl_nfsv4_to_posix); |
706 | 667 | ||
707 | struct nfs4_acl * | 668 | struct nfs4_acl * |
708 | nfs4_acl_new(void) | 669 | nfs4_acl_new(int n) |
709 | { | 670 | { |
710 | struct nfs4_acl *acl; | 671 | struct nfs4_acl *acl; |
711 | 672 | ||
712 | if ((acl = kmalloc(sizeof(*acl), GFP_KERNEL)) == NULL) | 673 | acl = kmalloc(sizeof(*acl) + n*sizeof(struct nfs4_ace), GFP_KERNEL); |
674 | if (acl == NULL) | ||
713 | return NULL; | 675 | return NULL; |
714 | |||
715 | acl->naces = 0; | 676 | acl->naces = 0; |
716 | INIT_LIST_HEAD(&acl->ace_head); | ||
717 | |||
718 | return acl; | 677 | return acl; |
719 | } | 678 | } |
720 | 679 | ||
721 | void | 680 | void |
722 | nfs4_acl_free(struct nfs4_acl *acl) | ||
723 | { | ||
724 | struct list_head *h; | ||
725 | struct nfs4_ace *ace; | ||
726 | |||
727 | if (!acl) | ||
728 | return; | ||
729 | |||
730 | while (!list_empty(&acl->ace_head)) { | ||
731 | h = acl->ace_head.next; | ||
732 | list_del(h); | ||
733 | ace = list_entry(h, struct nfs4_ace, l_ace); | ||
734 | kfree(ace); | ||
735 | } | ||
736 | |||
737 | kfree(acl); | ||
738 | |||
739 | return; | ||
740 | } | ||
741 | |||
742 | int | ||
743 | nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask, | 681 | nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask, |
744 | int whotype, uid_t who) | 682 | int whotype, uid_t who) |
745 | { | 683 | { |
746 | struct nfs4_ace *ace; | 684 | struct nfs4_ace *ace = acl->aces + acl->naces; |
747 | |||
748 | if ((ace = kmalloc(sizeof(*ace), GFP_KERNEL)) == NULL) | ||
749 | return -ENOMEM; | ||
750 | 685 | ||
751 | ace->type = type; | 686 | ace->type = type; |
752 | ace->flag = flag; | 687 | ace->flag = flag; |
@@ -754,10 +689,7 @@ nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask, | |||
754 | ace->whotype = whotype; | 689 | ace->whotype = whotype; |
755 | ace->who = who; | 690 | ace->who = who; |
756 | 691 | ||
757 | list_add_tail(&ace->l_ace, &acl->ace_head); | ||
758 | acl->naces++; | 692 | acl->naces++; |
759 | |||
760 | return 0; | ||
761 | } | 693 | } |
762 | 694 | ||
763 | static struct { | 695 | static struct { |
@@ -811,7 +743,6 @@ nfs4_acl_write_who(int who, char *p) | |||
811 | } | 743 | } |
812 | 744 | ||
813 | EXPORT_SYMBOL(nfs4_acl_new); | 745 | EXPORT_SYMBOL(nfs4_acl_new); |
814 | EXPORT_SYMBOL(nfs4_acl_free); | ||
815 | EXPORT_SYMBOL(nfs4_acl_add_ace); | 746 | EXPORT_SYMBOL(nfs4_acl_add_ace); |
816 | EXPORT_SYMBOL(nfs4_acl_get_whotype); | 747 | EXPORT_SYMBOL(nfs4_acl_get_whotype); |
817 | EXPORT_SYMBOL(nfs4_acl_write_who); | 748 | EXPORT_SYMBOL(nfs4_acl_write_who); |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0efba557fb55..fbb4af969243 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -273,42 +273,42 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia | |||
273 | iattr->ia_valid |= ATTR_SIZE; | 273 | iattr->ia_valid |= ATTR_SIZE; |
274 | } | 274 | } |
275 | if (bmval[0] & FATTR4_WORD0_ACL) { | 275 | if (bmval[0] & FATTR4_WORD0_ACL) { |
276 | int nace, i; | 276 | int nace; |
277 | struct nfs4_ace ace; | 277 | struct nfs4_ace *ace; |
278 | 278 | ||
279 | READ_BUF(4); len += 4; | 279 | READ_BUF(4); len += 4; |
280 | READ32(nace); | 280 | READ32(nace); |
281 | 281 | ||
282 | *acl = nfs4_acl_new(); | 282 | if (nace > NFS4_ACL_MAX) |
283 | return nfserr_resource; | ||
284 | |||
285 | *acl = nfs4_acl_new(nace); | ||
283 | if (*acl == NULL) { | 286 | if (*acl == NULL) { |
284 | host_err = -ENOMEM; | 287 | host_err = -ENOMEM; |
285 | goto out_nfserr; | 288 | goto out_nfserr; |
286 | } | 289 | } |
287 | defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl); | 290 | defer_free(argp, kfree, *acl); |
288 | 291 | ||
289 | for (i = 0; i < nace; i++) { | 292 | (*acl)->naces = nace; |
293 | for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { | ||
290 | READ_BUF(16); len += 16; | 294 | READ_BUF(16); len += 16; |
291 | READ32(ace.type); | 295 | READ32(ace->type); |
292 | READ32(ace.flag); | 296 | READ32(ace->flag); |
293 | READ32(ace.access_mask); | 297 | READ32(ace->access_mask); |
294 | READ32(dummy32); | 298 | READ32(dummy32); |
295 | READ_BUF(dummy32); | 299 | READ_BUF(dummy32); |
296 | len += XDR_QUADLEN(dummy32) << 2; | 300 | len += XDR_QUADLEN(dummy32) << 2; |
297 | READMEM(buf, dummy32); | 301 | READMEM(buf, dummy32); |
298 | ace.whotype = nfs4_acl_get_whotype(buf, dummy32); | 302 | ace->whotype = nfs4_acl_get_whotype(buf, dummy32); |
299 | host_err = 0; | 303 | host_err = 0; |
300 | if (ace.whotype != NFS4_ACL_WHO_NAMED) | 304 | if (ace->whotype != NFS4_ACL_WHO_NAMED) |
301 | ace.who = 0; | 305 | ace->who = 0; |
302 | else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP) | 306 | else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) |
303 | host_err = nfsd_map_name_to_gid(argp->rqstp, | 307 | host_err = nfsd_map_name_to_gid(argp->rqstp, |
304 | buf, dummy32, &ace.who); | 308 | buf, dummy32, &ace->who); |
305 | else | 309 | else |
306 | host_err = nfsd_map_name_to_uid(argp->rqstp, | 310 | host_err = nfsd_map_name_to_uid(argp->rqstp, |
307 | buf, dummy32, &ace.who); | 311 | buf, dummy32, &ace->who); |
308 | if (host_err) | ||
309 | goto out_nfserr; | ||
310 | host_err = nfs4_acl_add_ace(*acl, ace.type, ace.flag, | ||
311 | ace.access_mask, ace.whotype, ace.who); | ||
312 | if (host_err) | 312 | if (host_err) |
313 | goto out_nfserr; | 313 | goto out_nfserr; |
314 | } | 314 | } |
@@ -1596,7 +1596,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1596 | } | 1596 | } |
1597 | if (bmval0 & FATTR4_WORD0_ACL) { | 1597 | if (bmval0 & FATTR4_WORD0_ACL) { |
1598 | struct nfs4_ace *ace; | 1598 | struct nfs4_ace *ace; |
1599 | struct list_head *h; | ||
1600 | 1599 | ||
1601 | if (acl == NULL) { | 1600 | if (acl == NULL) { |
1602 | if ((buflen -= 4) < 0) | 1601 | if ((buflen -= 4) < 0) |
@@ -1609,9 +1608,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1609 | goto out_resource; | 1608 | goto out_resource; |
1610 | WRITE32(acl->naces); | 1609 | WRITE32(acl->naces); |
1611 | 1610 | ||
1612 | list_for_each(h, &acl->ace_head) { | 1611 | for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { |
1613 | ace = list_entry(h, struct nfs4_ace, l_ace); | ||
1614 | |||
1615 | if ((buflen -= 4*3) < 0) | 1612 | if ((buflen -= 4*3) < 0) |
1616 | goto out_resource; | 1613 | goto out_resource; |
1617 | WRITE32(ace->type); | 1614 | WRITE32(ace->type); |
@@ -1821,7 +1818,7 @@ out_acl: | |||
1821 | status = nfs_ok; | 1818 | status = nfs_ok; |
1822 | 1819 | ||
1823 | out: | 1820 | out: |
1824 | nfs4_acl_free(acl); | 1821 | kfree(acl); |
1825 | if (fhp == &tempfh) | 1822 | if (fhp == &tempfh) |
1826 | fh_put(&tempfh); | 1823 | fh_put(&tempfh); |
1827 | return status; | 1824 | return status; |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index db05182ca0e8..1be5be88debe 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
@@ -105,12 +105,11 @@ struct nfs4_ace { | |||
105 | uint32_t access_mask; | 105 | uint32_t access_mask; |
106 | int whotype; | 106 | int whotype; |
107 | uid_t who; | 107 | uid_t who; |
108 | struct list_head l_ace; | ||
109 | }; | 108 | }; |
110 | 109 | ||
111 | struct nfs4_acl { | 110 | struct nfs4_acl { |
112 | uint32_t naces; | 111 | uint32_t naces; |
113 | struct list_head ace_head; | 112 | struct nfs4_ace aces[0]; |
114 | }; | 113 | }; |
115 | 114 | ||
116 | typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; | 115 | typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; |
diff --git a/include/linux/nfs4_acl.h b/include/linux/nfs4_acl.h index 22aff4d01f20..409b6e02f337 100644 --- a/include/linux/nfs4_acl.h +++ b/include/linux/nfs4_acl.h | |||
@@ -39,9 +39,12 @@ | |||
39 | 39 | ||
40 | #include <linux/posix_acl.h> | 40 | #include <linux/posix_acl.h> |
41 | 41 | ||
42 | struct nfs4_acl *nfs4_acl_new(void); | 42 | /* Maximum ACL we'll accept from client; chosen (somewhat arbitrarily) to |
43 | void nfs4_acl_free(struct nfs4_acl *); | 43 | * fit in a page: */ |
44 | int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t); | 44 | #define NFS4_ACL_MAX 170 |
45 | |||
46 | struct nfs4_acl *nfs4_acl_new(int); | ||
47 | void nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t); | ||
45 | int nfs4_acl_get_whotype(char *, u32); | 48 | int nfs4_acl_get_whotype(char *, u32); |
46 | int nfs4_acl_write_who(int who, char *p); | 49 | int nfs4_acl_write_who(int who, char *p); |
47 | int nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group, | 50 | int nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group, |