1 diff -urN linux-2.4.22/fs/Config.in linux-2.4.22-aclea/fs/Config.in
2 --- linux-2.4.22/fs/Config.in 2003-09-12 17:01:18.000000000 +0200
3 +++ linux-2.4.22-aclea/fs/Config.in 2003-09-12 17:19:43.000000000 +0200
5 tristate 'Reiserfs support' CONFIG_REISERFS_FS
6 dep_mbool ' Enable reiserfs debug mode' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS
7 dep_mbool ' Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS
8 +dep_mbool ' ReiserFS extended attributes' CONFIG_REISERFS_FS_XATTR $CONFIG_REISERFS_FS
9 +dep_mbool ' ReiserFS extended user attributes' CONFIG_REISERFS_FS_XATTR_USER $CONFIG_REISERFS_FS_XATTR
10 +dep_mbool ' ReiserFS trusted extended attributes' CONFIG_REISERFS_FS_XATTR_TRUSTED $CONFIG_REISERFS_FS_XATTR
11 +dep_mbool ' ReiserFS POSIX Access Control Lists' CONFIG_REISERFS_FS_POSIX_ACL $CONFIG_REISERFS_FS_XATTR $CONFIG_FS_POSIX_ACL
13 dep_tristate 'ADFS file system support (EXPERIMENTAL)' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
14 dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
15 diff -urN linux-2.4.22/fs/reiserfs/Makefile linux-2.4.22-aclea/fs/reiserfs/Makefile
16 --- linux-2.4.22/fs/reiserfs/Makefile 2003-08-25 13:44:43.000000000 +0200
17 +++ linux-2.4.22-aclea/fs/reiserfs/Makefile 2003-09-12 17:19:43.000000000 +0200
19 obj-y := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o super.o prints.o objectid.o \
20 lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o item_ops.o ioctl.o procfs.o
22 +obj-$(CONFIG_REISERFS_FS_XATTR) += xattr.o
23 +obj-$(CONFIG_REISERFS_FS_XATTR_USER) += xattr_user.o
24 +obj-$(CONFIG_REISERFS_FS_XATTR_TRUSTED) += xattr_trusted.o
25 +obj-$(CONFIG_REISERFS_FS_POSIX_ACL) += xattr_acl.o
29 # gcc -O2 (the kernel default) is overaggressive on ppc32 when many inline
30 diff -urN linux-2.4.22/fs/reiserfs/dir.c linux-2.4.22-aclea/fs/reiserfs/dir.c
31 --- linux-2.4.22/fs/reiserfs/dir.c 2003-08-25 13:44:43.000000000 +0200
32 +++ linux-2.4.22-aclea/fs/reiserfs/dir.c 2003-09-12 17:19:29.000000000 +0200
34 /* too big to send back to VFS */
38 + /* Ignore the .reiserfs_priv entry */
39 + if (reiserfs_xattrs (inode->i_sb) &&
40 + !old_format_only(inode->i_sb) &&
41 + inode->i_sb->u.reiserfs_sb.priv_root &&
42 + inode->i_sb->u.reiserfs_sb.priv_root->d_inode &&
43 + deh_objectid (deh) == le32_to_cpu (INODE_PKEY(inode->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid))
46 d_off = deh_offset (deh);
48 d_ino = deh_objectid (deh);
49 diff -urN linux-2.4.22/fs/reiserfs/file.c linux-2.4.22-aclea/fs/reiserfs/file.c
50 --- linux-2.4.22/fs/reiserfs/file.c 2002-11-29 00:53:15.000000000 +0100
51 +++ linux-2.4.22-aclea/fs/reiserfs/file.c 2003-09-12 17:19:36.000000000 +0200
54 #include <linux/sched.h>
55 #include <linux/reiserfs_fs.h>
56 +#include <linux/reiserfs_acl.h>
57 +#include <linux/reiserfs_xattr.h>
58 #include <linux/smp_lock.h>
62 return ( n_err < 0 ) ? -EIO : 0;
65 -static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
66 - struct inode *inode = dentry->d_inode ;
68 - if (attr->ia_valid & ATTR_SIZE) {
69 - /* version 2 items will be caught by the s_maxbytes check
70 - ** done for us in vmtruncate
72 - if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
73 - attr->ia_size > MAX_NON_LFS)
76 - /* fill in hole pointers in the expanding truncate case. */
77 - if (attr->ia_size > inode->i_size) {
78 - error = generic_cont_expand(inode, attr->ia_size) ;
79 - if (inode->u.reiserfs_i.i_prealloc_count > 0) {
80 - struct reiserfs_transaction_handle th ;
81 - /* we're changing at most 2 bitmaps, inode + super */
82 - journal_begin(&th, inode->i_sb, 4) ;
83 - reiserfs_discard_prealloc (&th, inode);
84 - journal_end(&th, inode->i_sb, 4) ;
91 - if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
92 - ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
93 - (get_inode_sd_version (inode) == STAT_DATA_V1))
94 - /* stat data of format v3.5 has 16 bit uid and gid */
97 - error = inode_change_ok(inode, attr) ;
99 - inode_setattr(inode, attr) ;
104 struct file_operations reiserfs_file_operations = {
105 read: generic_file_read,
106 write: generic_file_write,
108 struct inode_operations reiserfs_file_inode_operations = {
109 truncate: reiserfs_vfs_truncate_file,
110 setattr: reiserfs_setattr,
111 + setxattr: reiserfs_setxattr,
112 + getxattr: reiserfs_getxattr,
113 + listxattr: reiserfs_listxattr,
114 + removexattr: reiserfs_removexattr,
115 + permission: reiserfs_permission,
119 diff -urN linux-2.4.22/fs/reiserfs/inode.c linux-2.4.22-aclea/fs/reiserfs/inode.c
120 --- linux-2.4.22/fs/reiserfs/inode.c 2003-08-25 13:44:43.000000000 +0200
121 +++ linux-2.4.22-aclea/fs/reiserfs/inode.c 2003-09-12 17:19:36.000000000 +0200
123 #include <linux/config.h>
124 #include <linux/sched.h>
125 #include <linux/reiserfs_fs.h>
126 +#include <linux/reiserfs_acl.h>
127 +#include <linux/reiserfs_xattr.h>
128 #include <linux/locks.h>
129 #include <linux/smp_lock.h>
130 +#include <linux/quotaops.h>
131 #include <asm/uaccess.h>
132 #include <asm/unaligned.h>
135 if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
136 down (&inode->i_sem);
138 + reiserfs_delete_xattrs (inode);
140 journal_begin(&th, inode->i_sb, jbegin_count) ;
141 reiserfs_update_inode_transaction(inode) ;
142 windex = push_journal_writer("delete_inode") ;
144 struct super_block *s = th->t_super ;
145 int len = th->t_blocks_allocated ;
147 + /* we cannot restart while nested */
148 + if (th->t_refcount > 1) {
152 reiserfs_update_sd(th, inode) ;
153 journal_end(th, s, len) ;
154 @@ -1016,7 +1025,7 @@
155 inode->i_op = &reiserfs_dir_inode_operations;
156 inode->i_fop = &reiserfs_dir_operations;
157 } else if (S_ISLNK (inode->i_mode)) {
158 - inode->i_op = &page_symlink_inode_operations;
159 + inode->i_op = &reiserfs_symlink_inode_operations;
160 inode->i_mapping->a_ops = &reiserfs_address_space_operations;
163 @@ -1694,6 +1703,18 @@
164 goto out_inserted_sd;
167 + if (reiserfs_posixacl (inode->i_sb)) {
168 + retval = reiserfs_inherit_default_acl (dir, dentry, inode);
172 + reiserfs_check_path(&path_to_key) ;
173 + goto out_inserted_sd;
175 + } else if (inode->i_sb->s_flags & MS_POSIXACL) {
176 + reiserfs_warning (inode->i_sb, "ACLs aren't enabled in the fs, but vfs thinks they are!\n");
179 insert_inode_hash (inode);
180 reiserfs_update_sd(th, inode) ;
181 reiserfs_check_path(&path_to_key) ;
182 @@ -2229,6 +2250,72 @@
183 reiserfs_get_block_direct_io) ;
186 +int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
187 + struct inode *inode = dentry->d_inode ;
189 + unsigned int ia_valid = attr->ia_valid;
190 + if (attr->ia_valid & ATTR_SIZE) {
191 + /* version 2 items will be caught by the s_maxbytes check
192 + ** done for us in vmtruncate
194 + if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
195 + attr->ia_size > MAX_NON_LFS)
198 + /* fill in hole pointers in the expanding truncate case. */
199 + if (attr->ia_size > inode->i_size) {
200 + error = generic_cont_expand(inode, attr->ia_size) ;
201 + if (inode->u.reiserfs_i.i_prealloc_count > 0) {
202 + struct reiserfs_transaction_handle th ;
203 + /* we're changing at most 2 bitmaps, inode + super */
204 + journal_begin(&th, inode->i_sb, 4) ;
205 + reiserfs_discard_prealloc (&th, inode);
206 + journal_end(&th, inode->i_sb, 4) ;
213 + if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
214 + ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
215 + (get_inode_sd_version (inode) == STAT_DATA_V1))
216 + /* stat data of format v3.5 has 16 bit uid and gid */
219 + error = inode_change_ok(inode, attr) ;
221 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
222 + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
223 + if (!(attr->ia_valid & ATTR_SIZE))
224 + down (&inode->i_sem);
225 + error = reiserfs_chown_xattrs (inode, attr);
226 + if (!(attr->ia_valid & ATTR_SIZE))
227 + up (&inode->i_sem);
229 +#if defined(CONFIG_QUOTA)
231 + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
235 + inode_setattr(inode, attr) ;
239 + if (!error && reiserfs_posixacl (inode->i_sb)) {
240 + if (attr->ia_valid & ATTR_MODE) {
241 + if (!(attr->ia_valid & ATTR_SIZE))
242 + down (&inode->i_sem);
243 + error = reiserfs_acl_chmod (inode);
244 + if (!(attr->ia_valid & ATTR_SIZE))
245 + up (&inode->i_sem);
252 struct address_space_operations reiserfs_address_space_operations = {
253 writepage: reiserfs_writepage,
254 readpage: reiserfs_readpage,
255 diff -urN linux-2.4.22/fs/reiserfs/journal.c linux-2.4.22-aclea/fs/reiserfs/journal.c
256 --- linux-2.4.22/fs/reiserfs/journal.c 2003-08-25 13:44:43.000000000 +0200
257 +++ linux-2.4.22-aclea/fs/reiserfs/journal.c 2003-09-12 17:04:51.000000000 +0200
258 @@ -2232,6 +2232,9 @@
259 time_t now = CURRENT_TIME ;
260 if (reiserfs_dont_log(th->t_super))
262 + /* cannot restart while nested */
263 + if (th->t_refcount > 1)
265 if ( SB_JOURNAL(th->t_super)->j_must_wait > 0 ||
266 (SB_JOURNAL(th->t_super)->j_len_alloc + new_alloc) >= SB_JOURNAL_MAX_BATCH(th->t_super) ||
267 atomic_read(&(SB_JOURNAL(th->t_super)->j_jlock)) ||
268 @@ -2287,6 +2290,9 @@
271 PROC_INFO_INC( p_s_sb, journal.journal_being );
272 + /* set here for journal_join */
273 + th->t_refcount = 1;
274 + th->t_super = p_s_sb ;
277 lock_journal(p_s_sb) ;
278 @@ -2343,9 +2349,7 @@
279 SB_JOURNAL(p_s_sb)->j_len_alloc += nblocks ;
280 th->t_blocks_logged = 0 ;
281 th->t_blocks_allocated = nblocks ;
282 - th->t_super = p_s_sb ;
283 th->t_trans_id = SB_JOURNAL(p_s_sb)->j_trans_id ;
284 - th->t_caller = "Unknown" ;
285 unlock_journal(p_s_sb) ;
288 @@ -2353,11 +2357,47 @@
291 static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
292 + struct reiserfs_transaction_handle *cur_th = current->journal_info;
294 + /* this keeps do_journal_end from NULLing out the current->journal_info
297 + th->t_handle_save = cur_th ;
298 + if (cur_th && cur_th->t_refcount > 1) {
301 return do_journal_begin_r(th, p_s_sb, nblocks, 1) ;
304 int journal_begin(struct reiserfs_transaction_handle *th, struct super_block * p_s_sb, unsigned long nblocks) {
305 - return do_journal_begin_r(th, p_s_sb, nblocks, 0) ;
306 + struct reiserfs_transaction_handle *cur_th = current->journal_info ;
309 + th->t_handle_save = NULL ;
311 + /* we are nesting into the current transaction */
312 + if (cur_th->t_super == p_s_sb) {
313 + cur_th->t_refcount++ ;
314 + memcpy(th, cur_th, sizeof(*th));
315 + if (th->t_refcount <= 1)
316 + printk("BAD: refcount <= 1, but journal_info != 0\n");
319 + /* we've ended up with a handle from a different filesystem.
320 + ** save it and restore on journal_end. This should never
321 + ** really happen...
323 + reiserfs_warning("clm-2100: nesting info a different FS\n") ;
324 + th->t_handle_save = current->journal_info ;
325 + current->journal_info = th;
328 + current->journal_info = th;
330 + ret = do_journal_begin_r(th, p_s_sb, nblocks, 0) ;
331 + if (current->journal_info != th)
336 /* not used at all */
337 @@ -2497,7 +2537,23 @@
340 int journal_end(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
341 - return do_journal_end(th, p_s_sb, nblocks, 0) ;
342 + if (!current->journal_info && th->t_refcount > 1)
343 + printk("REISER-NESTING: th NULL, refcount %d\n", th->t_refcount);
344 + if (th->t_refcount > 1) {
345 + struct reiserfs_transaction_handle *cur_th = current->journal_info ;
347 + /* we aren't allowed to close a nested transaction on a different
348 + ** filesystem from the one in the task struct
350 + if (cur_th->t_super != th->t_super)
354 + memcpy(current->journal_info, th, sizeof(*th));
357 + return do_journal_end(th, p_s_sb, nblocks, 0) ;
361 /* removes from the current transaction, relsing and descrementing any counters.
362 @@ -2600,6 +2656,10 @@
364 int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
366 + /* you can sync while nested, very, very bad */
367 + if (th->t_refcount > 1) {
370 if (SB_JOURNAL(p_s_sb)->j_len == 0) {
371 reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
372 journal_mark_dirty(th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
373 @@ -3000,6 +3060,10 @@
374 int wait_on_commit = flags & WAIT ;
375 struct reiserfs_super_block *rs ;
377 + if (th->t_refcount > 1)
380 + current->journal_info = th->t_handle_save;
381 if (reiserfs_dont_log(th->t_super)) {
384 @@ -3037,8 +3101,11 @@
387 #ifdef REISERFS_PREALLOCATE
388 + /* quota ops might need to nest, setup the journal_info pointer for them */
389 + current->journal_info = th ;
390 reiserfs_discard_all_prealloc(th); /* it should not involve new blocks into
392 + current->journal_info = th->t_handle_save ;
395 rs = SB_DISK_SUPER_BLOCK(p_s_sb) ;
396 diff -urN linux-2.4.22/fs/reiserfs/namei.c linux-2.4.22-aclea/fs/reiserfs/namei.c
397 --- linux-2.4.22/fs/reiserfs/namei.c 2003-08-25 13:44:43.000000000 +0200
398 +++ linux-2.4.22-aclea/fs/reiserfs/namei.c 2003-09-12 17:19:36.000000000 +0200
400 #include <linux/sched.h>
401 #include <linux/bitops.h>
402 #include <linux/reiserfs_fs.h>
403 +#include <linux/reiserfs_acl.h>
404 +#include <linux/reiserfs_xattr.h>
405 #include <linux/smp_lock.h>
407 #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
408 @@ -323,10 +325,21 @@
409 retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
410 pathrelse (&path_to_entry);
411 if (retval == NAME_FOUND) {
412 + /* Hide the .reiserfs_priv dir */
413 + if (reiserfs_xattrs (dir->i_sb) &&
414 + !old_format_only(dir->i_sb) &&
415 + dir->i_sb->u.reiserfs_sb.priv_root &&
416 + dir->i_sb->u.reiserfs_sb.priv_root->d_inode &&
417 + de.de_objectid == le32_to_cpu (INODE_PKEY(dir->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid)) {
418 + return ERR_PTR (-EACCES);
420 inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
421 if (!inode || IS_ERR(inode)) {
422 return ERR_PTR(-EACCES);
424 + /* Propogate the priv_object flag so we know we're in the priv tree */
425 + if (is_reiserfs_priv_object (dir))
426 + inode->u.reiserfs_i.i_flags |= i_priv_object;
428 if ( retval == IO_ERROR ) {
429 return ERR_PTR(-EIO);
431 struct inode * inode;
432 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
433 struct reiserfs_transaction_handle th ;
436 if (!(inode = new_inode(dir->i_sb))) {
442 + locked = reiserfs_cache_default_acl (dir);
444 + reiserfs_write_lock_xattrs (dir->i_sb);
446 journal_begin(&th, dir->i_sb, jbegin_count) ;
447 - th.t_caller = "create" ;
448 retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
453 retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
454 inode, 1/*visible*/);
456 + reiserfs_write_unlock_xattrs (dir->i_sb);
460 reiserfs_update_sd (&th, inode);
462 struct inode * inode;
463 struct reiserfs_transaction_handle th ;
464 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
467 if (!(inode = new_inode(dir->i_sb))) {
473 + locked = reiserfs_cache_default_acl (dir);
475 + reiserfs_write_lock_xattrs (inode->i_sb);
477 journal_begin(&th, dir->i_sb, jbegin_count) ;
479 retval = reiserfs_new_inode(&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
482 + reiserfs_write_unlock_xattrs (inode->i_sb);
488 struct inode * inode;
489 struct reiserfs_transaction_handle th ;
490 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
493 mode = S_IFDIR | mode;
494 if (!(inode = new_inode(dir->i_sb))) {
499 + locked = reiserfs_cache_default_acl (dir);
501 + reiserfs_write_lock_xattrs (inode->i_sb);
503 journal_begin(&th, dir->i_sb, jbegin_count) ;
505 /* inc the link count now, so another writer doesn't overflow it while
507 old_format_only (dir->i_sb) ?
508 EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
511 + reiserfs_write_unlock_xattrs (inode->i_sb);
517 memcpy (name, symname, strlen (symname));
518 padd_item (name, item_len, strlen (symname));
520 + /* We would inherit the default ACL here, but symlinks don't get ACLs */
522 journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
524 retval = reiserfs_new_inode(&th, parent_dir, mode, name,
526 reiserfs_update_inode_transaction(inode) ;
527 reiserfs_update_inode_transaction(parent_dir) ;
529 - inode->i_op = &page_symlink_inode_operations;
530 + inode->i_op = &reiserfs_symlink_inode_operations;
531 inode->i_mapping->a_ops = &reiserfs_address_space_operations;
533 // must be sure this inode is written with this transaction
534 @@ -1277,5 +1316,25 @@
535 rmdir: reiserfs_rmdir,
536 mknod: reiserfs_mknod,
537 rename: reiserfs_rename,
538 + setattr: reiserfs_setattr,
539 + setxattr: reiserfs_setxattr,
540 + getxattr: reiserfs_getxattr,
541 + listxattr: reiserfs_listxattr,
542 + removexattr: reiserfs_removexattr,
543 + permission: reiserfs_permission,
547 + * symlink operations.. same as page_symlink_inode_operations, with xattr
550 +struct inode_operations reiserfs_symlink_inode_operations = {
551 + readlink: page_readlink,
552 + follow_link: page_follow_link,
553 + setattr: reiserfs_setattr,
554 + setxattr: reiserfs_setxattr,
555 + getxattr: reiserfs_getxattr,
556 + listxattr: reiserfs_listxattr,
557 + removexattr: reiserfs_removexattr,
558 + permission: reiserfs_permission,
560 diff -urN linux-2.4.22/fs/reiserfs/super.c linux-2.4.22-aclea/fs/reiserfs/super.c
561 --- linux-2.4.22/fs/reiserfs/super.c 2003-08-25 13:44:43.000000000 +0200
562 +++ linux-2.4.22-aclea/fs/reiserfs/super.c 2003-09-12 17:19:43.000000000 +0200
564 #include <linux/vmalloc.h>
565 #include <asm/uaccess.h>
566 #include <linux/reiserfs_fs.h>
567 +#include <linux/reiserfs_fs_sb.h>
568 +#include <linux/reiserfs_acl.h>
569 +#include <linux/reiserfs_xattr.h>
570 #include <linux/smp_lock.h>
571 #include <linux/locks.h>
572 #include <linux/init.h>
576 struct reiserfs_transaction_handle th ;
578 + if (s->u.reiserfs_sb.xattr_root) {
579 + d_invalidate (s->u.reiserfs_sb.xattr_root);
580 + dput (s->u.reiserfs_sb.xattr_root);
583 + if (s->u.reiserfs_sb.priv_root) {
584 + d_invalidate (s->u.reiserfs_sb.priv_root);
585 + dput (s->u.reiserfs_sb.priv_root);
588 /* change file system state to current state if it was mounted with read-write permissions */
589 if (!(s->s_flags & MS_RDONLY)) {
590 journal_begin(&th, s, 10) ;
595 +static void reiserfs_clear_inode (struct inode *inode)
597 + struct posix_acl *acl;
599 + acl = inode->u.reiserfs_i.i_acl_access;
600 + if (acl && !IS_ERR (acl))
601 + posix_acl_release (acl);
602 + inode->u.reiserfs_i.i_acl_access = NULL;
604 + acl = inode->u.reiserfs_i.i_acl_default;
605 + if (acl && !IS_ERR (acl))
606 + posix_acl_release (acl);
607 + inode->u.reiserfs_i.i_acl_default = NULL;
611 struct super_operations reiserfs_sops =
613 read_inode: reiserfs_read_inode,
615 write_inode: reiserfs_write_inode,
616 dirty_inode: reiserfs_dirty_inode,
617 delete_inode: reiserfs_delete_inode,
618 + clear_inode: reiserfs_clear_inode,
619 put_super: reiserfs_put_super,
620 write_super: reiserfs_write_super,
621 write_super_lockfs: reiserfs_write_super_lockfs,
623 {"resize", 'r', 0, 0, 0},
624 {"attrs", 0, 0, 1<<REISERFS_ATTRS, 0},
625 {"noattrs", 0, 0, 0, 1<<REISERFS_ATTRS},
626 +#ifdef CONFIG_REISERFS_FS_XATTR
627 +# ifdef CONFIG_REISERFS_FS_XATTR_USER
628 + {"user_xattr", 0, 0, REISERFS_XATTRS_USER},
629 + {"nouser_xattr", 0, 0, REISERFS_NO_XATTRS_USER},
631 +# ifdef CONFIG_REISERFS_FS_POSIX_ACL
632 + {"acl", 0, 0, REISERFS_POSIXACL},
633 + {"noacl", 0, 0, REISERFS_NO_POSIXACL},
640 safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
641 safe_mask |= 1 << REISERFS_TEST4;
642 safe_mask |= 1 << REISERFS_ATTRS;
643 + safe_mask |= 1 << REISERFS_XATTRS_USER;
644 + safe_mask |= 1 << REISERFS_NO_XATTRS_USER;
645 + safe_mask |= 1 << REISERFS_POSIXACL;
646 + safe_mask |= 1 << REISERFS_NO_POSIXACL;
648 /* Update the bitmask, taking care to keep
649 * the bits we're not allowed to change here */
653 if (*mount_flags & MS_RDONLY) {
654 + reiserfs_xattr_init (s, *mount_flags);
655 /* remount read-only */
656 if (s->s_flags & MS_RDONLY)
657 /* it is read-only already */
661 /* remount read-write */
662 - if (!(s->s_flags & MS_RDONLY))
663 + if (!(s->s_flags & MS_RDONLY)) {
664 + reiserfs_xattr_init (s, *mount_flags);
665 return 0; /* We are read-write already */
668 s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
669 journal_begin(&th, s, 10) ;
671 SB_JOURNAL(s)->j_must_wait = 1 ;
672 journal_end(&th, s, 10) ;
674 - if (!( *mount_flags & MS_RDONLY ) )
675 + if (!( *mount_flags & MS_RDONLY ) ) {
676 finish_unfinished( s );
677 + reiserfs_xattr_init (s, *mount_flags);
682 @@ -1169,6 +1217,8 @@
683 s->u.reiserfs_sb.s_alloc_options.preallocmin = 4;
684 /* Preallocate by 8 blocks (9-1) at once */
685 s->u.reiserfs_sb.s_alloc_options.preallocsize = 9;
686 + /* Initialize the rwsem for xattr dir */
687 + init_rwsem(&s->u.reiserfs_sb.xattr_dir_sem);
689 if (reiserfs_parse_options (s, (char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
691 @@ -1301,11 +1351,23 @@
693 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
694 journal_end(&th, s, 1) ;
697 + if (reiserfs_xattr_init (s, s->s_flags)) {
703 /* look for files which were to be removed in previous session */
704 finish_unfinished (s);
708 + if (reiserfs_xattr_init (s, s->s_flags)) {
715 // mark hash in super block: it could be unset. overwrite should be ok
716 @@ -1364,10 +1426,29 @@
718 static int __init init_reiserfs_fs (void)
721 reiserfs_proc_info_global_init();
722 reiserfs_proc_register_global( "version",
723 reiserfs_global_version_in_proc );
724 - return register_filesystem(&reiserfs_fs_type);
725 + ret = reiserfs_xattr_user_init ();
726 + if (ret) goto failed_xattr_user_init;
728 + ret = reiserfs_xattr_trusted_init();
729 + if (ret) goto failed_xattr_trusted_init;
731 + ret = reiserfs_xattr_posix_acl_init();
732 + if (ret) goto failed_xattr_posix_acl_init;
734 + return register_filesystem(&reiserfs_fs_type);
736 +failed_xattr_posix_acl_init:
737 + reiserfs_xattr_trusted_exit();
738 +failed_xattr_trusted_init:
739 + reiserfs_xattr_user_exit();
740 +failed_xattr_user_init:
741 + reiserfs_proc_unregister_global( "version" );
742 + reiserfs_proc_info_global_done();
746 MODULE_DESCRIPTION("ReiserFS journaled filesystem");
747 @@ -1377,6 +1458,9 @@
749 static void __exit exit_reiserfs_fs(void)
751 + reiserfs_xattr_posix_acl_exit ();
752 + reiserfs_xattr_trusted_exit ();
753 + reiserfs_xattr_user_exit ();
754 reiserfs_proc_unregister_global( "version" );
755 reiserfs_proc_info_global_done();
756 unregister_filesystem(&reiserfs_fs_type);
757 diff -urN linux-2.4.22/fs/reiserfs/xattr.c linux-2.4.22-aclea/fs/reiserfs/xattr.c
758 --- linux-2.4.22/fs/reiserfs/xattr.c 1970-01-01 01:00:00.000000000 +0100
759 +++ linux-2.4.22-aclea/fs/reiserfs/xattr.c 2003-09-12 17:19:37.000000000 +0200
762 + * linux/fs/reiserfs/xattr.c
764 + * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com>
769 + * In order to implement EA/ACLs in a clean, backwards compatible manner,
770 + * they are implemented as files in a "private" directory.
771 + * Each EA is in it's own file, with the directory layout like so (/ is assumed
772 + * to be relative to fs root). Inside the /.reiserfs_priv/xattrs directory,
773 + * directories named using the capital-hex form of the objectid and
774 + * generation number are used. Inside each directory are individual files
775 + * named with the name of the extended attribute.
777 + * So, for objectid 12648430, we could have:
778 + * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_access
779 + * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_default
780 + * /.reiserfs_priv/xattrs/C0FFEE.0/user.Content-Type
783 + * The file contents are the text of the EA. The size is known based on the
784 + * stat data describing the file.
786 + * In the case of system.posix_acl_access and system.posix_acl_default, since
787 + * these are special cases for filesystem ACLs, they are interpreted by the
788 + * kernel, in addition, they are negatively and positively cached and attached
789 + * to the inode so that unnecessary lookups are avoided.
792 +#include <linux/reiserfs_fs.h>
793 +#include <linux/dcache.h>
794 +#include <linux/errno.h>
795 +#include <linux/fs.h>
796 +#include <linux/file.h>
797 +#include <linux/pagemap.h>
798 +#include <linux/xattr.h>
799 +#include <linux/reiserfs_xattr.h>
800 +#include <linux/mbcache.h>
801 +#include <asm/uaccess.h>
802 +#include <asm/checksum.h>
803 +#include <linux/smp_lock.h>
804 +#include <linux/stat.h>
805 +#include <asm/semaphore.h>
807 +#define FL_READONLY 128
808 +#define FL_DIR_SEM_HELD 256
809 +#define PRIVROOT_NAME ".reiserfs_priv"
810 +#define XAROOT_NAME "xattrs"
812 +static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix);
814 +static struct dentry *
815 +create_xa_root (struct super_block *sb)
817 + struct dentry *privroot = dget (sb->u.reiserfs_sb.priv_root);
818 + struct dentry *xaroot;
820 + /* This needs to be created at mount-time */
822 + return ERR_PTR(-EOPNOTSUPP);
824 + xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
825 + if (IS_ERR (xaroot)) {
827 + } else if (!xaroot->d_inode) {
829 + down (&privroot->d_inode->i_sem);
830 + err = privroot->d_inode->i_op->mkdir (privroot->d_inode, xaroot, 0700);
831 + up (&privroot->d_inode->i_sem);
836 + return ERR_PTR (err);
838 + sb->u.reiserfs_sb.xattr_root = dget (xaroot);
846 +/* This will return a dentry, or error, refering to the xa root directory.
847 + * If the xa root doesn't exist yet, the dentry will be returned without
848 + * an associated inode. This dentry can be used with ->mkdir to create
849 + * the xa directory. */
850 +static struct dentry *
851 +__get_xa_root (struct super_block *s)
853 + struct dentry *privroot = dget (s->u.reiserfs_sb.priv_root);
854 + struct dentry *xaroot = NULL;
856 + if (IS_ERR (privroot) || !privroot)
859 + xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
860 + if (IS_ERR (xaroot)) {
862 + } else if (!xaroot->d_inode) {
868 + s->u.reiserfs_sb.xattr_root = dget (xaroot);
875 +/* Returns the dentry (or NULL) referring to the root of the extended
876 + * attribute directory tree. If it has already been retreived, it is used.
877 + * Otherwise, we attempt to retreive it from disk. It may also return
878 + * a pointer-encoded error.
880 +static inline struct dentry *
881 +get_xa_root (struct super_block *s)
883 + struct dentry *dentry = s->u.reiserfs_sb.xattr_root;
886 + dentry = __get_xa_root (s);
892 +/* Same as above, but only returns a valid dentry or NULL */
894 +reiserfs_get_xa_root (struct super_block *sb)
896 + struct dentry *dentry;
898 + dentry = get_xa_root (sb);
899 + if (IS_ERR (dentry)) {
901 + } else if (dentry && !dentry->d_inode) {
909 +/* Opens the directory corresponding to the inode's extended attribute store.
910 + * If flags allow, the tree to the directory may be created. If creation is
911 + * prohibited, -ENODATA is returned. */
912 +static struct dentry *
913 +open_xa_dir (const struct inode *inode, int flags)
915 + struct dentry *xaroot, *xadir;
918 + xaroot = get_xa_root (inode->i_sb);
919 + if (IS_ERR (xaroot)) {
921 + } else if (!xaroot) {
922 + if (flags == 0 || flags & XATTR_CREATE) {
923 + xaroot = create_xa_root (inode->i_sb);
924 + if (IS_ERR (xaroot))
928 + return ERR_PTR (-ENODATA);
931 + /* ok, we have xaroot open */
933 + snprintf (namebuf, sizeof (namebuf), "%X.%X",
934 + le32_to_cpu (INODE_PKEY (inode)->k_objectid),
935 + inode->i_generation);
936 + xadir = lookup_one_len (namebuf, xaroot, strlen (namebuf));
937 + if (IS_ERR (xadir)) {
942 + if (!xadir->d_inode) {
944 + if (flags == 0 || flags & XATTR_CREATE) {
945 + /* Although there is nothing else trying to create this directory,
946 + * another directory with the same hash may be created, so we need
947 + * to protect against that */
948 + err = xaroot->d_inode->i_op->mkdir (xaroot->d_inode, xadir, 0700);
952 + return ERR_PTR (err);
955 + if (!xadir->d_inode) {
958 + return ERR_PTR (-ENODATA);
966 +/* Returns a dentry corresponding to a specific extended attribute file
967 + * for the inode. If flags allow, the file is created. Otherwise, a
968 + * valid or negative dentry, or an error is returned. */
969 +static struct dentry *
970 +get_xa_file_dentry (const struct inode *inode, const char *name, int flags)
972 + struct dentry *xadir, *xafile;
975 + xadir = open_xa_dir (inode, flags);
976 + if (IS_ERR (xadir)) {
977 + return ERR_PTR (PTR_ERR (xadir));
978 + } else if (xadir && !xadir->d_inode) {
980 + return ERR_PTR (-ENODATA);
983 + xafile = lookup_one_len (name, xadir, strlen (name));
984 + if (IS_ERR (xafile)) {
986 + return ERR_PTR (PTR_ERR (xafile));
989 + if (xafile->d_inode) { /* file exists */
990 + if (flags & XATTR_CREATE) {
995 + } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
998 + /* inode->i_sem is down, so nothing else can try to create
999 + * the same xattr */
1000 + err = xadir->d_inode->i_op->create (xadir->d_inode, xafile,
1012 + xafile = ERR_PTR (err);
1017 +/* Opens a file pointer to the attribute associated with inode */
1018 +static struct file *
1019 +open_xa_file (const struct inode *inode, const char *name, int flags)
1021 + struct dentry *xafile;
1024 + xafile = get_xa_file_dentry (inode, name, flags);
1025 + if (IS_ERR (xafile))
1026 + return ERR_PTR (PTR_ERR (xafile));
1027 + else if (!xafile->d_inode) {
1029 + return ERR_PTR (-ENODATA);
1032 + fp = dentry_open (xafile, NULL, O_RDWR);
1033 + /* dentry_open dputs the dentry if it fails */
1040 + * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but
1041 + * we need to drop the path before calling the filldir struct. That
1042 + * would be a big performance hit to the non-xattr case, so I've copied
1043 + * the whole thing for now. --clm
1045 + * the big difference is that I go backwards through the directory,
1046 + * and don't mess with f->f_pos, but the idea is the same. Do some
1047 + * action on each and every entry in the directory.
1049 + * we're called with i_sem held, so there are no worries about the directory
1050 + * changing underneath us.
1052 +static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir)
1054 + struct inode *inode = filp->f_dentry->d_inode;
1055 + struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */
1056 + INITIALIZE_PATH (path_to_entry);
1057 + struct buffer_head * bh;
1059 + struct item_head * ih, tmp_ih;
1063 + char small_buf[32] ; /* avoid kmalloc if we can */
1064 + struct reiserfs_de_head *deh;
1069 + struct reiserfs_dir_entry de;
1072 + /* form key for search the next directory entry using f_pos field of
1074 + next_pos = max_reiserfs_offset(inode);
1078 + if (next_pos <= DOT_DOT_OFFSET)
1080 + make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
1082 + search_res = search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, &de);
1083 + if (search_res == IO_ERROR) {
1084 + // FIXME: we could just skip part of directory which could
1086 + pathrelse(&path_to_entry);
1090 + if (search_res == NAME_NOT_FOUND)
1091 + de.de_entry_num--;
1093 + set_de_name_and_namelen(&de);
1094 + entry_num = de.de_entry_num;
1095 + deh = &(de.de_deh[entry_num]);
1100 + if (!is_direntry_le_ih(ih)) {
1101 +reiserfs_warning(inode->i_sb, "not direntry %h\n", ih);
1104 + copy_item_head(&tmp_ih, ih);
1106 + /* we must have found item, that is item of this directory, */
1107 + RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key),
1108 + "vs-9000: found item %h does not match to dir we readdir %K",
1111 + if (deh_offset(deh) <= DOT_DOT_OFFSET) {
1115 + /* look for the previous entry in the directory */
1116 + next_pos = deh_offset (deh) - 1;
1118 + if (!de_visible (deh))
1119 + /* it is hidden entry */
1122 + d_reclen = entry_length(bh, ih, entry_num);
1123 + d_name = B_I_DEH_ENTRY_FILE_NAME (bh, ih, deh);
1124 + d_off = deh_offset (deh);
1125 + d_ino = deh_objectid (deh);
1127 + if (!d_name[d_reclen - 1])
1128 + d_reclen = strlen (d_name);
1130 + if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
1131 + /* too big to send back to VFS */
1135 + /* Ignore the .reiserfs_priv entry */
1136 + if (reiserfs_xattrs (inode->i_sb) &&
1137 + !old_format_only(inode->i_sb) &&
1138 + deh_objectid (deh) == le32_to_cpu (INODE_PKEY(inode->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid))
1141 + if (d_reclen <= 32) {
1142 + local_buf = small_buf ;
1144 + local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
1146 + pathrelse (&path_to_entry);
1149 + if (item_moved (&tmp_ih, &path_to_entry)) {
1150 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
1152 + /* sigh, must retry. Do this same offset again */
1158 + // Note, that we copy name to user space via temporary
1159 + // buffer (local_buf) because filldir will block if
1160 + // user space buffer is swapped out. At that time
1161 + // entry can move to somewhere else
1162 + memcpy (local_buf, d_name, d_reclen);
1164 + /* the filldir function might need to start transactions,
1165 + * or do who knows what. Release the path now that we've
1166 + * copied all the important stuff out of the deh
1168 + pathrelse (&path_to_entry);
1170 + if (filldir (dirent, local_buf, d_reclen, d_off, d_ino,
1171 + DT_UNKNOWN) < 0) {
1172 + if (local_buf != small_buf) {
1173 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
1177 + if (local_buf != small_buf) {
1178 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
1183 + pathrelse (&path_to_entry);
1188 + * this could be done with dedicated readdir ops for the xattr files,
1189 + * but I want to get something working asap
1190 + * this is stolen from vfs_readdir
1194 +int xattr_readdir(struct file *file, filldir_t filler, void *buf)
1196 + struct inode *inode = file->f_dentry->d_inode;
1197 + int res = -ENOTDIR;
1198 + if (!file->f_op || !file->f_op->readdir)
1200 + down(&inode->i_sem);
1201 + down(&inode->i_zombie);
1203 + if (!IS_DEADDIR(inode)) {
1205 + res = __xattr_readdir(file, buf, filler);
1208 + up(&inode->i_zombie);
1209 + up(&inode->i_sem);
1215 +/* Internal operations on file data */
1217 +reiserfs_put_page(struct page *page)
1220 + page_cache_release(page);
1223 +static struct page *
1224 +reiserfs_get_page(struct inode *dir, unsigned long n)
1226 + struct address_space *mapping = dir->i_mapping;
1227 + struct page *page;
1228 + /* We can deadlock if we try to free dentries,
1229 + and an unlink/rmdir has just occured - GFP_NOFS avoids this */
1230 + mapping->gfp_mask = GFP_NOFS;
1231 + page = read_cache_page (mapping, n,
1232 + (filler_t*)mapping->a_ops->readpage, NULL);
1233 + if (!IS_ERR(page)) {
1234 + wait_on_page(page);
1236 + if (!Page_Uptodate(page))
1239 + if (PageError(page))
1245 + reiserfs_put_page(page);
1246 + return ERR_PTR(-EIO);
1249 +static inline __u32
1250 +xattr_hash (const char *msg, int len)
1252 + return csum_partial (msg, len, 0);
1255 +/* Generic extended attribute operations that can be used by xa plugins */
1258 + * inode->i_sem: down
1261 +reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer,
1262 + size_t buffer_size, int flags)
1266 + struct page *page;
1268 + struct address_space *mapping;
1269 + size_t file_pos = 0;
1270 + size_t buffer_pos = 0;
1271 + struct inode *xinode;
1272 + struct iattr newattrs;
1275 + if (get_inode_sd_version (inode) == STAT_DATA_V1)
1276 + return -EOPNOTSUPP;
1278 + /* Empty xattrs are ok, they're just empty files, no hash */
1279 + if (buffer && buffer_size)
1280 + xahash = xattr_hash (buffer, buffer_size);
1283 + fp = open_xa_file (inode, name, flags);
1284 + if (IS_ERR (fp)) {
1285 + err = PTR_ERR (fp);
1289 + xinode = fp->f_dentry->d_inode;
1291 + /* we need to copy it off.. */
1292 + if (xinode->i_nlink > 1) {
1294 + err = reiserfs_xattr_del (inode, name);
1297 + /* We just killed the old one, we're not replacing anymore */
1298 + if (flags & XATTR_REPLACE)
1299 + flags &= ~XATTR_REPLACE;
1303 + /* Resize it so we're ok to write there */
1304 + newattrs.ia_size = buffer_size;
1305 + newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
1306 + down (&xinode->i_sem);
1307 + err = notify_change(fp->f_dentry, &newattrs);
1311 + mapping = xinode->i_mapping;
1312 + while (buffer_pos < buffer_size || buffer_pos == 0) {
1315 + size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1));
1316 + if (buffer_size - buffer_pos > PAGE_CACHE_SIZE)
1317 + chunk = PAGE_CACHE_SIZE;
1319 + chunk = buffer_size - buffer_pos;
1321 + page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
1322 + if (IS_ERR (page)) {
1323 + err = PTR_ERR (page);
1328 + data = page_address (page);
1330 + if (file_pos == 0) {
1331 + struct reiserfs_xattr_header *rxh;
1332 + skip = file_pos = sizeof (struct reiserfs_xattr_header);
1333 + if (chunk + skip > PAGE_CACHE_SIZE)
1334 + chunk = PAGE_CACHE_SIZE - skip;
1335 + rxh = (struct reiserfs_xattr_header *)data;
1336 + rxh->h_magic = cpu_to_le32 (REISERFS_XATTR_MAGIC);
1337 + rxh->h_hash = cpu_to_le32 (xahash);
1340 + err = mapping->a_ops->prepare_write (fp, page, page_offset,
1341 + page_offset + chunk + skip);
1344 + memcpy (data + skip, buffer + buffer_pos, chunk);
1345 + err = mapping->a_ops->commit_write (fp, page, page_offset,
1346 + page_offset + chunk + skip);
1348 + UnlockPage (page);
1349 + reiserfs_put_page (page);
1350 + buffer_pos += chunk;
1351 + file_pos += chunk;
1353 + if (err || buffer_size == 0 || !buffer)
1358 + up (&xinode->i_sem);
1366 + * inode->i_sem: down
1369 +reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer,
1370 + size_t buffer_size)
1375 + size_t file_pos = 0;
1376 + size_t buffer_pos = 0;
1377 + struct page *page;
1378 + struct inode *xinode;
1381 + /* We can't have xattrs attached to v1 items since they don't have
1382 + * generation numbers */
1383 + if (get_inode_sd_version (inode) == STAT_DATA_V1)
1384 + return -EOPNOTSUPP;
1386 + fp = open_xa_file (inode, name, FL_READONLY);
1387 + if (IS_ERR (fp)) {
1388 + err = PTR_ERR (fp);
1392 + xinode = fp->f_dentry->d_inode;
1393 + isize = xinode->i_size;
1395 + /* Just return the size needed */
1396 + if (buffer == NULL) {
1397 + err = isize - sizeof (struct reiserfs_xattr_header);
1401 + if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) {
1406 + while (file_pos < isize) {
1410 + if (isize - file_pos > PAGE_CACHE_SIZE)
1411 + chunk = PAGE_CACHE_SIZE;
1413 + chunk = isize - file_pos;
1415 + page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
1416 + if (IS_ERR (page)) {
1417 + err = PTR_ERR (page);
1422 + data = page_address (page);
1423 + if (file_pos == 0) {
1424 + struct reiserfs_xattr_header *rxh =
1425 + (struct reiserfs_xattr_header *)data;
1426 + skip = file_pos = sizeof (struct reiserfs_xattr_header);
1428 + /* Magic doesn't match up.. */
1429 + if (rxh->h_magic != cpu_to_le32 (REISERFS_XATTR_MAGIC)) {
1430 + UnlockPage (page);
1431 + reiserfs_put_page (page);
1435 + hash = le32_to_cpu (rxh->h_hash);
1437 + memcpy (buffer + buffer_pos, data + skip, chunk);
1438 + UnlockPage (page);
1439 + reiserfs_put_page (page);
1440 + file_pos += chunk;
1441 + buffer_pos += chunk;
1444 + err = isize - sizeof (struct reiserfs_xattr_header);
1446 + if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash)
1457 +__reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen)
1459 + struct dentry *file;
1460 + struct inode *dir = xadir->d_inode;
1463 + file = lookup_one_len (name, xadir, namelen);
1464 + if (IS_ERR (file)) {
1465 + err = PTR_ERR (file);
1467 + } else if (!file->d_inode) {
1472 + /* Skip directories.. */
1473 + if (S_ISDIR (file->d_inode->i_mode))
1476 + if (!is_reiserfs_priv_object (file->d_inode)) {
1477 + reiserfs_warning (file->d_inode->i_sb, "trying to delete objectid %08x, which isn't an xattr!\n", le32_to_cpu (INODE_PKEY (file->d_inode)->k_objectid));
1482 + err = dir->i_op->unlink (dir, file);
1495 +reiserfs_xattr_del (struct inode *inode, const char *name)
1497 + struct dentry *dir;
1500 + dir = open_xa_dir (inode, FL_READONLY);
1501 + if (IS_ERR (dir)) {
1502 + err = PTR_ERR (dir);
1506 + err = __reiserfs_xattr_del (dir, name, strlen (name));
1513 +/* The following are side effects of other operations that aren't explicitly
1514 + * modifying extended attributes. This includes operations such as permissions
1515 + * or ownership changes, object deletions, etc. */
1518 +reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen,
1519 + loff_t offset, ino_t ino, unsigned int d_type)
1521 + struct dentry *xadir = (struct dentry *)buf;
1523 + return __reiserfs_xattr_del (xadir, name, namelen);
1528 +reiserfs_delete_xattrs (struct inode *inode)
1531 + struct dentry *dir, *root;
1534 + /* Skip out, an xattr has no xattrs associated with it */
1535 + if (is_reiserfs_priv_object (inode) ||
1536 + get_inode_sd_version (inode) == STAT_DATA_V1 ||
1537 + !reiserfs_xattrs(inode->i_sb))
1541 + reiserfs_read_lock_xattrs (inode->i_sb);
1542 + dir = open_xa_dir (inode, FL_READONLY);
1543 + reiserfs_read_unlock_xattrs (inode->i_sb);
1544 + if (IS_ERR (dir)) {
1545 + err = PTR_ERR (dir);
1547 + } else if (!dir->d_inode) {
1552 + fp = dentry_open (dir, NULL, O_RDWR);
1553 + if (IS_ERR (fp)) {
1554 + err = PTR_ERR (fp);
1555 + /* dentry_open dputs the dentry if it fails */
1560 + err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir);
1566 + /* Leftovers besides . and .. -- that's not good. */
1567 + if (dir->d_inode->i_nlink <= 2) {
1568 + root = get_xa_root (inode->i_sb);
1569 + reiserfs_write_lock_xattrs (inode->i_sb);
1570 + err = vfs_rmdir (root->d_inode, dir);
1571 + reiserfs_write_unlock_xattrs (inode->i_sb);
1574 + reiserfs_warning (inode->i_sb, "Couldn't remove all entries in directory\n");
1585 +struct reiserfs_chown_buf {
1586 + struct inode *inode;
1587 + struct dentry *xadir;
1588 + struct iattr *attrs;
1591 +/* XXX: If there is a better way to do this, I'd love to hear about it */
1593 +reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen,
1594 + loff_t offset, ino_t ino, unsigned int d_type)
1596 + struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
1597 + struct dentry *xafile, *xadir = chown_buf->xadir;
1598 + struct iattr *attrs = chown_buf->attrs;
1601 + xafile = lookup_one_len (name, xadir, namelen);
1602 + if (IS_ERR (xafile))
1603 + return PTR_ERR (xafile);
1604 + else if (!xafile->d_inode) {
1609 + if (!S_ISDIR (xafile->d_inode->i_mode))
1610 + err = notify_change (xafile, attrs);
1617 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
1620 + struct dentry *dir;
1622 + struct reiserfs_chown_buf buf;
1623 + unsigned int ia_valid = attrs->ia_valid;
1625 + /* Skip out, an xattr has no xattrs associated with it */
1626 + if (is_reiserfs_priv_object (inode) ||
1627 + get_inode_sd_version (inode) == STAT_DATA_V1 ||
1628 + !reiserfs_xattrs(inode->i_sb))
1632 + reiserfs_read_lock_xattrs (inode->i_sb);
1633 + dir = open_xa_dir (inode, FL_READONLY);
1634 + reiserfs_read_unlock_xattrs (inode->i_sb);
1635 + if (IS_ERR (dir)) {
1636 + if (PTR_ERR (dir) != -ENODATA)
1637 + err = PTR_ERR (dir);
1639 + } else if (!dir->d_inode) {
1644 + fp = dentry_open (dir, NULL, O_RDWR);
1645 + if (IS_ERR (fp)) {
1646 + err = PTR_ERR (fp);
1647 + /* dentry_open dputs the dentry if it fails */
1653 + attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
1655 + buf.attrs = attrs;
1656 + buf.inode = inode;
1658 + err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf);
1664 + err = notify_change (dir, attrs);
1671 + attrs->ia_valid = ia_valid;
1676 +/* Actual operations that are exported to VFS-land */
1679 + * Inode operation getxattr()
1680 + * dentry->d_inode->i_sem down
1681 + * BKL held [before 2.5.x]
1684 +reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer,
1687 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1690 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1691 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1692 + return -EOPNOTSUPP;
1694 + reiserfs_read_lock_xattrs (dentry->d_sb);
1695 + err = xah->get (dentry->d_inode, name, buffer, size);
1696 + reiserfs_read_unlock_xattrs (dentry->d_sb);
1702 + * Inode operation setxattr()
1704 + * dentry->d_inode->i_sem down
1705 + * BKL held [before 2.5.x]
1708 +reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value,
1709 + size_t size, int flags)
1711 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1714 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1715 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1716 + return -EOPNOTSUPP;
1719 + reiserfs_write_lock_xattrs (dentry->d_sb);
1720 + err = xah->set (dentry->d_inode, name, value, size, flags);
1721 + reiserfs_write_unlock_xattrs (dentry->d_sb);
1726 + * Inode operation removexattr()
1728 + * dentry->d_inode->i_sem down
1729 + * BKL held [before 2.5.x]
1732 +reiserfs_removexattr (struct dentry *dentry, const char *name)
1735 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1737 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1738 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1739 + return -EOPNOTSUPP;
1741 + down (&dentry->d_inode->i_zombie);
1742 + reiserfs_read_lock_xattrs (dentry->d_sb);
1744 + /* Deletion pre-operation */
1746 + err = xah->del (dentry->d_inode, name);
1748 + reiserfs_read_unlock_xattrs (dentry->d_sb);
1749 + up (&dentry->d_inode->i_zombie);
1754 + err = reiserfs_xattr_del (dentry->d_inode, name);
1755 + reiserfs_read_unlock_xattrs (dentry->d_sb);
1756 + up (&dentry->d_inode->i_zombie);
1761 +/* This is what filldir will use:
1762 + * r_pos will always contain the amount of space required for the entire
1763 + * list. If r_pos becomes larger than r_size, we need more space and we
1764 + * return an error indicating this. If r_pos is less than r_size, then we've
1765 + * filled the buffer successfully and we return success */
1766 +struct reiserfs_listxattr_buf {
1770 + struct inode *r_inode;
1774 +reiserfs_listxattr_filler (void *buf, const char *name, int namelen,
1775 + loff_t offset, ino_t ino, unsigned int d_type)
1777 + struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
1779 + if (name[0] != '.' || (namelen != 1 && (name[1] != '.' || namelen != 2))) {
1780 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1781 + if (!xah) return 0; /* Unsupported xattr name, skip it */
1783 + /* We call ->list() twice because the operation isn't required to just
1784 + * return the name back - we want to make sure we have enough space */
1785 + len += xah->list (b->r_inode, name, namelen, NULL);
1788 + if (b->r_pos + len + 1 <= b->r_size) {
1789 + char *p = b->r_buf + b->r_pos;
1790 + p += xah->list (b->r_inode, name, namelen, p);
1793 + b->r_pos += len + 1;
1800 + * Inode operation listxattr()
1802 + * dentry->d_inode->i_sem down
1803 + * BKL held [before 2.5.x]
1806 +reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
1809 + struct dentry *dir;
1811 + struct reiserfs_listxattr_buf buf;
1813 + if (!dentry->d_inode)
1816 + if (!reiserfs_xattrs(dentry->d_sb) ||
1817 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1818 + return -EOPNOTSUPP;
1820 + reiserfs_read_lock_xattrs (dentry->d_sb);
1821 + dir = open_xa_dir (dentry->d_inode, FL_READONLY);
1822 + reiserfs_read_unlock_xattrs (dentry->d_sb);
1823 + if (IS_ERR (dir)) {
1824 + err = PTR_ERR (dir);
1825 + if (err == -ENODATA)
1826 + err = 0; /* Not an error if there aren't any xattrs */
1830 + fp = dentry_open (dir, NULL, O_RDWR);
1831 + if (IS_ERR (fp)) {
1832 + err = PTR_ERR (fp);
1833 + /* dentry_open dputs the dentry if it fails */
1837 + buf.r_buf = buffer;
1838 + buf.r_size = buffer ? size : 0;
1840 + buf.r_inode = dentry->d_inode;
1842 + err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf);
1846 + if (buf.r_pos > buf.r_size && buffer != NULL)
1858 +/* This is the implementation for the xattr plugin infrastructure */
1859 +static struct reiserfs_xattr_handler *xattr_handlers;
1860 +static rwlock_t handler_lock = RW_LOCK_UNLOCKED;
1862 +static struct reiserfs_xattr_handler *
1863 +find_xattr_handler_prefix (const char *prefix)
1865 + struct reiserfs_xattr_handler **xah;
1866 + read_lock (&handler_lock);
1867 + for (xah = &xattr_handlers; *xah; xah=&(*xah)->next)
1868 + if (strncmp ((*xah)->prefix, prefix, strlen ((*xah)->prefix)) == 0)
1870 + read_unlock (&handler_lock);
1875 +reiserfs_xattr_register_handler (struct reiserfs_xattr_handler *handler)
1878 + struct reiserfs_xattr_handler **xah;
1883 + if (handler->next)
1886 + write_lock (&handler_lock);
1888 + for (xah = &xattr_handlers; *xah; xah=&(*xah)->next) {
1889 + if (strcmp ((*xah)->prefix, handler->prefix) == 0)
1899 + printk ("ReiserFS: Registered xattr handler for %s\n", handler->prefix);
1902 + write_unlock (&handler_lock);
1907 +reiserfs_xattr_unregister_handler (struct reiserfs_xattr_handler *handler)
1909 + struct reiserfs_xattr_handler **xah;
1910 + write_lock (&handler_lock);
1912 + xah = &xattr_handlers;
1914 + if (handler == *xah) {
1915 + *xah = handler->next;
1916 + handler->next = NULL;
1917 + write_unlock (&handler_lock);
1919 + printk ("ReiserFS: Unregistered xattr handler for %s\n",
1924 + xah = &(*xah)->next;
1926 + write_unlock (&handler_lock);
1930 +/* We need to take a copy of the mount flags since things like
1931 + * MS_RDONLY don't get set until *after* we're called.
1932 + * mount_flags != mount_options */
1935 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
1939 + /* I hate using the _NO_ variant to clear bits. We use the normal variant
1940 + * everywhere else, so just clear them both here */
1941 + if (test_bit (REISERFS_NO_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt))) {
1942 + clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
1943 + clear_bit (REISERFS_NO_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
1946 + if (test_bit (REISERFS_NO_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt))) {
1947 + clear_bit (REISERFS_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
1948 + clear_bit (REISERFS_NO_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
1951 + /* If the user has requested an optional xattrs type (e.g. user/acl), then
1952 + * enable xattrs. If we're a v3.5 filesystem, this will get caught and
1953 + * error out. If no optional xattrs are enabled, disable xattrs */
1954 + if (reiserfs_xattrs_optional (s))
1955 + set_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
1957 + clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
1959 + if (reiserfs_xattrs (s)) {
1960 + /* We need generation numbers to ensure that the oid mapping is correct
1961 + * v3.5 filesystems don't have them. */
1962 + if (old_format_only (s)) {
1963 + reiserfs_warning (s, "reiserfs: xattrs/ACLs not supported on pre v3.6 "
1964 + "format filesystem. Failing mount.\n");
1965 + err = -EOPNOTSUPP;
1967 + } else if (!s->u.reiserfs_sb.priv_root) {
1968 + struct dentry *dentry;
1969 + dentry = lookup_one_len (PRIVROOT_NAME, s->s_root,
1970 + strlen (PRIVROOT_NAME));
1971 + if (!IS_ERR (dentry)) {
1972 + if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
1973 + struct inode *inode = dentry->d_parent->d_inode;
1974 + down (&inode->i_sem);
1975 + err = inode->i_op->mkdir (inode, dentry, 0700);
1976 + up (&inode->i_sem);
1982 + if (dentry && dentry->d_inode)
1983 + reiserfs_warning (s, "reiserfs: Created %s on %s - reserved for "
1984 + "xattr storage.\n", PRIVROOT_NAME,
1985 + bdevname (inode->i_sb->s_dev));
1988 + err = PTR_ERR (dentry);
1992 + dentry->d_inode->u.reiserfs_i.i_flags |= i_priv_object;
1993 + s->u.reiserfs_sb.priv_root = dentry;
1994 + } else { /* xattrs are unavailable */
1995 + /* If we're read-only it just means that the dir hasn't been
1996 + * created. Not an error -- just no xattrs on the fs. We'll
1997 + * check again if we go read-write */
1998 + if (!(mount_flags & MS_RDONLY)) {
1999 + reiserfs_warning (s, "reiserfs: xattrs/ACLs enabled and couldn't "
2000 + "find/create .reiserfs_priv. Failing mount.\n");
2001 + err = -EOPNOTSUPP;
2004 + /* Just to speed things up a bit since it won't find anything and
2005 + * we're read-only */
2006 + clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
2007 + clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
2008 + clear_bit (REISERFS_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
2014 + /* This is only nonzero if there was an error initializing the xattr
2015 + * directory or if there is a condition where we don't support them. */
2018 + clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
2019 + clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
2020 + clear_bit (REISERFS_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
2023 + s->s_flags = (s->s_flags & ~MS_POSIXACL) |
2024 + (reiserfs_posixacl (s) ? MS_POSIXACL : 0);
2027 diff -urN linux-2.4.22/fs/reiserfs/xattr_acl.c linux-2.4.22-aclea/fs/reiserfs/xattr_acl.c
2028 --- linux-2.4.22/fs/reiserfs/xattr_acl.c 1970-01-01 01:00:00.000000000 +0100
2029 +++ linux-2.4.22-aclea/fs/reiserfs/xattr_acl.c 2003-09-12 17:19:37.000000000 +0200
2031 +#include <linux/posix_acl.h>
2032 +#include <linux/reiserfs_fs.h>
2033 +#include <linux/errno.h>
2034 +#include <linux/fs.h>
2035 +#include <linux/pagemap.h>
2036 +#include <linux/xattr.h>
2037 +#include <linux/xattr_acl.h>
2038 +#include <linux/reiserfs_xattr.h>
2039 +#include <linux/reiserfs_acl.h>
2040 +#include <asm/uaccess.h>
2043 +xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
2045 + struct posix_acl *acl;
2048 + if (!reiserfs_posixacl(inode->i_sb))
2049 + return -EOPNOTSUPP;
2050 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
2054 + acl = posix_acl_from_xattr(value, size);
2055 + if (IS_ERR(acl)) {
2056 + return PTR_ERR(acl);
2058 + error = posix_acl_valid(acl);
2060 + goto release_and_out;
2065 + error = reiserfs_set_acl (inode, type, acl);
2068 + posix_acl_release(acl);
2074 +xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
2076 + struct posix_acl *acl;
2079 + if (!reiserfs_posixacl(inode->i_sb))
2080 + return -EOPNOTSUPP;
2082 + acl = reiserfs_get_acl (inode, type);
2084 + return PTR_ERR(acl);
2087 + error = posix_acl_to_xattr(acl, buffer, size);
2088 + posix_acl_release(acl);
2095 + * Convert from filesystem to in-memory representation.
2097 +static struct posix_acl *
2098 +posix_acl_from_disk(const void *value, size_t size)
2100 + const char *end = (char *)value + size;
2102 + struct posix_acl *acl;
2106 + if (size < sizeof(reiserfs_acl_header))
2107 + return ERR_PTR(-EINVAL);
2108 + if (((reiserfs_acl_header *)value)->a_version !=
2109 + cpu_to_le32(REISERFS_ACL_VERSION))
2110 + return ERR_PTR(-EINVAL);
2111 + value = (char *)value + sizeof(reiserfs_acl_header);
2112 + count = reiserfs_acl_count(size);
2114 + return ERR_PTR(-EINVAL);
2117 + acl = posix_acl_alloc(count, GFP_NOFS);
2119 + return ERR_PTR(-ENOMEM);
2120 + for (n=0; n < count; n++) {
2121 + reiserfs_acl_entry *entry =
2122 + (reiserfs_acl_entry *)value;
2123 + if ((char *)value + sizeof(reiserfs_acl_entry_short) > end)
2125 + acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag);
2126 + acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
2127 + switch(acl->a_entries[n].e_tag) {
2128 + case ACL_USER_OBJ:
2129 + case ACL_GROUP_OBJ:
2132 + value = (char *)value +
2133 + sizeof(reiserfs_acl_entry_short);
2134 + acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
2139 + value = (char *)value + sizeof(reiserfs_acl_entry);
2140 + if ((char *)value > end)
2142 + acl->a_entries[n].e_id =
2143 + le32_to_cpu(entry->e_id);
2155 + posix_acl_release(acl);
2156 + return ERR_PTR(-EINVAL);
2160 + * Convert from in-memory to filesystem representation.
2163 +posix_acl_to_disk(const struct posix_acl *acl, size_t *size)
2165 + reiserfs_acl_header *ext_acl;
2169 + *size = reiserfs_acl_size(acl->a_count);
2170 + ext_acl = (reiserfs_acl_header *)kmalloc(sizeof(reiserfs_acl_header) +
2171 + acl->a_count * sizeof(reiserfs_acl_entry), GFP_NOFS);
2173 + return ERR_PTR(-ENOMEM);
2174 + ext_acl->a_version = cpu_to_le32(REISERFS_ACL_VERSION);
2175 + e = (char *)ext_acl + sizeof(reiserfs_acl_header);
2176 + for (n=0; n < acl->a_count; n++) {
2177 + reiserfs_acl_entry *entry = (reiserfs_acl_entry *)e;
2178 + entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag);
2179 + entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
2180 + switch(acl->a_entries[n].e_tag) {
2184 + cpu_to_le32(acl->a_entries[n].e_id);
2185 + e += sizeof(reiserfs_acl_entry);
2188 + case ACL_USER_OBJ:
2189 + case ACL_GROUP_OBJ:
2192 + e += sizeof(reiserfs_acl_entry_short);
2199 + return (char *)ext_acl;
2203 + return ERR_PTR(-EINVAL);
2207 + * Inode operation get_posix_acl().
2209 + * inode->i_sem: down
2210 + * BKL held [before 2.5.x]
2213 +reiserfs_get_acl(struct inode *inode, int type)
2215 + char *name, *value;
2216 + struct posix_acl *acl, **p_acl;
2221 + case ACL_TYPE_ACCESS:
2222 + name = XATTR_NAME_ACL_ACCESS;
2223 + p_acl = &inode->u.reiserfs_i.i_acl_access;
2225 + case ACL_TYPE_DEFAULT:
2226 + name = XATTR_NAME_ACL_DEFAULT;
2227 + p_acl = &inode->u.reiserfs_i.i_acl_default;
2230 + return ERR_PTR (-EINVAL);
2233 + if (IS_ERR (*p_acl)) {
2234 + if (PTR_ERR (*p_acl) == -ENODATA)
2236 + } else if (*p_acl != NULL)
2237 + return posix_acl_dup (*p_acl);
2239 + size = reiserfs_xattr_get (inode, name, NULL, 0);
2240 + if ((int)size < 0) {
2241 + if (size == -ENODATA || size == -ENOSYS) {
2242 + *p_acl = ERR_PTR (-ENODATA);
2245 + return ERR_PTR (size);
2248 + value = kmalloc (size, GFP_NOFS);
2250 + return ERR_PTR (-ENOMEM);
2252 + retval = reiserfs_xattr_get(inode, name, value, size);
2253 + if (retval == -ENODATA || retval == -ENOSYS) {
2254 + /* This shouldn't actually happen as it should have
2255 + been caught above.. but just in case */
2257 + *p_acl = ERR_PTR (-ENODATA);
2258 + } else if (retval < 0) {
2259 + acl = ERR_PTR(retval);
2261 + acl = posix_acl_from_disk(value, retval);
2262 + *p_acl = posix_acl_dup (acl);
2270 + * Inode operation set_posix_acl().
2272 + * inode->i_sem: down
2273 + * BKL held [before 2.5.x]
2276 +reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
2279 + void *value = NULL;
2280 + struct posix_acl **p_acl;
2284 + if (S_ISLNK(inode->i_mode))
2285 + return -EOPNOTSUPP;
2289 + case ACL_TYPE_ACCESS:
2290 + name = XATTR_NAME_ACL_ACCESS;
2291 + p_acl = &inode->u.reiserfs_i.i_acl_access;
2293 + mode_t mode = inode->i_mode;
2294 + error = posix_acl_equiv_mode (acl, &mode);
2298 + inode->i_mode = mode;
2304 + case ACL_TYPE_DEFAULT:
2305 + name = XATTR_NAME_ACL_DEFAULT;
2306 + p_acl = &inode->u.reiserfs_i.i_acl_default;
2307 + if (!S_ISDIR (inode->i_mode))
2308 + return acl ? -EACCES : 0;
2315 + value = posix_acl_to_disk(acl, &size);
2316 + if (IS_ERR(value))
2317 + return (int)PTR_ERR(value);
2318 + error = reiserfs_xattr_set(inode, name, value, size, 0);
2320 + error = reiserfs_xattr_del (inode, name);
2321 + if (error == -ENODATA)
2329 + /* Release the old one */
2330 + if (!IS_ERR (*p_acl) && *p_acl)
2331 + posix_acl_release (*p_acl);
2334 + *p_acl = ERR_PTR (-ENODATA);
2336 + *p_acl = posix_acl_dup (acl);
2342 +/* dir->i_sem: down,
2343 + * inode is new and not released into the wild yet */
2345 +reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode)
2347 + struct posix_acl *acl;
2350 + /* ACLs only get applied to files and directories */
2351 + if (S_ISLNK (inode->i_mode))
2354 + /* ACLs can only be used on "new" objects, so if it's an old object
2355 + * there is nothing to inherit from */
2356 + if (get_inode_sd_version (dir) == STAT_DATA_V1)
2359 + /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
2360 + * would be useless since permissions are ignored, and a pain because
2361 + * it introduces locking cycles */
2362 + if (is_reiserfs_priv_object (dir)) {
2363 + inode->u.reiserfs_i.i_flags |= i_priv_object;
2367 + acl = reiserfs_get_acl (dir, ACL_TYPE_DEFAULT);
2368 + if (IS_ERR (acl)) {
2369 + if (PTR_ERR (acl) == -ENODATA)
2371 + return PTR_ERR (acl);
2375 + struct posix_acl *acl_copy;
2376 + mode_t mode = inode->i_mode;
2379 + /* Copy the default ACL to the default ACL of a new directory */
2380 + if (S_ISDIR (inode->i_mode)) {
2381 + err = reiserfs_set_acl (inode, ACL_TYPE_DEFAULT, acl);
2386 + /* Now we reconcile the new ACL and the mode,
2387 + potentially modifying both */
2388 + acl_copy = posix_acl_clone (acl, GFP_NOFS);
2395 + need_acl = posix_acl_create_masq (acl_copy, &mode);
2396 + if (need_acl >= 0) {
2397 + if (mode != inode->i_mode) {
2398 + inode->i_mode = mode;
2401 + /* If we need an ACL.. */
2402 + if (need_acl > 0) {
2403 + err = reiserfs_set_acl (inode, ACL_TYPE_ACCESS, acl_copy);
2405 + goto cleanup_copy;
2409 + posix_acl_release (acl_copy);
2411 + posix_acl_release (acl);
2414 + /* no ACL, apply umask */
2415 + inode->i_mode &= ~current->fs->umask;
2421 +/* Looks up and caches the result of the default ACL.
2422 + * We do this so that we don't need to carry the xattr_sem into
2423 + * reiserfs_new_inode if we don't need to */
2425 +reiserfs_cache_default_acl (struct inode *inode)
2428 + if (reiserfs_posixacl (inode->i_sb) &&
2429 + !is_reiserfs_priv_object (inode)) {
2430 + struct posix_acl *acl;
2431 + reiserfs_read_lock_xattrs (inode->i_sb);
2432 + acl = reiserfs_get_acl (inode, ACL_TYPE_DEFAULT);
2433 + reiserfs_read_unlock_xattrs (inode->i_sb);
2434 + ret = acl ? 1 : 0;
2435 + posix_acl_release (acl);
2442 +__reiserfs_permission (struct inode *inode, int mask, int need_lock)
2444 + int mode = inode->i_mode;
2446 + /* Nobody gets write access to a read-only fs */
2447 + if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
2448 + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
2451 + /* Nobody gets write access to an immutable file */
2452 + if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
2455 + /* We don't do permission checks on the internal objects.
2456 + * Permissions are determined by the "owning" object. */
2457 + if (is_reiserfs_priv_object (inode))
2460 + if (current->fsuid == inode->i_uid) {
2462 + } else if (reiserfs_posixacl(inode->i_sb) &&
2463 + get_inode_sd_version (inode) != STAT_DATA_V1) {
2464 + struct posix_acl *acl;
2466 + /* ACL can't contain additional permissions if
2467 + the ACL_MASK entry is 0 */
2468 + if (!(mode & S_IRWXG))
2469 + goto check_groups;
2472 + reiserfs_read_lock_xattrs (inode->i_sb);
2473 + acl = reiserfs_get_acl (inode, ACL_TYPE_ACCESS);
2475 + reiserfs_read_unlock_xattrs (inode->i_sb);
2476 + if (IS_ERR (acl)) {
2477 + if (PTR_ERR (acl) == -ENODATA)
2478 + goto check_groups;
2479 + return PTR_ERR (acl);
2483 + int err = posix_acl_permission (inode, acl, mask);
2484 + posix_acl_release (acl);
2485 + if (err == -EACCES) {
2486 + goto check_capabilities;
2490 + goto check_groups;
2495 + if (in_group_p(inode->i_gid))
2498 + if ((mode & mask & S_IRWXO) == mask)
2501 +check_capabilities:
2502 + /* Allowed to override Discretionary Access Control? */
2503 + if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
2504 + if (capable(CAP_DAC_OVERRIDE))
2506 + /* Read and search granted if capable(CAP_DAC_READ_SEARCH) */
2507 + if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) ||
2508 + (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))))
2514 +reiserfs_permission (struct inode *inode, int mask)
2516 + return __reiserfs_permission (inode, mask, 1);
2520 +reiserfs_permission_locked (struct inode *inode, int mask)
2522 + return __reiserfs_permission (inode, mask, 0);
2526 +reiserfs_acl_chmod (struct inode *inode)
2528 + struct posix_acl *acl, *clone;
2531 + if (S_ISLNK(inode->i_mode))
2532 + return -EOPNOTSUPP;
2534 + if (get_inode_sd_version (inode) == STAT_DATA_V1 ||
2535 + !reiserfs_posixacl(inode->i_sb))
2540 + reiserfs_read_lock_xattrs (inode->i_sb);
2541 + acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
2542 + reiserfs_read_unlock_xattrs (inode->i_sb);
2546 + return PTR_ERR(acl);
2547 + clone = posix_acl_clone(acl, GFP_NOFS);
2548 + posix_acl_release(acl);
2551 + error = posix_acl_chmod_masq(clone, inode->i_mode);
2553 + reiserfs_write_lock_xattrs (inode->i_sb);
2554 + error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
2555 + reiserfs_write_unlock_xattrs (inode->i_sb);
2557 + posix_acl_release(clone);
2562 +posix_acl_access_get(struct inode *inode, const char *name,
2563 + void *buffer, size_t size)
2565 + if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
2567 + return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
2571 +posix_acl_access_set(struct inode *inode, const char *name,
2572 + const void *value, size_t size, int flags)
2574 + if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
2576 + return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
2580 +posix_acl_access_del (struct inode *inode, const char *name)
2582 + struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_access;
2583 + if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
2585 + if (!IS_ERR (*acl) && *acl) {
2586 + posix_acl_release (*acl);
2587 + *acl = ERR_PTR (-ENODATA);
2594 +posix_acl_access_list (struct inode *inode, const char *name, int namelen, char *out)
2596 + int len = namelen;
2597 + if (!reiserfs_posixacl (inode->i_sb))
2600 + memcpy (out, name, len);
2605 +struct reiserfs_xattr_handler posix_acl_access_handler = {
2606 + prefix: XATTR_NAME_ACL_ACCESS,
2607 + get: posix_acl_access_get,
2608 + set: posix_acl_access_set,
2609 + del: posix_acl_access_del,
2610 + list: posix_acl_access_list,
2614 +posix_acl_default_get (struct inode *inode, const char *name,
2615 + void *buffer, size_t size)
2617 + if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
2619 + return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
2623 +posix_acl_default_set(struct inode *inode, const char *name,
2624 + const void *value, size_t size, int flags)
2626 + if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
2628 + return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
2632 +posix_acl_default_del (struct inode *inode, const char *name)
2634 + struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_default;
2635 + if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
2637 + if (!IS_ERR (*acl) && *acl) {
2638 + posix_acl_release (*acl);
2639 + *acl = ERR_PTR (-ENODATA);
2646 +posix_acl_default_list (struct inode *inode, const char *name, int namelen, char *out)
2648 + int len = namelen;
2649 + if (!reiserfs_posixacl (inode->i_sb))
2652 + memcpy (out, name, len);
2657 +struct reiserfs_xattr_handler posix_acl_default_handler = {
2658 + prefix: XATTR_NAME_ACL_DEFAULT,
2659 + get: posix_acl_default_get,
2660 + set: posix_acl_default_set,
2661 + del: posix_acl_default_del,
2662 + list: posix_acl_default_list,
2666 +reiserfs_xattr_posix_acl_init (void)
2669 + err = reiserfs_xattr_register_handler (&posix_acl_access_handler);
2671 + err = reiserfs_xattr_register_handler (&posix_acl_default_handler);
2676 +reiserfs_xattr_posix_acl_exit (void)
2679 + err = reiserfs_xattr_unregister_handler (&posix_acl_access_handler);
2681 + err = reiserfs_xattr_unregister_handler (&posix_acl_default_handler);
2684 diff -urN linux-2.4.22/fs/reiserfs/xattr_trusted.c linux-2.4.22-aclea/fs/reiserfs/xattr_trusted.c
2685 --- linux-2.4.22/fs/reiserfs/xattr_trusted.c 1970-01-01 01:00:00.000000000 +0100
2686 +++ linux-2.4.22-aclea/fs/reiserfs/xattr_trusted.c 2003-09-12 17:19:43.000000000 +0200
2688 +#include <linux/reiserfs_fs.h>
2689 +#include <linux/errno.h>
2690 +#include <linux/fs.h>
2691 +#include <linux/pagemap.h>
2692 +#include <linux/xattr.h>
2693 +#include <linux/reiserfs_xattr.h>
2694 +#include <asm/uaccess.h>
2696 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
2697 +# include <linux/reiserfs_acl.h>
2700 +#define XATTR_TRUSTED_PREFIX "trusted."
2703 +trusted_get (struct inode *inode, const char *name, void *buffer, size_t size)
2705 + if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
2708 + if (!reiserfs_xattrs_trusted (inode->i_sb))
2709 + return -EOPNOTSUPP;
2711 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2714 + return reiserfs_xattr_get (inode, name, buffer, size);
2718 +trusted_set (struct inode *inode, const char *name, const void *buffer,
2719 + size_t size, int flags)
2721 + if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
2724 + if (!reiserfs_xattrs_trusted (inode->i_sb))
2725 + return -EOPNOTSUPP;
2727 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2730 + return reiserfs_xattr_set (inode, name, buffer, size, flags);
2734 +trusted_del (struct inode *inode, const char *name)
2736 + if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
2739 + if (!reiserfs_xattrs_trusted (inode->i_sb))
2740 + return -EOPNOTSUPP;
2742 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2749 +trusted_list (struct inode *inode, const char *name, int namelen, char *out)
2751 + int len = namelen;
2753 + if (!reiserfs_xattrs_trusted (inode->i_sb))
2756 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2760 + memcpy (out, name, len);
2766 +struct reiserfs_xattr_handler trusted_handler = {
2767 + prefix: XATTR_TRUSTED_PREFIX,
2771 + list: trusted_list,
2775 +reiserfs_xattr_trusted_init (void)
2777 + return reiserfs_xattr_register_handler (&trusted_handler);
2781 +reiserfs_xattr_trusted_exit (void)
2783 + return reiserfs_xattr_unregister_handler (&trusted_handler);
2785 diff -urN linux-2.4.22/fs/reiserfs/xattr_user.c linux-2.4.22-aclea/fs/reiserfs/xattr_user.c
2786 --- linux-2.4.22/fs/reiserfs/xattr_user.c 1970-01-01 01:00:00.000000000 +0100
2787 +++ linux-2.4.22-aclea/fs/reiserfs/xattr_user.c 2003-09-12 17:19:37.000000000 +0200
2789 +#include <linux/reiserfs_fs.h>
2790 +#include <linux/errno.h>
2791 +#include <linux/fs.h>
2792 +#include <linux/pagemap.h>
2793 +#include <linux/xattr.h>
2794 +#include <linux/reiserfs_xattr.h>
2795 +#include <asm/uaccess.h>
2797 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
2798 +# include <linux/reiserfs_acl.h>
2801 +#define XATTR_USER_PREFIX "user."
2804 +user_get (struct inode *inode, const char *name, void *buffer, size_t size)
2809 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
2812 + if (!reiserfs_xattrs_user (inode->i_sb))
2813 + return -EOPNOTSUPP;
2815 + error = reiserfs_permission_locked (inode, MAY_READ);
2819 + return reiserfs_xattr_get (inode, name, buffer, size);
2823 +user_set (struct inode *inode, const char *name, const void *buffer,
2824 + size_t size, int flags)
2829 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
2832 + if (!reiserfs_xattrs_user (inode->i_sb))
2833 + return -EOPNOTSUPP;
2835 + if (!S_ISREG (inode->i_mode) &&
2836 + (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
2839 + error = reiserfs_permission_locked (inode, MAY_WRITE);
2843 + return reiserfs_xattr_set (inode, name, buffer, size, flags);
2847 +user_del (struct inode *inode, const char *name)
2851 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
2854 + if (!reiserfs_xattrs_user (inode->i_sb))
2855 + return -EOPNOTSUPP;
2857 + if (!S_ISREG (inode->i_mode) &&
2858 + (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
2861 + error = reiserfs_permission_locked (inode, MAY_WRITE);
2869 +user_list (struct inode *inode, const char *name, int namelen, char *out)
2871 + int len = namelen;
2872 + if (!reiserfs_xattrs_user (inode->i_sb))
2876 + memcpy (out, name, len);
2882 +struct reiserfs_xattr_handler user_handler = {
2883 + prefix: XATTR_USER_PREFIX,
2891 +reiserfs_xattr_user_init (void)
2893 + return reiserfs_xattr_register_handler (&user_handler);
2897 +reiserfs_xattr_user_exit (void)
2899 + return reiserfs_xattr_unregister_handler (&user_handler);
2901 diff -urN linux-2.4.22/include/linux/reiserfs_acl.h linux-2.4.22-aclea/include/linux/reiserfs_acl.h
2902 --- linux-2.4.22/include/linux/reiserfs_acl.h 1970-01-01 01:00:00.000000000 +0100
2903 +++ linux-2.4.22-aclea/include/linux/reiserfs_acl.h 2003-09-12 17:19:37.000000000 +0200
2905 +#include <linux/init.h>
2906 +#include <linux/posix_acl.h>
2907 +#include <linux/xattr_acl.h>
2909 +#define REISERFS_ACL_VERSION 0x0001
2915 +} reiserfs_acl_entry;
2920 +} reiserfs_acl_entry_short;
2924 +} reiserfs_acl_header;
2926 +static inline size_t reiserfs_acl_size(int count)
2929 + return sizeof(reiserfs_acl_header) +
2930 + count * sizeof(reiserfs_acl_entry_short);
2932 + return sizeof(reiserfs_acl_header) +
2933 + 4 * sizeof(reiserfs_acl_entry_short) +
2934 + (count - 4) * sizeof(reiserfs_acl_entry);
2938 +static inline int reiserfs_acl_count(size_t size)
2941 + size -= sizeof(reiserfs_acl_header);
2942 + s = size - 4 * sizeof(reiserfs_acl_entry_short);
2944 + if (size % sizeof(reiserfs_acl_entry_short))
2946 + return size / sizeof(reiserfs_acl_entry_short);
2948 + if (s % sizeof(reiserfs_acl_entry))
2950 + return s / sizeof(reiserfs_acl_entry) + 4;
2955 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
2956 +struct posix_acl * reiserfs_get_acl(struct inode *inode, int type);
2957 +int reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl);
2958 +int reiserfs_permission (struct inode *inode, int mask);
2959 +int reiserfs_permission_locked (struct inode *inode, int mask);
2960 +int reiserfs_acl_chmod (struct inode *inode);
2961 +int reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode);
2962 +int reiserfs_cache_default_acl (struct inode *dir);
2963 +extern int reiserfs_xattr_posix_acl_init (void) __init;
2964 +extern int reiserfs_xattr_posix_acl_exit (void);
2967 +#define reiserfs_permission NULL
2968 +#define reiserfs_set_acl NULL
2969 +#define reiserfs_get_acl NULL
2970 +#define reiserfs_cache_default_acl(inode) 0
2973 +reiserfs_xattr_posix_acl_init (void)
2979 +reiserfs_xattr_posix_acl_exit (void)
2985 +reiserfs_acl_chmod (struct inode *inode)
2991 +reiserfs_inherit_default_acl (const struct inode *dir, struct dentry *dentry, struct inode *inode)
2997 diff -urN linux-2.4.22/include/linux/reiserfs_fs.h linux-2.4.22-aclea/include/linux/reiserfs_fs.h
2998 --- linux-2.4.22/include/linux/reiserfs_fs.h 2003-08-25 13:44:44.000000000 +0200
2999 +++ linux-2.4.22-aclea/include/linux/reiserfs_fs.h 2003-09-12 17:19:29.000000000 +0200
3000 @@ -1900,6 +1900,7 @@
3002 void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
3003 void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
3004 +int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
3007 inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
3008 @@ -1969,6 +1970,7 @@
3011 extern struct inode_operations reiserfs_dir_inode_operations;
3012 +extern struct inode_operations reiserfs_symlink_inode_operations;
3013 extern struct file_operations reiserfs_dir_operations;
3015 /* tail_conversion.c */
3016 @@ -2189,6 +2191,9 @@
3017 #define REISERFS_IOC_GETVERSION EXT2_IOC_GETVERSION
3018 #define REISERFS_IOC_SETVERSION EXT2_IOC_SETVERSION
3021 +#define REISERFS_XATTR_DIR_SEM(s) ((s)->u.reiserfs_sb.xattr_dir_sem)
3023 #endif /* _LINUX_REISER_FS_H */
3026 diff -urN linux-2.4.22/include/linux/reiserfs_fs_i.h linux-2.4.22-aclea/include/linux/reiserfs_fs_i.h
3027 --- linux-2.4.22/include/linux/reiserfs_fs_i.h 2003-06-13 16:51:39.000000000 +0200
3028 +++ linux-2.4.22-aclea/include/linux/reiserfs_fs_i.h 2003-09-12 17:19:37.000000000 +0200
3030 truncate or unlink. Safe link is used to avoid leakage of disk
3031 space on crash with some files open, but unlinked. */
3032 i_link_saved_unlink_mask = 0x0010,
3033 - i_link_saved_truncate_mask = 0x0020
3034 + i_link_saved_truncate_mask = 0x0020,
3035 + i_priv_object = 0x0080,
3036 } reiserfs_inode_flags;
3041 unsigned long i_tail_trans_id;
3042 unsigned long i_tail_trans_index;
3044 + struct posix_acl *i_acl_access;
3045 + struct posix_acl *i_acl_default;
3049 diff -urN linux-2.4.22/include/linux/reiserfs_fs_sb.h linux-2.4.22-aclea/include/linux/reiserfs_fs_sb.h
3050 --- linux-2.4.22/include/linux/reiserfs_fs_sb.h 2003-08-25 13:44:44.000000000 +0200
3051 +++ linux-2.4.22-aclea/include/linux/reiserfs_fs_sb.h 2003-09-12 17:19:43.000000000 +0200
3055 #include <linux/tqueue.h>
3056 +#include <linux/rwsem.h>
3060 @@ -171,13 +172,17 @@
3061 ** transaction handle which is passed around for all journal calls
3063 struct reiserfs_transaction_handle {
3064 - /* ifdef it. -Hans */
3065 - char *t_caller ; /* debugging use */
3066 + struct super_block *t_super ; /* super for this FS when journal_begin was
3067 + called. saves calls to reiserfs_get_super
3068 + also used by nested transactions to make
3069 + sure they are nesting on the right FS
3070 + _must_ be first in the handle
3073 int t_blocks_logged ; /* number of blocks this writer has logged */
3074 int t_blocks_allocated ; /* number of blocks this writer allocated */
3075 unsigned long t_trans_id ; /* sanity check, equals the current trans id */
3076 - struct super_block *t_super ; /* super for this FS when journal_begin was
3077 - called. saves calls to reiserfs_get_super */
3078 + void *t_handle_save ; /* save existing current->journal_info */
3079 int displace_new_blocks:1; /* if new block allocation occurres, that block
3080 should be displaced from others */
3083 reiserfs_proc_info_data_t s_proc_info_data;
3084 struct proc_dir_entry *procdir;
3085 int reserved_blocks; /* amount of blocks reserved for further allocations */
3086 + struct dentry *priv_root; /* root of /.reiserfs_priv */
3087 + struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
3088 + struct rw_semaphore xattr_dir_sem;
3091 /* Definitions of reiserfs on-disk properties: */
3092 @@ -459,6 +467,12 @@
3093 #define REISERFS_TEST4 14
3095 #define REISERFS_ATTRS (15)
3096 +#define REISERFS_XATTRS 16
3097 +#define REISERFS_XATTRS_USER 17
3098 +#define REISERFS_NO_XATTRS_USER 18
3099 +#define REISERFS_POSIXACL 17
3100 +#define REISERFS_NO_POSIXACL 18
3103 #define reiserfs_r5_hash(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << FORCE_R5_HASH))
3104 #define reiserfs_rupasov_hash(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << FORCE_RUPASOV_HASH))
3105 @@ -476,6 +490,17 @@
3106 #define reiserfs_attrs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_ATTRS))
3107 #define old_format_only(s) ((s)->u.reiserfs_sb.s_properties & (1 << REISERFS_3_5))
3108 #define convert_reiserfs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_CONVERT))
3109 +#define reiserfs_xattrs_user(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_XATTRS_USER))
3110 +#define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s))
3111 +#define reiserfs_posixacl(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_POSIXACL))
3112 +#ifndef CONFIG_REISERFS_FS_XATTR_TRUSTED
3113 +#define reiserfs_xattrs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_XATTRS))
3114 +# define reiserfs_xattrs_trusted(s) (0)
3116 +/* If trusted xattrs are compiled in, they're "always on." */
3117 +# define reiserfs_xattrs(s) (1)
3118 +# define reiserfs_xattrs_trusted(s) (1)
3122 void reiserfs_file_buffer (struct buffer_head * bh, int list);
3123 diff -urN linux-2.4.22/include/linux/reiserfs_xattr.h linux-2.4.22-aclea/include/linux/reiserfs_xattr.h
3124 --- linux-2.4.22/include/linux/reiserfs_xattr.h 1970-01-01 01:00:00.000000000 +0100
3125 +++ linux-2.4.22-aclea/include/linux/reiserfs_xattr.h 2003-09-12 17:19:43.000000000 +0200
3128 + File: linux/reiserfs_xattr.h
3131 +#include <linux/config.h>
3132 +#include <linux/init.h>
3133 +#include <linux/xattr.h>
3135 +/* Magic value in header */
3136 +#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
3138 +struct reiserfs_xattr_header {
3139 + __u32 h_magic; /* magic number for identification */
3140 + __u32 h_hash; /* hash of the value */
3145 +struct reiserfs_xattr_handler {
3147 + int (*get)(struct inode *inode, const char *name, void *buffer,
3149 + int (*set)(struct inode *inode, const char *name, const void *buffer,
3150 + size_t size, int flags);
3151 + int (*del)(struct inode *inode, const char *name);
3152 + int (*list)(struct inode *inode, const char *name, int namelen, char *out);
3153 + struct reiserfs_xattr_handler *next;
3157 +#ifdef CONFIG_REISERFS_FS_XATTR
3158 +#define is_reiserfs_priv_object(inode) (((inode)->u.reiserfs_i.i_flags & i_priv_object) == i_priv_object)
3159 +ssize_t reiserfs_getxattr (struct dentry *dentry, const char *name,
3160 + void *buffer, size_t size);
3161 +int reiserfs_setxattr (struct dentry *dentry, const char *name,
3162 + const void *value, size_t size, int flags);
3163 +ssize_t reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size);
3164 +int reiserfs_removexattr (struct dentry *dentry, const char *name);
3165 +int reiserfs_delete_xattrs (struct inode *inode);
3166 +int reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs);
3167 +int reiserfs_xattr_init (struct super_block *sb, int mount_flags);
3170 +reiserfs_write_lock_xattrs(struct super_block *sb)
3172 + down_write (&REISERFS_XATTR_DIR_SEM(sb));
3175 +reiserfs_write_unlock_xattrs(struct super_block *sb)
3177 + up_write (&REISERFS_XATTR_DIR_SEM(sb));
3180 +reiserfs_read_lock_xattrs(struct super_block *sb)
3182 + down_read (&REISERFS_XATTR_DIR_SEM(sb));
3185 +reiserfs_read_unlock_xattrs(struct super_block *sb)
3187 + up_read (&REISERFS_XATTR_DIR_SEM(sb));
3190 +#define is_reiserfs_priv_object(inode) 0
3191 +#define reiserfs_getxattr NULL
3192 +#define reiserfs_setxattr NULL
3193 +#define reiserfs_listxattr NULL
3194 +#define reiserfs_removexattr NULL
3195 +#define reiserfs_write_lock_xattrs(sb)
3196 +#define reiserfs_write_unlock_xattrs(sb)
3197 +#define reiserfs_read_lock_xattrs(sb)
3198 +#define reiserfs_read_unlock_xattrs(sb)
3200 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
3202 + s->s_flags = (s->s_flags & ~MS_POSIXACL); /* to be sure */
3207 +reiserfs_delete_xattrs (struct inode *inode)
3213 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
3219 +extern int reiserfs_xattr_register_handler(struct reiserfs_xattr_handler *);
3220 +extern int reiserfs_xattr_unregister_handler(struct reiserfs_xattr_handler *);
3221 +extern int reiserfs_xattr_del (struct inode *, const char *);
3222 +extern int reiserfs_xattr_get (const struct inode *, const char *, void *, size_t);
3223 +extern int reiserfs_xattr_set (struct inode *, const char *, const void *,
3225 +#ifdef CONFIG_REISERFS_FS_XATTR_USER
3226 +extern int reiserfs_xattr_user_init (void) __init;
3227 +extern int reiserfs_xattr_user_exit (void);
3230 +reiserfs_xattr_user_init (void)
3236 +reiserfs_xattr_user_exit (void)
3241 +#ifdef CONFIG_REISERFS_FS_XATTR_TRUSTED
3242 +extern int reiserfs_xattr_trusted_init (void) __init;
3243 +extern int reiserfs_xattr_trusted_exit (void);
3246 +reiserfs_xattr_trusted_init (void)
3252 +reiserfs_xattr_trusted_exit (void)
3258 +#endif /* __KERNEL__ */