]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.21-jfs-acl.patch
- obsolete
[packages/kernel.git] / linux-2.4.21-jfs-acl.patch
1 --------------------------------------------------------------------
2 This patch adds ACL support for JFS 1.1.2.
3
4 This patch was built against linux-2.4.20 + ea+acl+nfsacl-2.4.20-0.8.57 +
5 JFS 1.1.2 + the JFS extended attribute patch.
6
7 ea+acl+nfsacl-2.4.20-08.57 is available from http://acl.bestbits.at/
8 --------------------------------------------------------------------
9 diff -Nur linux-ea/Documentation/Configure.help linux-acl/Documentation/Configure.help
10 --- linux-ea/Documentation/Configure.help       2003-05-08 14:07:13.000000000 -0500
11 +++ linux-acl/Documentation/Configure.help      2003-05-08 14:41:19.000000000 -0500
12 @@ -16232,6 +16232,10 @@
13  
14    If you do not intend to use the JFS filesystem, say N.
15  
16 +JFS Posix ACL support
17 +CONFIG_JFS_POSIX_ACL
18 +  Say Y here for Posix ACL support on JFS.
19 +
20  JFS Debugging
21  CONFIG_JFS_DEBUG
22    If you are experiencing any problems with the JFS filesystem, say
23 diff -Nur linux-ea/fs/Config.in linux-acl/fs/Config.in
24 --- linux-ea/fs/Config.in       2003-05-08 14:07:12.000000000 -0500
25 +++ linux-acl/fs/Config.in      2003-05-08 14:41:19.000000000 -0500
26 @@ -64,6 +64,7 @@
27  dep_mbool '  Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS
28  
29  tristate 'JFS filesystem support' CONFIG_JFS_FS
30 +dep_mbool '  JFS Posix ACL support' CONFIG_JFS_POSIX_ACL $CONFIG_JFS_FS
31  dep_mbool '  JFS debugging' CONFIG_JFS_DEBUG $CONFIG_JFS_FS
32  dep_mbool '  JFS statistics' CONFIG_JFS_STATISTICS $CONFIG_JFS_FS
33  
34 @@ -182,7 +183,8 @@
35  # POSIX ACL helper functions
36  
37  if [ "$CONFIG_EXT2_FS_POSIX_ACL" = "y" -o \
38 -     "$CONFIG_EXT3_FS_POSIX_ACL" = "y" ]; then
39 +     "$CONFIG_EXT3_FS_POSIX_ACL" = "y" -o \
40 +     "$CONFIG_JFS_POSIX_ACL" = "y" ]; then
41     define_bool CONFIG_FS_POSIX_ACL y
42  else
43     bool "POSIX ACL helper functions" CONFIG_FS_POSIX_ACL
44 diff -Nur linux-ea/fs/jfs/Makefile linux-acl/fs/jfs/Makefile
45 --- linux-ea/fs/jfs/Makefile    2003-05-08 14:13:00.000000000 -0500
46 +++ linux-acl/fs/jfs/Makefile   2003-05-08 14:41:19.000000000 -0500
47 @@ -14,6 +14,7 @@
48             jfs_extent.o symlink.o jfs_metapage.o \
49             jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o resize.o xattr.o
50  obj-m   := $(O_TARGET)
51 +obj-$(CONFIG_JFS_POSIX_ACL)    += acl.o
52  
53  EXTRA_CFLAGS += -D_JFS_4K
54  
55 diff -Nur linux-ea/fs/jfs/acl.c linux-acl/fs/jfs/acl.c
56 --- linux-ea/fs/jfs/acl.c       1969-12-31 18:00:00.000000000 -0600
57 +++ linux-acl/fs/jfs/acl.c      2003-05-08 14:41:19.000000000 -0500
58 @@ -0,0 +1,308 @@
59 +/*
60 + *   Copyright (c) International Business Machines  Corp., 2002-2003
61 + *   Copyright (c) Andreas Gruenbacher, 2001
62 + *   Copyright (c) Linus Torvalds, 1991, 1992
63 + *
64 + *   This program is free software;  you can redistribute it and/or modify
65 + *   it under the terms of the GNU General Public License as published by
66 + *   the Free Software Foundation; either version 2 of the License, or 
67 + *   (at your option) any later version.
68 + * 
69 + *   This program is distributed in the hope that it will be useful,
70 + *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
71 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
72 + *   the GNU General Public License for more details.
73 + *
74 + *   You should have received a copy of the GNU General Public License
75 + *   along with this program;  if not, write to the Free Software 
76 + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
77 + */
78 +
79 +#include <linux/fs.h>
80 +#include "jfs_incore.h"
81 +#include "jfs_xattr.h"
82 +#include "jfs_acl.h"
83 +
84 +static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
85 +{
86 +       struct posix_acl *acl;
87 +       char *ea_name;
88 +       struct jfs_inode_info *ji = JFS_IP(inode);
89 +       struct posix_acl **p_acl;
90 +       int size;
91 +       char *value = NULL;
92 +
93 +       switch(type) {
94 +               case ACL_TYPE_ACCESS:
95 +                       ea_name = XATTR_NAME_ACL_ACCESS;
96 +                       p_acl = &ji->i_acl;
97 +                       break;
98 +               case ACL_TYPE_DEFAULT:
99 +                       ea_name = XATTR_NAME_ACL_DEFAULT;
100 +                       p_acl = &ji->i_default_acl;
101 +                       break;
102 +               default:
103 +                       return ERR_PTR(-EINVAL);
104 +       }
105 +
106 +       if (*p_acl != JFS_ACL_NOT_CACHED)
107 +               return posix_acl_dup(*p_acl);
108 +
109 +       size = __jfs_getxattr(inode, ea_name, NULL, 0);
110 +
111 +       if (size > 0) {
112 +               value = kmalloc(size, GFP_KERNEL);
113 +               if (!value)
114 +                       return ERR_PTR(-ENOMEM);
115 +               size = __jfs_getxattr(inode, ea_name, value, size);
116 +       }
117 +
118 +       if (size < 0) {
119 +               if (size == -ENODATA) {
120 +                       *p_acl = NULL;
121 +                       acl = NULL;
122 +               } else
123 +                       acl = ERR_PTR(size);
124 +       } else {
125 +               acl = posix_acl_from_xattr(value, size);
126 +               if (!IS_ERR(acl))
127 +                       *p_acl = posix_acl_dup(acl);
128 +       }
129 +       if (value)
130 +               kfree(value);
131 +       return acl;
132 +}
133 +
134 +static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
135 +{
136 +       char *ea_name;
137 +       struct jfs_inode_info *ji = JFS_IP(inode);
138 +       struct posix_acl **p_acl;
139 +       int rc;
140 +       int size = 0;
141 +       char *value = NULL;
142 +
143 +       if (S_ISLNK(inode->i_mode))
144 +               return -EOPNOTSUPP;
145 +
146 +       switch(type) {
147 +               case ACL_TYPE_ACCESS:
148 +                       ea_name = XATTR_NAME_ACL_ACCESS;
149 +                       p_acl = &ji->i_acl;
150 +                       break;
151 +               case ACL_TYPE_DEFAULT:
152 +                       ea_name = XATTR_NAME_ACL_DEFAULT;
153 +                       p_acl = &ji->i_default_acl;
154 +                       if (!S_ISDIR(inode->i_mode))
155 +                               return acl ? -EACCES : 0;
156 +                       break;
157 +               default:
158 +                       return -EINVAL;
159 +       }
160 +       if (acl) {
161 +               size = xattr_acl_size(acl->a_count);
162 +               value = kmalloc(size, GFP_KERNEL);
163 +               if (!value)
164 +                       return -ENOMEM;
165 +               rc = posix_acl_to_xattr(acl, value, size);
166 +               if (rc < 0)
167 +                       goto out;
168 +       }
169 +       rc = __jfs_setxattr(inode, ea_name, value, size, 0);
170 +out:
171 +       if (value)
172 +               kfree(value);
173 +
174 +       if (!rc) {
175 +               if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED))
176 +                       posix_acl_release(*p_acl);
177 +               *p_acl = posix_acl_dup(acl);
178 +       }
179 +       return rc;
180 +}
181 +
182 +/*
183 + *     __jfs_permission()
184 + *
185 + * modified vfs_permission to check posix acl
186 + */
187 +static int __jfs_permission(struct inode * inode, int mask, int have_sem)
188 +{
189 +       umode_t mode = inode->i_mode;
190 +       struct jfs_inode_info *ji = JFS_IP(inode);
191 +
192 +       if (mask & MAY_WRITE) {
193 +               /*
194 +                * Nobody gets write access to a read-only fs.
195 +                */
196 +               if (IS_RDONLY(inode) &&
197 +                   (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
198 +                       return -EROFS;
199 +
200 +               /*
201 +                * Nobody gets write access to an immutable file.
202 +                */
203 +               if (IS_IMMUTABLE(inode))
204 +                       return -EACCES;
205 +       }
206 +
207 +       if (current->fsuid == inode->i_uid) {
208 +               mode >>= 6;
209 +               goto check_mode;
210 +       }
211 +       /*
212 +        * ACL can't contain additional permissions if the ACL_MASK entry
213 +        * is zero.
214 +        */
215 +       if (!(mode & S_IRWXG))
216 +               goto check_groups;
217 +
218 +       if (ji->i_acl == JFS_ACL_NOT_CACHED) {
219 +               struct posix_acl *acl;
220 +
221 +               if (!have_sem)
222 +                       down(&inode->i_sem);
223 +               acl = jfs_get_acl(inode, ACL_TYPE_ACCESS);
224 +               if (!have_sem)
225 +                       up(&inode->i_sem);
226 +
227 +               if (IS_ERR(acl))
228 +                       return PTR_ERR(acl);
229 +               posix_acl_release(acl);
230 +       }
231 +
232 +       if (ji->i_acl) {
233 +               int rc = posix_acl_permission(inode, ji->i_acl, mask);
234 +               if (rc == -EACCES)
235 +                       goto check_capabilities;
236 +               return rc;
237 +       }
238 +
239 +check_groups:
240 +       if (in_group_p(inode->i_gid))
241 +               mode >>= 3;
242 +
243 +check_mode:
244 +       /*
245 +        * If the DACs are ok we don't need any capability check.
246 +        */
247 +       if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask))
248 +               return 0;
249 +
250 +check_capabilities:
251 +       /*
252 +        * Read/write DACs are always overridable.
253 +        * Executable DACs are overridable if at least one exec bit is set.
254 +        */
255 +       if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
256 +               if (capable(CAP_DAC_OVERRIDE))
257 +                       return 0;
258 +
259 +       /*
260 +        * Searching includes executable on directories, else just read.
261 +        */
262 +       if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
263 +               if (capable(CAP_DAC_READ_SEARCH))
264 +                       return 0;
265 +
266 +       return -EACCES;
267 +}
268 +int jfs_permission(struct inode * inode, int mask)
269 +{
270 +       return __jfs_permission(inode, mask, 0);
271 +}
272 +int jfs_permission_have_sem(struct inode * inode, int mask)
273 +{
274 +       return __jfs_permission(inode, mask, 1);
275 +}
276 +
277 +int jfs_init_acl(struct inode *inode, struct inode *dir)
278 +{
279 +       struct posix_acl *acl = NULL;
280 +       struct posix_acl *clone;
281 +       mode_t mode;
282 +       int rc = 0;
283 +
284 +       if (S_ISLNK(inode->i_mode))
285 +               return 0;
286 +
287 +       acl = jfs_get_acl(dir, ACL_TYPE_DEFAULT);
288 +       if (IS_ERR(acl))
289 +               return PTR_ERR(acl);
290 +
291 +       if (acl) {
292 +               if (S_ISDIR(inode->i_mode)) {
293 +                       rc = jfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
294 +                       if (rc)
295 +                               goto cleanup;
296 +               }
297 +               clone = posix_acl_clone(acl, GFP_KERNEL);
298 +               if (!clone) {
299 +                       rc = -ENOMEM;
300 +                       goto cleanup;
301 +               }
302 +               mode = inode->i_mode;
303 +               rc = posix_acl_create_masq(clone, &mode);
304 +               if (rc >= 0) {
305 +                       inode->i_mode = mode;
306 +                       if (rc > 0)
307 +                               rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
308 +               }
309 +               posix_acl_release(clone);
310 +cleanup:
311 +               posix_acl_release(acl);
312 +       } else
313 +               inode->i_mode &= ~current->fs->umask;
314 +
315 +       return rc;
316 +}
317 +
318 +int jfs_acl_chmod(struct inode *inode)
319 +{
320 +       struct posix_acl *acl, *clone;
321 +       int rc;
322 +
323 +       if (S_ISLNK(inode->i_mode))
324 +               return -EOPNOTSUPP;
325 +
326 +       acl = jfs_get_acl(inode, ACL_TYPE_ACCESS);
327 +       if (IS_ERR(acl) || !acl)
328 +               return PTR_ERR(acl);
329 +
330 +       clone = posix_acl_clone(acl, GFP_KERNEL);
331 +       posix_acl_release(acl);
332 +       if (!clone)
333 +               return -ENOMEM;
334 +
335 +       rc = posix_acl_chmod_masq(clone, inode->i_mode);
336 +       if (!rc)
337 +               rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
338 +
339 +       posix_acl_release(clone);
340 +       return rc;
341 +}
342 +
343 +int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
344 +{
345 +       struct inode *inode = dentry->d_inode;
346 +       int rc;
347 +
348 +       rc = inode_change_ok(inode, iattr);
349 +       if (rc)
350 +               return rc;
351 +
352 +       inode_setattr(inode, iattr);
353 +
354 +       if (iattr->ia_valid & ATTR_MODE) {
355 +               /*
356 +                * Mode change may affect acl.  i_sem already held by
357 +                * truncate (ia_valid & ATTR_SIZE)
358 +                */
359 +               if (!(iattr->ia_valid & ATTR_SIZE))
360 +                       down(&inode->i_sem);
361 +               rc = jfs_acl_chmod(inode);
362 +               if (!(iattr->ia_valid & ATTR_SIZE))
363 +                       up(&inode->i_sem);
364 +       }
365 +       return rc;
366 +}
367 diff -Nur linux-ea/fs/jfs/file.c linux-acl/fs/jfs/file.c
368 --- linux-ea/fs/jfs/file.c      2003-05-08 14:13:00.000000000 -0500
369 +++ linux-acl/fs/jfs/file.c     2003-05-08 14:41:19.000000000 -0500
370 @@ -23,6 +23,7 @@
371  #include "jfs_dmap.h"
372  #include "jfs_txnmgr.h"
373  #include "jfs_xattr.h"
374 +#include "jfs_acl.h"
375  #include "jfs_debug.h"
376  
377  
378 @@ -96,6 +97,10 @@
379         .getxattr       = jfs_getxattr,
380         .listxattr      = jfs_listxattr,
381         .removexattr    = jfs_removexattr,
382 +#ifdef CONFIG_JFS_POSIX_ACL
383 +       .setattr        = jfs_setattr,
384 +       .permission     = jfs_permission,
385 +#endif
386  };
387  
388  struct file_operations jfs_file_operations = {
389 diff -Nur linux-ea/fs/jfs/inode.c linux-acl/fs/jfs/inode.c
390 --- linux-ea/fs/jfs/inode.c     2003-05-08 14:13:00.000000000 -0500
391 +++ linux-acl/fs/jfs/inode.c    2003-05-08 14:41:19.000000000 -0500
392 @@ -24,6 +24,7 @@
393  #include "jfs_dmap.h"
394  #include "jfs_imap.h"
395  #include "jfs_extent.h"
396 +#include "jfs_acl.h"
397  #include "jfs_unicode.h"
398  #include "jfs_debug.h"
399  
400 @@ -57,6 +58,17 @@
401  
402         ASSERT(list_empty(&ji->anon_inode_list));
403  
404 +#ifdef CONFIG_JFS_POSIX_ACL
405 +       if (ji->i_acl != JFS_ACL_NOT_CACHED) {
406 +               posix_acl_release(ji->i_acl);
407 +               ji->i_acl = JFS_ACL_NOT_CACHED;
408 +       }
409 +       if (ji->i_default_acl != JFS_ACL_NOT_CACHED) {
410 +               posix_acl_release(ji->i_default_acl);
411 +               ji->i_default_acl = JFS_ACL_NOT_CACHED;
412 +       }
413 +#endif
414 +
415         if (ji->atlhead) {
416                 jfs_err("jfs_clear_inode: inode %p has anonymous tlocks",
417                         inode);
418 diff -Nur linux-ea/fs/jfs/jfs_acl.h linux-acl/fs/jfs/jfs_acl.h
419 --- linux-ea/fs/jfs/jfs_acl.h   1969-12-31 18:00:00.000000000 -0600
420 +++ linux-acl/fs/jfs/jfs_acl.h  2003-05-08 14:41:19.000000000 -0500
421 @@ -0,0 +1,32 @@
422 +/*
423 + *   Copyright (c) International Business Machines  Corp., 2002-2003
424 + *
425 + *   This program is free software;  you can redistribute it and/or modify
426 + *   it under the terms of the GNU General Public License as published by
427 + *   the Free Software Foundation; either version 2 of the License, or 
428 + *   (at your option) any later version.
429 + * 
430 + *   This program is distributed in the hope that it will be useful,
431 + *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
432 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
433 + *   the GNU General Public License for more details.
434 + *
435 + *   You should have received a copy of the GNU General Public License
436 + *   along with this program;  if not, write to the Free Software 
437 + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
438 + */
439 +#ifndef _H_JFS_ACL
440 +#define _H_JFS_ACL
441 +
442 +#ifdef CONFIG_JFS_POSIX_ACL
443 +
444 +#include <linux/xattr_acl.h>
445 +
446 +int jfs_permission_have_sem(struct inode *, int);
447 +int jfs_permission(struct inode *, int);
448 +int jfs_init_acl(struct inode *, struct inode *);
449 +int jfs_setattr(struct dentry *, struct iattr *);
450 +
451 +#endif                         /* CONFIG_JFS_POSIX_ACL */
452 +
453 +#endif                         /* _H_JFS_ACL */
454 diff -Nur linux-ea/fs/jfs/jfs_incore.h linux-acl/fs/jfs/jfs_incore.h
455 --- linux-ea/fs/jfs/jfs_incore.h        2003-05-08 14:13:01.000000000 -0500
456 +++ linux-acl/fs/jfs/jfs_incore.h       2003-05-08 14:41:19.000000000 -0500
457 @@ -69,6 +69,10 @@
458          */
459         struct semaphore commit_sem;
460         lid_t   xtlid;          /* lid of xtree lock on directory */
461 +#ifdef CONFIG_JFS_POSIX_ACL
462 +       struct posix_acl *i_acl;
463 +       struct posix_acl *i_default_acl;
464 +#endif
465         union {
466                 struct {
467                         xtpage_t _xtroot;       /* 288: xtree root */
468 @@ -96,6 +100,7 @@
469  #define i_inline u.link._inline
470  #define i_inline_ea u.link._inline_ea
471  
472 +#define JFS_ACL_NOT_CACHED ((void *)-1)
473  
474  #define IREAD_LOCK(ip)         down_read(&JFS_IP(ip)->rdwrlock)
475  #define IREAD_UNLOCK(ip)       up_read(&JFS_IP(ip)->rdwrlock)
476 diff -Nur linux-ea/fs/jfs/namei.c linux-acl/fs/jfs/namei.c
477 --- linux-ea/fs/jfs/namei.c     2003-05-08 14:13:01.000000000 -0500
478 +++ linux-acl/fs/jfs/namei.c    2003-05-08 14:41:19.000000000 -0500
479 @@ -25,6 +25,7 @@
480  #include "jfs_unicode.h"
481  #include "jfs_metapage.h"
482  #include "jfs_xattr.h"
483 +#include "jfs_acl.h"
484  #include "jfs_debug.h"
485  
486  extern struct inode_operations jfs_file_inode_operations;
487 @@ -35,6 +36,7 @@
488  
489  extern int jfs_fsync(struct file *, struct dentry *, int);
490  extern void jfs_truncate_nolock(struct inode *, loff_t);
491 +extern int jfs_init_acl(struct inode *, struct inode *);
492  
493  /*
494   * forward references
495 @@ -150,6 +152,11 @@
496        out2:
497         free_UCSname(&dname);
498  
499 +#ifdef CONFIG_JFS_POSIX_ACL
500 +       if (rc == 0)
501 +               jfs_init_acl(ip, dip);
502 +#endif
503 +
504        out1:
505  
506         jfs_info("jfs_create: rc:%d", -rc);
507 @@ -275,6 +282,11 @@
508        out2:
509         free_UCSname(&dname);
510  
511 +#ifdef CONFIG_JFS_POSIX_ACL
512 +       if (rc == 0)
513 +               jfs_init_acl(ip, dip);
514 +#endif
515 +
516        out1:
517  
518         jfs_info("jfs_mkdir: rc:%d", -rc);
519 @@ -1009,6 +1021,11 @@
520        out2:
521         free_UCSname(&dname);
522  
523 +#ifdef CONFIG_JFS_POSIX_ACL
524 +       if (rc == 0)
525 +               jfs_init_acl(ip, dip);
526 +#endif
527 +
528        out1:
529         jfs_info("jfs_symlink: rc:%d", -rc);
530         return -rc;
531 @@ -1345,6 +1362,11 @@
532        out1:
533         free_UCSname(&dname);
534  
535 +#ifdef CONFIG_JFS_POSIX_ACL
536 +       if (rc == 0)
537 +               jfs_init_acl(ip, dir);
538 +#endif
539 +
540        out:
541         jfs_info("jfs_mknod: returning %d", rc);
542         return -rc;
543 @@ -1407,6 +1429,10 @@
544         .getxattr       = jfs_getxattr,
545         .listxattr      = jfs_listxattr,
546         .removexattr    = jfs_removexattr,
547 +#ifdef CONFIG_JFS_POSIX_ACL
548 +       .setattr        = jfs_setattr,
549 +       .permission     = jfs_permission,
550 +#endif
551  };
552  
553  struct file_operations jfs_dir_operations = {
554 diff -Nur linux-ea/fs/jfs/super.c linux-acl/fs/jfs/super.c
555 --- linux-ea/fs/jfs/super.c     2003-05-08 14:10:45.000000000 -0500
556 +++ linux-acl/fs/jfs/super.c    2003-05-08 14:41:19.000000000 -0500
557 @@ -432,6 +432,10 @@
558                 init_MUTEX(&jfs_ip->commit_sem);
559                 jfs_ip->atlhead = 0;
560                 jfs_ip->active_ag = -1;
561 +#ifdef CONFIG_JFS_POSIX_ACL
562 +               jfs_ip->i_acl = JFS_ACL_NOT_CACHED;
563 +               jfs_ip->i_default_acl = JFS_ACL_NOT_CACHED;
564 +#endif
565         }
566  }
567  
568 diff -Nur linux-ea/fs/jfs/xattr.c linux-acl/fs/jfs/xattr.c
569 --- linux-ea/fs/jfs/xattr.c     2003-05-08 14:30:04.000000000 -0500
570 +++ linux-acl/fs/jfs/xattr.c    2003-05-08 14:41:19.000000000 -0500
571 @@ -26,6 +26,7 @@
572  #include "jfs_extent.h"
573  #include "jfs_metapage.h"
574  #include "jfs_xattr.h"
575 +#include "jfs_acl.h"
576  
577  /*
578   *     jfs_xattr.c: extended attribute service
579 @@ -201,7 +202,6 @@
580                         ji->mode2 |= INLINEEA;
581         }
582  
583 -       mark_inode_dirty(ip);
584         return 0;
585  }
586  
587 @@ -640,6 +640,71 @@
588         return rc;
589  }
590  
591 +/*
592 + * can_set_system_xattr
593 + *
594 + * This code is specific to the system.* namespace.  It contains policy
595 + * which doesn't belong in the main xattr codepath.
596 + */
597 +static int can_set_system_xattr(struct inode *inode, const char *name,
598 +                               const void *value, size_t value_len)
599 +{
600 +#ifdef CONFIG_JFS_POSIX_ACL
601 +       struct posix_acl *acl;
602 +       int rc;
603 +
604 +       if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
605 +               return -EPERM;
606 +
607 +       /*
608 +        * XATTR_NAME_ACL_ACCESS is tied to i_mode
609 +        */
610 +       if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) {
611 +               acl = posix_acl_from_xattr(value, value_len);
612 +               if (acl < 0) {
613 +                       printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
614 +                              rc);
615 +                       return rc;
616 +               }
617 +               if (acl > 0) {
618 +                       mode_t mode = inode->i_mode;
619 +                       rc = posix_acl_equiv_mode(acl, &mode);
620 +                       posix_acl_release(acl);
621 +                       if (rc < 0) {
622 +                               printk(KERN_ERR
623 +                                      "posix_acl_equiv_mode returned %d\n",
624 +                                      rc);
625 +                               return rc;
626 +                       }
627 +                       inode->i_mode = mode;
628 +                       mark_inode_dirty(inode);
629 +                       if (rc == 0)
630 +                               value = NULL;
631 +               }
632 +               /*
633 +                * We're changing the ACL.  Get rid of the cached one
634 +                */
635 +               acl =JFS_IP(inode)->i_acl;
636 +               if (acl && (acl != JFS_ACL_NOT_CACHED))
637 +                       posix_acl_release(acl);
638 +               JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
639 +       } else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) {
640 +               /*
641 +                * We're changing the default ACL.  Get rid of the cached one
642 +                */
643 +               acl =JFS_IP(inode)->i_default_acl;
644 +               if (acl && (acl != JFS_ACL_NOT_CACHED))
645 +                       posix_acl_release(acl);
646 +               JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED;
647 +       } else
648 +               /* Invalid xattr name */
649 +               return -EINVAL;
650 +       return 0;
651 +#else                  /* CONFIG_JFS_POSIX_ACL */
652 +       return -EOPNOTSUPP;
653 +#endif                 /* CONFIG_JFS_POSIX_ACL */
654 +}
655 +
656  static int can_set_xattr(struct inode *inode, const char *name,
657                          const void *value, size_t value_len)
658  {
659 @@ -649,6 +714,12 @@
660         if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
661                 return -EPERM;
662  
663 +       if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
664 +               /*
665 +                * "system.*"
666 +                */
667 +               return can_set_system_xattr(inode, name, value, value_len);
668 +
669         if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) &&
670            (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) != 0))
671                 return -EOPNOTSUPP;
672 @@ -657,7 +728,11 @@
673             (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX))
674                 return -EPERM;
675  
676 +#ifdef CONFIG_JFS_POSIX_ACL
677 +       return jfs_permission_have_sem(inode, MAY_WRITE);
678 +#else
679         return permission(inode, MAY_WRITE);
680 +#endif
681  }
682  
683  int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
684 @@ -810,9 +885,16 @@
685         return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags);
686  }
687  
688 -static inline int can_get_xattr(struct inode *inode, const char *name)
689 +static int can_get_xattr(struct inode *inode, const char *name)
690  {
691 +#ifdef CONFIG_JFS_POSIX_ACL
692 +       if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
693 +               return 0;
694 +       else
695 +               return jfs_permission_have_sem(inode, MAY_READ);
696 +#else
697         return permission(inode, MAY_READ);
698 +#endif
699  }
700  
701  ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
This page took 0.073446 seconds and 3 git commands to generate.