]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.21-jfs-acl.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / linux-2.4.21-jfs-acl.patch
CommitLineData
c42a23b1
JR
1--------------------------------------------------------------------
2This patch adds ACL support for JFS 1.1.2.
3
4This patch was built against linux-2.4.20 + ea+acl+nfsacl-2.4.20-0.8.57 +
5JFS 1.1.2 + the JFS extended attribute patch.
6
7ea+acl+nfsacl-2.4.20-08.57 is available from http://acl.bestbits.at/
8--------------------------------------------------------------------
9diff -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
23diff -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
44diff -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
55diff -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+}
367diff -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 = {
389diff -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);
418diff -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 */
454diff -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)
476diff -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 = {
554diff -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
568diff -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 */
215d0d0a 652+ return -EOPNOTSUPP;
c42a23b1
JR
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.236439 seconds and 4 git commands to generate.