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