aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-06-10 11:07:47 -0400
committerChristoph Hellwig <hch@brick.lst.de>2009-06-10 11:07:47 -0400
commitef14f0c1578dce4b688726eb2603e50b62d6665a (patch)
tree5a221081850fab8f96455745e90f4a0e2127bce0 /fs/xfs/linux-2.6
parent8b5403a6d772d340541cfb30a668fde119c40ac1 (diff)
xfs: use generic Posix ACL code
This patch rips out the XFS ACL handling code and uses the generic fs/posix_acl.c code instead. The ondisk format is of course left unchanged. This also introduces the same ACL caching all other Linux filesystems do by adding pointers to the acl and default acl in struct xfs_inode. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Eric Sandeen <sandeen@sandeen.net>
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r--fs/xfs/linux-2.6/xfs_acl.c523
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c53
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_xattr.c67
6 files changed, 540 insertions, 119 deletions
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c
new file mode 100644
index 000000000000..1e9d1246eebc
--- /dev/null
+++ b/fs/xfs/linux-2.6/xfs_acl.c
@@ -0,0 +1,523 @@
1/*
2 * Copyright (c) 2008, Christoph Hellwig
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include "xfs.h"
19#include "xfs_acl.h"
20#include "xfs_attr.h"
21#include "xfs_bmap_btree.h"
22#include "xfs_inode.h"
23#include "xfs_vnodeops.h"
24#include <linux/xattr.h>
25#include <linux/posix_acl_xattr.h>
26
27
28#define XFS_ACL_NOT_CACHED ((void *)-1)
29
30/*
31 * Locking scheme:
32 * - all ACL updates are protected by inode->i_mutex, which is taken before
33 * calling into this file.
34 * - access and updates to the ip->i_acl and ip->i_default_acl pointers are
35 * protected by inode->i_lock.
36 */
37
38STATIC struct posix_acl *
39xfs_acl_from_disk(struct xfs_acl *aclp)
40{
41 struct posix_acl_entry *acl_e;
42 struct posix_acl *acl;
43 struct xfs_acl_entry *ace;
44 int count, i;
45
46 count = be32_to_cpu(aclp->acl_cnt);
47
48 acl = posix_acl_alloc(count, GFP_KERNEL);
49 if (!acl)
50 return ERR_PTR(-ENOMEM);
51
52 for (i = 0; i < count; i++) {
53 acl_e = &acl->a_entries[i];
54 ace = &aclp->acl_entry[i];
55
56 /*
57 * The tag is 32 bits on disk and 16 bits in core.
58 *
59 * Because every access to it goes through the core
60 * format first this is not a problem.
61 */
62 acl_e->e_tag = be32_to_cpu(ace->ae_tag);
63 acl_e->e_perm = be16_to_cpu(ace->ae_perm);
64
65 switch (acl_e->e_tag) {
66 case ACL_USER:
67 case ACL_GROUP:
68 acl_e->e_id = be32_to_cpu(ace->ae_id);
69 break;
70 case ACL_USER_OBJ:
71 case ACL_GROUP_OBJ:
72 case ACL_MASK:
73 case ACL_OTHER:
74 acl_e->e_id = ACL_UNDEFINED_ID;
75 break;
76 default:
77 goto fail;
78 }
79 }
80 return acl;
81
82fail:
83 posix_acl_release(acl);
84 return ERR_PTR(-EINVAL);
85}
86
87STATIC void
88xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl)
89{
90 const struct posix_acl_entry *acl_e;
91 struct xfs_acl_entry *ace;
92 int i;
93
94 aclp->acl_cnt = cpu_to_be32(acl->a_count);
95 for (i = 0; i < acl->a_count; i++) {
96 ace = &aclp->acl_entry[i];
97 acl_e = &acl->a_entries[i];
98
99 ace->ae_tag = cpu_to_be32(acl_e->e_tag);
100 ace->ae_id = cpu_to_be32(acl_e->e_id);
101 ace->ae_perm = cpu_to_be16(acl_e->e_perm);
102 }
103}
104
105/*
106 * Update the cached ACL pointer in the inode.
107 *
108 * Because we don't hold any locks while reading/writing the attribute
109 * from/to disk another thread could have raced and updated the cached
110 * ACL value before us. In that case we release the previous cached value
111 * and update it with our new value.
112 */
113STATIC void
114xfs_update_cached_acl(struct inode *inode, struct posix_acl **p_acl,
115 struct posix_acl *acl)
116{
117 spin_lock(&inode->i_lock);
118 if (*p_acl && *p_acl != XFS_ACL_NOT_CACHED)
119 posix_acl_release(*p_acl);
120 *p_acl = posix_acl_dup(acl);
121 spin_unlock(&inode->i_lock);
122}
123
124struct posix_acl *
125xfs_get_acl(struct inode *inode, int type)
126{
127 struct xfs_inode *ip = XFS_I(inode);
128 struct posix_acl *acl = NULL, **p_acl;
129 struct xfs_acl *xfs_acl;
130 int len = sizeof(struct xfs_acl);
131 char *ea_name;
132 int error;
133
134 switch (type) {
135 case ACL_TYPE_ACCESS:
136 ea_name = SGI_ACL_FILE;
137 p_acl = &ip->i_acl;
138 break;
139 case ACL_TYPE_DEFAULT:
140 ea_name = SGI_ACL_DEFAULT;
141 p_acl = &ip->i_default_acl;
142 break;
143 default:
144 return ERR_PTR(-EINVAL);
145 }
146
147 spin_lock(&inode->i_lock);
148 if (*p_acl != XFS_ACL_NOT_CACHED)
149 acl = posix_acl_dup(*p_acl);
150 spin_unlock(&inode->i_lock);
151
152 /*
153 * If we have a cached ACLs value just return it, not need to
154 * go out to the disk.
155 */
156 if (acl)
157 return acl;
158
159 xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
160 if (!xfs_acl)
161 return ERR_PTR(-ENOMEM);
162
163 error = -xfs_attr_get(ip, ea_name, (char *)xfs_acl, &len, ATTR_ROOT);
164 if (error) {
165 /*
166 * If the attribute doesn't exist make sure we have a negative
167 * cache entry, for any other error assume it is transient and
168 * leave the cache entry as XFS_ACL_NOT_CACHED.
169 */
170 if (error == -ENOATTR) {
171 acl = NULL;
172 goto out_update_cache;
173 }
174 goto out;
175 }
176
177 acl = xfs_acl_from_disk(xfs_acl);
178 if (IS_ERR(acl))
179 goto out;
180
181 out_update_cache:
182 xfs_update_cached_acl(inode, p_acl, acl);
183 out:
184 kfree(xfs_acl);
185 return acl;
186}
187
188STATIC int
189xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
190{
191 struct xfs_inode *ip = XFS_I(inode);
192 struct posix_acl **p_acl;
193 char *ea_name;
194 int error;
195
196 if (S_ISLNK(inode->i_mode))
197 return -EOPNOTSUPP;
198
199 switch (type) {
200 case ACL_TYPE_ACCESS:
201 ea_name = SGI_ACL_FILE;
202 p_acl = &ip->i_acl;
203 break;
204 case ACL_TYPE_DEFAULT:
205 if (!S_ISDIR(inode->i_mode))
206 return acl ? -EACCES : 0;
207 ea_name = SGI_ACL_DEFAULT;
208 p_acl = &ip->i_default_acl;
209 break;
210 default:
211 return -EINVAL;
212 }
213
214 if (acl) {
215 struct xfs_acl *xfs_acl;
216 int len;
217
218 xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
219 if (!xfs_acl)
220 return -ENOMEM;
221
222 xfs_acl_to_disk(xfs_acl, acl);
223 len = sizeof(struct xfs_acl) -
224 (sizeof(struct xfs_acl_entry) *
225 (XFS_ACL_MAX_ENTRIES - acl->a_count));
226
227 error = -xfs_attr_set(ip, ea_name, (char *)xfs_acl,
228 len, ATTR_ROOT);
229
230 kfree(xfs_acl);
231 } else {
232 /*
233 * A NULL ACL argument means we want to remove the ACL.
234 */
235 error = -xfs_attr_remove(ip, ea_name, ATTR_ROOT);
236
237 /*
238 * If the attribute didn't exist to start with that's fine.
239 */
240 if (error == -ENOATTR)
241 error = 0;
242 }
243
244 if (!error)
245 xfs_update_cached_acl(inode, p_acl, acl);
246 return error;
247}
248
249int
250xfs_check_acl(struct inode *inode, int mask)
251{
252 struct xfs_inode *ip = XFS_I(inode);
253 struct posix_acl *acl;
254 int error = -EAGAIN;
255
256 xfs_itrace_entry(ip);
257
258 /*
259 * If there is no attribute fork no ACL exists on this inode and
260 * we can skip the whole exercise.
261 */
262 if (!XFS_IFORK_Q(ip))
263 return -EAGAIN;
264
265 acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
266 if (IS_ERR(acl))
267 return PTR_ERR(acl);
268 if (acl) {
269 error = posix_acl_permission(inode, acl, mask);
270 posix_acl_release(acl);
271 }
272
273 return error;
274}
275
276static int
277xfs_set_mode(struct inode *inode, mode_t mode)
278{
279 int error = 0;
280
281 if (mode != inode->i_mode) {
282 struct iattr iattr;
283
284 iattr.ia_valid = ATTR_MODE;
285 iattr.ia_mode = mode;
286
287 error = -xfs_setattr(XFS_I(inode), &iattr, XFS_ATTR_NOACL);
288 }
289
290 return error;
291}
292
293static int
294xfs_acl_exists(struct inode *inode, char *name)
295{
296 int len = sizeof(struct xfs_acl);
297
298 return (xfs_attr_get(XFS_I(inode), name, NULL, &len,
299 ATTR_ROOT|ATTR_KERNOVAL) == 0);
300}
301
302int
303posix_acl_access_exists(struct inode *inode)
304{
305 return xfs_acl_exists(inode, SGI_ACL_FILE);
306}
307
308int
309posix_acl_default_exists(struct inode *inode)
310{
311 if (!S_ISDIR(inode->i_mode))
312 return 0;
313 return xfs_acl_exists(inode, SGI_ACL_DEFAULT);
314}
315
316/*
317 * No need for i_mutex because the inode is not yet exposed to the VFS.
318 */
319int
320xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl)
321{
322 struct posix_acl *clone;
323 mode_t mode;
324 int error = 0, inherit = 0;
325
326 if (S_ISDIR(inode->i_mode)) {
327 error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl);
328 if (error)
329 return error;
330 }
331
332 clone = posix_acl_clone(default_acl, GFP_KERNEL);
333 if (!clone)
334 return -ENOMEM;
335
336 mode = inode->i_mode;
337 error = posix_acl_create_masq(clone, &mode);
338 if (error < 0)
339 goto out_release_clone;
340
341 /*
342 * If posix_acl_create_masq returns a positive value we need to
343 * inherit a permission that can't be represented using the Unix
344 * mode bits and we actually need to set an ACL.
345 */
346 if (error > 0)
347 inherit = 1;
348
349 error = xfs_set_mode(inode, mode);
350 if (error)
351 goto out_release_clone;
352
353 if (inherit)
354 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
355
356 out_release_clone:
357 posix_acl_release(clone);
358 return error;
359}
360
361int
362xfs_acl_chmod(struct inode *inode)
363{
364 struct posix_acl *acl, *clone;
365 int error;
366
367 if (S_ISLNK(inode->i_mode))
368 return -EOPNOTSUPP;
369
370 acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
371 if (IS_ERR(acl) || !acl)
372 return PTR_ERR(acl);
373
374 clone = posix_acl_clone(acl, GFP_KERNEL);
375 posix_acl_release(acl);
376 if (!clone)
377 return -ENOMEM;
378
379 error = posix_acl_chmod_masq(clone, inode->i_mode);
380 if (!error)
381 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
382
383 posix_acl_release(clone);
384 return error;
385}
386
387void
388xfs_inode_init_acls(struct xfs_inode *ip)
389{
390 /*
391 * No need for locking, inode is not live yet.
392 */
393 ip->i_acl = XFS_ACL_NOT_CACHED;
394 ip->i_default_acl = XFS_ACL_NOT_CACHED;
395}
396
397void
398xfs_inode_clear_acls(struct xfs_inode *ip)
399{
400 /*
401 * No need for locking here, the inode is not live anymore
402 * and just about to be freed.
403 */
404 if (ip->i_acl != XFS_ACL_NOT_CACHED)
405 posix_acl_release(ip->i_acl);
406 if (ip->i_default_acl != XFS_ACL_NOT_CACHED)
407 posix_acl_release(ip->i_default_acl);
408}
409
410
411/*
412 * System xattr handlers.
413 *
414 * Currently Posix ACLs are the only system namespace extended attribute
415 * handlers supported by XFS, so we just implement the handlers here.
416 * If we ever support other system extended attributes this will need
417 * some refactoring.
418 */
419
420static int
421xfs_decode_acl(const char *name)
422{
423 if (strcmp(name, "posix_acl_access") == 0)
424 return ACL_TYPE_ACCESS;
425 else if (strcmp(name, "posix_acl_default") == 0)
426 return ACL_TYPE_DEFAULT;
427 return -EINVAL;
428}
429
430static int
431xfs_xattr_system_get(struct inode *inode, const char *name,
432 void *value, size_t size)
433{
434 struct posix_acl *acl;
435 int type, error;
436
437 type = xfs_decode_acl(name);
438 if (type < 0)
439 return type;
440
441 acl = xfs_get_acl(inode, type);
442 if (IS_ERR(acl))
443 return PTR_ERR(acl);
444 if (acl == NULL)
445 return -ENODATA;
446
447 error = posix_acl_to_xattr(acl, value, size);
448 posix_acl_release(acl);
449
450 return error;
451}
452
453static int
454xfs_xattr_system_set(struct inode *inode, const char *name,
455 const void *value, size_t size, int flags)
456{
457 struct posix_acl *acl = NULL;
458 int error = 0, type;
459
460 type = xfs_decode_acl(name);
461 if (type < 0)
462 return type;
463 if (flags & XATTR_CREATE)
464 return -EINVAL;
465 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
466 return value ? -EACCES : 0;
467 if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
468 return -EPERM;
469
470 if (!value)
471 goto set_acl;
472
473 acl = posix_acl_from_xattr(value, size);
474 if (!acl) {
475 /*
476 * acl_set_file(3) may request that we set default ACLs with
477 * zero length -- defend (gracefully) against that here.
478 */
479 goto out;
480 }
481 if (IS_ERR(acl)) {
482 error = PTR_ERR(acl);
483 goto out;
484 }
485
486 error = posix_acl_valid(acl);
487 if (error)
488 goto out_release;
489
490 error = -EINVAL;
491 if (acl->a_count > XFS_ACL_MAX_ENTRIES)
492 goto out_release;
493
494 if (type == ACL_TYPE_ACCESS) {
495 mode_t mode = inode->i_mode;
496 error = posix_acl_equiv_mode(acl, &mode);
497
498 if (error <= 0) {
499 posix_acl_release(acl);
500 acl = NULL;
501
502 if (error < 0)
503 return error;
504 }
505
506 error = xfs_set_mode(inode, mode);
507 if (error)
508 goto out_release;
509 }
510
511 set_acl:
512 error = xfs_set_acl(inode, type, acl);
513 out_release:
514 posix_acl_release(acl);
515 out:
516 return error;
517}
518
519struct xattr_handler xfs_xattr_system_handler = {
520 .prefix = XATTR_SYSTEM_PREFIX,
521 .get = xfs_xattr_system_get,
522 .set = xfs_xattr_system_set,
523};
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index c7d684f02f89..182d4be9ffab 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -41,7 +41,6 @@
41#include "xfs_itable.h" 41#include "xfs_itable.h"
42#include "xfs_error.h" 42#include "xfs_error.h"
43#include "xfs_rw.h" 43#include "xfs_rw.h"
44#include "xfs_acl.h"
45#include "xfs_attr.h" 44#include "xfs_attr.h"
46#include "xfs_bmap.h" 45#include "xfs_bmap.h"
47#include "xfs_buf_item.h" 46#include "xfs_buf_item.h"
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 631d0137551e..84e391ab70b0 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -17,6 +17,7 @@
17 */ 17 */
18#include "xfs.h" 18#include "xfs.h"
19#include "xfs_fs.h" 19#include "xfs_fs.h"
20#include "xfs_acl.h"
20#include "xfs_bit.h" 21#include "xfs_bit.h"
21#include "xfs_log.h" 22#include "xfs_log.h"
22#include "xfs_inum.h" 23#include "xfs_inum.h"
@@ -51,6 +52,7 @@
51#include <linux/capability.h> 52#include <linux/capability.h>
52#include <linux/xattr.h> 53#include <linux/xattr.h>
53#include <linux/namei.h> 54#include <linux/namei.h>
55#include <linux/posix_acl.h>
54#include <linux/security.h> 56#include <linux/security.h>
55#include <linux/falloc.h> 57#include <linux/falloc.h>
56#include <linux/fiemap.h> 58#include <linux/fiemap.h>
@@ -202,9 +204,8 @@ xfs_vn_mknod(
202{ 204{
203 struct inode *inode; 205 struct inode *inode;
204 struct xfs_inode *ip = NULL; 206 struct xfs_inode *ip = NULL;
205 xfs_acl_t *default_acl = NULL; 207 struct posix_acl *default_acl = NULL;
206 struct xfs_name name; 208 struct xfs_name name;
207 int (*test_default_acl)(struct inode *) = _ACL_DEFAULT_EXISTS;
208 int error; 209 int error;
209 210
210 /* 211 /*
@@ -219,18 +220,14 @@ xfs_vn_mknod(
219 rdev = 0; 220 rdev = 0;
220 } 221 }
221 222
222 if (test_default_acl && test_default_acl(dir)) { 223 if (IS_POSIXACL(dir)) {
223 if (!_ACL_ALLOC(default_acl)) { 224 default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT);
224 return -ENOMEM; 225 if (IS_ERR(default_acl))
225 } 226 return -PTR_ERR(default_acl);
226 if (!_ACL_GET_DEFAULT(dir, default_acl)) {
227 _ACL_FREE(default_acl);
228 default_acl = NULL;
229 }
230 }
231 227
232 if (IS_POSIXACL(dir) && !default_acl) 228 if (!default_acl)
233 mode &= ~current->fs->umask; 229 mode &= ~current->fs->umask;
230 }
234 231
235 xfs_dentry_to_name(&name, dentry); 232 xfs_dentry_to_name(&name, dentry);
236 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL); 233 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
@@ -244,10 +241,10 @@ xfs_vn_mknod(
244 goto out_cleanup_inode; 241 goto out_cleanup_inode;
245 242
246 if (default_acl) { 243 if (default_acl) {
247 error = _ACL_INHERIT(inode, mode, default_acl); 244 error = -xfs_inherit_acl(inode, default_acl);
248 if (unlikely(error)) 245 if (unlikely(error))
249 goto out_cleanup_inode; 246 goto out_cleanup_inode;
250 _ACL_FREE(default_acl); 247 posix_acl_release(default_acl);
251 } 248 }
252 249
253 250
@@ -257,8 +254,7 @@ xfs_vn_mknod(
257 out_cleanup_inode: 254 out_cleanup_inode:
258 xfs_cleanup_inode(dir, inode, dentry); 255 xfs_cleanup_inode(dir, inode, dentry);
259 out_free_acl: 256 out_free_acl:
260 if (default_acl) 257 posix_acl_release(default_acl);
261 _ACL_FREE(default_acl);
262 return -error; 258 return -error;
263} 259}
264 260
@@ -488,26 +484,6 @@ xfs_vn_put_link(
488 kfree(s); 484 kfree(s);
489} 485}
490 486
491#ifdef CONFIG_XFS_POSIX_ACL
492STATIC int
493xfs_check_acl(
494 struct inode *inode,
495 int mask)
496{
497 struct xfs_inode *ip = XFS_I(inode);
498 int error;
499
500 xfs_itrace_entry(ip);
501
502 if (XFS_IFORK_Q(ip)) {
503 error = xfs_acl_iaccess(ip, mask, NULL);
504 if (error != -1)
505 return -error;
506 }
507
508 return -EAGAIN;
509}
510
511STATIC int 487STATIC int
512xfs_vn_permission( 488xfs_vn_permission(
513 struct inode *inode, 489 struct inode *inode,
@@ -515,9 +491,6 @@ xfs_vn_permission(
515{ 491{
516 return generic_permission(inode, mask, xfs_check_acl); 492 return generic_permission(inode, mask, xfs_check_acl);
517} 493}
518#else
519#define xfs_vn_permission NULL
520#endif
521 494
522STATIC int 495STATIC int
523xfs_vn_getattr( 496xfs_vn_getattr(
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 9142192ccbe6..7078974a6eee 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -42,7 +42,6 @@
42#include "xfs_error.h" 42#include "xfs_error.h"
43#include "xfs_itable.h" 43#include "xfs_itable.h"
44#include "xfs_rw.h" 44#include "xfs_rw.h"
45#include "xfs_acl.h"
46#include "xfs_attr.h" 45#include "xfs_attr.h"
47#include "xfs_inode_item.h" 46#include "xfs_inode_item.h"
48#include "xfs_buf_item.h" 47#include "xfs_buf_item.h"
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index d4e7ef8f8df9..36fb8a657c55 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -43,7 +43,6 @@
43#include "xfs_itable.h" 43#include "xfs_itable.h"
44#include "xfs_fsops.h" 44#include "xfs_fsops.h"
45#include "xfs_rw.h" 45#include "xfs_rw.h"
46#include "xfs_acl.h"
47#include "xfs_attr.h" 46#include "xfs_attr.h"
48#include "xfs_buf_item.h" 47#include "xfs_buf_item.h"
49#include "xfs_utils.h" 48#include "xfs_utils.h"
@@ -1735,18 +1734,8 @@ xfs_init_zones(void)
1735 if (!xfs_ili_zone) 1734 if (!xfs_ili_zone)
1736 goto out_destroy_inode_zone; 1735 goto out_destroy_inode_zone;
1737 1736
1738#ifdef CONFIG_XFS_POSIX_ACL
1739 xfs_acl_zone = kmem_zone_init(sizeof(xfs_acl_t), "xfs_acl");
1740 if (!xfs_acl_zone)
1741 goto out_destroy_ili_zone;
1742#endif
1743
1744 return 0; 1737 return 0;
1745 1738
1746#ifdef CONFIG_XFS_POSIX_ACL
1747 out_destroy_ili_zone:
1748#endif
1749 kmem_zone_destroy(xfs_ili_zone);
1750 out_destroy_inode_zone: 1739 out_destroy_inode_zone:
1751 kmem_zone_destroy(xfs_inode_zone); 1740 kmem_zone_destroy(xfs_inode_zone);
1752 out_destroy_efi_zone: 1741 out_destroy_efi_zone:
@@ -1780,9 +1769,6 @@ xfs_init_zones(void)
1780STATIC void 1769STATIC void
1781xfs_destroy_zones(void) 1770xfs_destroy_zones(void)
1782{ 1771{
1783#ifdef CONFIG_XFS_POSIX_ACL
1784 kmem_zone_destroy(xfs_acl_zone);
1785#endif
1786 kmem_zone_destroy(xfs_ili_zone); 1772 kmem_zone_destroy(xfs_ili_zone);
1787 kmem_zone_destroy(xfs_inode_zone); 1773 kmem_zone_destroy(xfs_inode_zone);
1788 kmem_zone_destroy(xfs_efi_zone); 1774 kmem_zone_destroy(xfs_efi_zone);
diff --git a/fs/xfs/linux-2.6/xfs_xattr.c b/fs/xfs/linux-2.6/xfs_xattr.c
index 964621fde6ed..497c7fb75cc1 100644
--- a/fs/xfs/linux-2.6/xfs_xattr.c
+++ b/fs/xfs/linux-2.6/xfs_xattr.c
@@ -29,67 +29,6 @@
29#include <linux/xattr.h> 29#include <linux/xattr.h>
30 30
31 31
32/*
33 * ACL handling. Should eventually be moved into xfs_acl.c
34 */
35
36static int
37xfs_decode_acl(const char *name)
38{
39 if (strcmp(name, "posix_acl_access") == 0)
40 return _ACL_TYPE_ACCESS;
41 else if (strcmp(name, "posix_acl_default") == 0)
42 return _ACL_TYPE_DEFAULT;
43 return -EINVAL;
44}
45
46/*
47 * Get system extended attributes which at the moment only
48 * includes Posix ACLs.
49 */
50static int
51xfs_xattr_system_get(struct inode *inode, const char *name,
52 void *buffer, size_t size)
53{
54 int acl;
55
56 acl = xfs_decode_acl(name);
57 if (acl < 0)
58 return acl;
59
60 return xfs_acl_vget(inode, buffer, size, acl);
61}
62
63static int
64xfs_xattr_system_set(struct inode *inode, const char *name,
65 const void *value, size_t size, int flags)
66{
67 int acl;
68
69 acl = xfs_decode_acl(name);
70 if (acl < 0)
71 return acl;
72 if (flags & XATTR_CREATE)
73 return -EINVAL;
74
75 if (!value)
76 return xfs_acl_vremove(inode, acl);
77
78 return xfs_acl_vset(inode, (void *)value, size, acl);
79}
80
81static struct xattr_handler xfs_xattr_system_handler = {
82 .prefix = XATTR_SYSTEM_PREFIX,
83 .get = xfs_xattr_system_get,
84 .set = xfs_xattr_system_set,
85};
86
87
88/*
89 * Real xattr handling. The only difference between the namespaces is
90 * a flag passed to the low-level attr code.
91 */
92
93static int 32static int
94__xfs_xattr_get(struct inode *inode, const char *name, 33__xfs_xattr_get(struct inode *inode, const char *name,
95 void *value, size_t size, int xflags) 34 void *value, size_t size, int xflags)
@@ -199,7 +138,9 @@ struct xattr_handler *xfs_xattr_handlers[] = {
199 &xfs_xattr_user_handler, 138 &xfs_xattr_user_handler,
200 &xfs_xattr_trusted_handler, 139 &xfs_xattr_trusted_handler,
201 &xfs_xattr_security_handler, 140 &xfs_xattr_security_handler,
141#ifdef CONFIG_XFS_POSIX_ACL
202 &xfs_xattr_system_handler, 142 &xfs_xattr_system_handler,
143#endif
203 NULL 144 NULL
204}; 145};
205 146
@@ -310,7 +251,7 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
310 /* 251 /*
311 * Then add the two synthetic ACL attributes. 252 * Then add the two synthetic ACL attributes.
312 */ 253 */
313 if (xfs_acl_vhasacl_access(inode)) { 254 if (posix_acl_access_exists(inode)) {
314 error = list_one_attr(POSIX_ACL_XATTR_ACCESS, 255 error = list_one_attr(POSIX_ACL_XATTR_ACCESS,
315 strlen(POSIX_ACL_XATTR_ACCESS) + 1, 256 strlen(POSIX_ACL_XATTR_ACCESS) + 1,
316 data, size, &context.count); 257 data, size, &context.count);
@@ -318,7 +259,7 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
318 return error; 259 return error;
319 } 260 }
320 261
321 if (xfs_acl_vhasacl_default(inode)) { 262 if (posix_acl_default_exists(inode)) {
322 error = list_one_attr(POSIX_ACL_XATTR_DEFAULT, 263 error = list_one_attr(POSIX_ACL_XATTR_DEFAULT,
323 strlen(POSIX_ACL_XATTR_DEFAULT) + 1, 264 strlen(POSIX_ACL_XATTR_DEFAULT) + 1,
324 data, size, &context.count); 265 data, size, &context.count);