]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.22-reiserfs-acl+ea.patch
- obsolete
[packages/kernel.git] / linux-2.4.22-reiserfs-acl+ea.patch
CommitLineData
2416a217
JR
1diff -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
4@@ -13,6 +13,10 @@
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
12
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
15diff -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
18@@ -11,6 +11,11 @@
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
21
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
26+
27 obj-m := $(O_TARGET)
28
29 # gcc -O2 (the kernel default) is overaggressive on ppc32 when many inline
30diff -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
33@@ -110,6 +110,15 @@
34 /* too big to send back to VFS */
35 continue ;
36 }
37+
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))
44+ continue;
45+
46 d_off = deh_offset (deh);
47 filp->f_pos = d_off ;
48 d_ino = deh_objectid (deh);
49diff -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
52@@ -5,6 +5,8 @@
53
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>
59
60 /*
61@@ -90,45 +92,6 @@
62 return ( n_err < 0 ) ? -EIO : 0;
63 }
64
65-static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
66- struct inode *inode = dentry->d_inode ;
67- int error ;
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
71- */
72- if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
73- attr->ia_size > MAX_NON_LFS)
74- return -EFBIG ;
75-
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) ;
85- }
86- if (error)
87- return error ;
88- }
89- }
90-
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 */
95- return -EINVAL;
96-
97- error = inode_change_ok(inode, attr) ;
98- if (!error)
99- inode_setattr(inode, attr) ;
100-
101- return error ;
102-}
103-
104 struct file_operations reiserfs_file_operations = {
105 read: generic_file_read,
106 write: generic_file_write,
107@@ -142,6 +105,11 @@
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,
116 };
117
118
119diff -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
122@@ -5,8 +5,11 @@
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>
133
134@@ -37,6 +40,8 @@
135 if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
136 down (&inode->i_sem);
137
138+ reiserfs_delete_xattrs (inode);
139+
140 journal_begin(&th, inode->i_sb, jbegin_count) ;
141 reiserfs_update_inode_transaction(inode) ;
142 windex = push_journal_writer("delete_inode") ;
143@@ -206,6 +211,10 @@
144 struct super_block *s = th->t_super ;
145 int len = th->t_blocks_allocated ;
146
147+ /* we cannot restart while nested */
148+ if (th->t_refcount > 1) {
149+ return ;
150+ }
151 pathrelse(path) ;
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;
161 } else {
162 inode->i_blocks = 0;
163@@ -1694,6 +1703,18 @@
164 goto out_inserted_sd;
165 }
166
167+ if (reiserfs_posixacl (inode->i_sb)) {
168+ retval = reiserfs_inherit_default_acl (dir, dentry, inode);
169+ if (retval) {
170+ iput (inode);
171+ err = retval;
172+ reiserfs_check_path(&path_to_key) ;
173+ goto out_inserted_sd;
174+ }
175+ } else if (inode->i_sb->s_flags & MS_POSIXACL) {
d871ed22 176+ reiserfs_warning (inode->i_sb, "ACLs aren't enabled in the fs, but vfs thinks they are!\n");
2416a217
JR
177+ }
178+
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) ;
184 }
185
186+int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
187+ struct inode *inode = dentry->d_inode ;
188+ int error ;
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
193+ */
194+ if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
195+ attr->ia_size > MAX_NON_LFS)
196+ return -EFBIG ;
197+
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) ;
207+ }
208+ if (error)
209+ return error ;
210+ }
211+ }
212+
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 */
217+ return -EINVAL;
218+
219+ error = inode_change_ok(inode, attr) ;
220+ if (!error) {
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);
228+
229+#if defined(CONFIG_QUOTA)
230+ if (!error)
231+ error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
232+#endif
233+ }
234+ if (!error)
235+ inode_setattr(inode, attr) ;
236+ }
237+
238+
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);
246+ }
247+ }
248+
249+ return error ;
250+}
251+
252 struct address_space_operations reiserfs_address_space_operations = {
253 writepage: reiserfs_writepage,
254 readpage: reiserfs_readpage,
255diff -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))
261 return 0 ;
262+ /* cannot restart while nested */
263+ if (th->t_refcount > 1)
264+ return 0 ;
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 @@
269 return 0 ;
270 }
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 ;
275
276 relock:
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) ;
286 p_s_sb->s_dirt = 1;
287 return 0 ;
288@@ -2353,11 +2357,47 @@
289
290
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;
293+
294+ /* this keeps do_journal_end from NULLing out the current->journal_info
295+ ** pointer
296+ */
297+ th->t_handle_save = cur_th ;
298+ if (cur_th && cur_th->t_refcount > 1) {
299+ BUG() ;
300+ }
301 return do_journal_begin_r(th, p_s_sb, nblocks, 1) ;
302 }
303
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 ;
307+ int ret ;
308+
309+ th->t_handle_save = NULL ;
310+ if (cur_th) {
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");
317+ return 0;
318+ } else {
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...
322+ */
323+ reiserfs_warning("clm-2100: nesting info a different FS\n") ;
324+ th->t_handle_save = current->journal_info ;
325+ current->journal_info = th;
326+ }
327+ } else {
328+ current->journal_info = th;
329+ }
330+ ret = do_journal_begin_r(th, p_s_sb, nblocks, 0) ;
331+ if (current->journal_info != th)
332+ BUG() ;
333+ return ret ;
334 }
335
336 /* not used at all */
337@@ -2497,7 +2537,23 @@
338 }
339
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 ;
346+
347+ /* we aren't allowed to close a nested transaction on a different
348+ ** filesystem from the one in the task struct
349+ */
350+ if (cur_th->t_super != th->t_super)
351+ BUG() ;
352+
353+ th->t_refcount--;
354+ memcpy(current->journal_info, th, sizeof(*th));
355+ return 0;
356+ } else {
357+ return do_journal_end(th, p_s_sb, nblocks, 0) ;
358+ }
359 }
360
361 /* removes from the current transaction, relsing and descrementing any counters.
362@@ -2600,6 +2656,10 @@
363 */
364 int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
365
366+ /* you can sync while nested, very, very bad */
367+ if (th->t_refcount > 1) {
368+ BUG() ;
369+ }
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 ;
376
377+ if (th->t_refcount > 1)
378+ BUG() ;
379+
380+ current->journal_info = th->t_handle_save;
381 if (reiserfs_dont_log(th->t_super)) {
382 return 0 ;
383 }
384@@ -3037,8 +3101,11 @@
385 }
386
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
391 * the transaction */
392+ current->journal_info = th->t_handle_save ;
393 #endif
394
395 rs = SB_DISK_SUPER_BLOCK(p_s_sb) ;
396diff -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
399@@ -6,6 +6,8 @@
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>
406
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);
419+ }
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);
423 }
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;
427 }
428 if ( retval == IO_ERROR ) {
429 return ERR_PTR(-EIO);
430@@ -527,6 +540,7 @@
431 struct inode * inode;
432 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
433 struct reiserfs_transaction_handle th ;
434+ int locked;
435
436 if (!(inode = new_inode(dir->i_sb))) {
437 return -ENOMEM ;
438@@ -535,8 +549,11 @@
439 if (retval)
440 return retval ;
441
442+ locked = reiserfs_cache_default_acl (dir);
443+ if (locked)
444+ reiserfs_write_lock_xattrs (dir->i_sb);
445+
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);
449 if (retval) {
450 goto out_failed ;
451@@ -548,6 +565,9 @@
452
453 retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
454 inode, 1/*visible*/);
455+ if (locked)
456+ reiserfs_write_unlock_xattrs (dir->i_sb);
457+
458 if (retval) {
459 inode->i_nlink--;
460 reiserfs_update_sd (&th, inode);
461@@ -573,6 +593,7 @@
462 struct inode * inode;
463 struct reiserfs_transaction_handle th ;
464 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
465+ int locked;
466
467 if (!(inode = new_inode(dir->i_sb))) {
468 return -ENOMEM ;
469@@ -581,9 +602,17 @@
470 if (retval)
471 return retval ;
472
473+ locked = reiserfs_cache_default_acl (dir);
474+ if (locked)
475+ reiserfs_write_lock_xattrs (inode->i_sb);
476+
477 journal_begin(&th, dir->i_sb, jbegin_count) ;
478
479 retval = reiserfs_new_inode(&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
480+
481+ if (locked)
482+ reiserfs_write_unlock_xattrs (inode->i_sb);
483+
484 if (retval) {
485 goto out_failed;
486 }
487@@ -621,6 +650,7 @@
488 struct inode * inode;
489 struct reiserfs_transaction_handle th ;
490 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
491+ int locked;
492
493 mode = S_IFDIR | mode;
494 if (!(inode = new_inode(dir->i_sb))) {
495@@ -630,6 +660,10 @@
496 if (retval)
497 return retval ;
498
499+ locked = reiserfs_cache_default_acl (dir);
500+ if (locked)
501+ reiserfs_write_lock_xattrs (inode->i_sb);
502+
503 journal_begin(&th, dir->i_sb, jbegin_count) ;
504
505 /* inc the link count now, so another writer doesn't overflow it while
506@@ -645,6 +679,9 @@
507 old_format_only (dir->i_sb) ?
508 EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
509 dentry, inode) ;
510+ if (locked)
511+ reiserfs_write_unlock_xattrs (inode->i_sb);
512+
513 if (retval) {
514 dir->i_nlink-- ;
515 goto out_failed ;
516@@ -892,6 +929,8 @@
517 memcpy (name, symname, strlen (symname));
518 padd_item (name, item_len, strlen (symname));
519
520+ /* We would inherit the default ACL here, but symlinks don't get ACLs */
521+
522 journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
523
524 retval = reiserfs_new_inode(&th, parent_dir, mode, name,
525@@ -904,7 +943,7 @@
526 reiserfs_update_inode_transaction(inode) ;
527 reiserfs_update_inode_transaction(parent_dir) ;
528
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;
532
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,
544 };
545
546+/*
547+ * symlink operations.. same as page_symlink_inode_operations, with xattr
548+ * stuff added
549+ */
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,
559+};
560diff -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
d871ed22 563@@ -9,6 +9,9 @@
2416a217
JR
564 #include <linux/vmalloc.h>
565 #include <asm/uaccess.h>
566 #include <linux/reiserfs_fs.h>
d871ed22 567+#include <linux/reiserfs_fs_sb.h>
2416a217
JR
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>
573@@ -344,7 +346,17 @@
574 {
575 int i;
576 struct reiserfs_transaction_handle th ;
577+
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);
581+ }
582
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);
586+ }
587+
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) ;
591@@ -408,6 +420,22 @@
592 unlock_kernel() ;
593 }
594
595+static void reiserfs_clear_inode (struct inode *inode)
596+{
597+ struct posix_acl *acl;
598+
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;
603+
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;
608+}
609+
610+
611 struct super_operations reiserfs_sops =
612 {
613 read_inode: reiserfs_read_inode,
614@@ -415,6 +443,7 @@
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,
622@@ -616,6 +645,16 @@
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},
630+# endif
631+# ifdef CONFIG_REISERFS_FS_POSIX_ACL
632+ {"acl", 0, 0, REISERFS_POSIXACL},
633+ {"noacl", 0, 0, REISERFS_NO_POSIXACL},
634+# endif
635+#endif
636 {NULL, 0, 0, 0, 0}
637 };
638
639@@ -692,6 +731,10 @@
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;
647
648 /* Update the bitmask, taking care to keep
649 * the bits we're not allowed to change here */
650@@ -706,6 +749,7 @@
651 }
652
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 */
658@@ -723,8 +767,10 @@
659 s->s_dirt = 0;
660 } else {
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 */
666+ }
667
668 s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
669 journal_begin(&th, s, 10) ;
670@@ -743,8 +789,10 @@
671 SB_JOURNAL(s)->j_must_wait = 1 ;
672 journal_end(&th, s, 10) ;
673
674- if (!( *mount_flags & MS_RDONLY ) )
675+ if (!( *mount_flags & MS_RDONLY ) ) {
676 finish_unfinished( s );
677+ reiserfs_xattr_init (s, *mount_flags);
678+ }
679
680 return 0;
681 }
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);
688
689 if (reiserfs_parse_options (s, (char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
690 return NULL;
691@@ -1301,11 +1351,23 @@
692
693 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
694 journal_end(&th, s, 1) ;
695-
696+
697+ if (reiserfs_xattr_init (s, s->s_flags)) {
698+ dput (s->s_root);
699+ s->s_root = NULL;
700+ goto error;
701+ }
702+
703 /* look for files which were to be removed in previous session */
704 finish_unfinished (s);
705
706 s->s_dirt = 0;
707+ } else {
708+ if (reiserfs_xattr_init (s, s->s_flags)) {
709+ dput (s->s_root);
710+ s->s_root = NULL;
711+ goto error;
712+ }
713 }
714
715 // mark hash in super block: it could be unset. overwrite should be ok
716@@ -1364,10 +1426,29 @@
717
718 static int __init init_reiserfs_fs (void)
719 {
720+ int ret;
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;
727+
728+ ret = reiserfs_xattr_trusted_init();
729+ if (ret) goto failed_xattr_trusted_init;
730+
731+ ret = reiserfs_xattr_posix_acl_init();
732+ if (ret) goto failed_xattr_posix_acl_init;
733+
734+ return register_filesystem(&reiserfs_fs_type);
735+
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();
743+ return ret;
744 }
745
746 MODULE_DESCRIPTION("ReiserFS journaled filesystem");
747@@ -1377,6 +1458,9 @@
748
749 static void __exit exit_reiserfs_fs(void)
750 {
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);
757diff -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
760@@ -0,0 +1,1266 @@
761+/*
762+ * linux/fs/reiserfs/xattr.c
763+ *
764+ * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com>
765+ *
766+ */
767+
768+/*
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.
776+ *
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
781+ * .. or similar.
782+ *
783+ * The file contents are the text of the EA. The size is known based on the
784+ * stat data describing the file.
785+ *
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.
790+ */
791+
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>
806+
807+#define FL_READONLY 128
808+#define FL_DIR_SEM_HELD 256
809+#define PRIVROOT_NAME ".reiserfs_priv"
810+#define XAROOT_NAME "xattrs"
811+
812+static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix);
813+
814+static struct dentry *
815+create_xa_root (struct super_block *sb)
816+{
817+ struct dentry *privroot = dget (sb->u.reiserfs_sb.priv_root);
818+ struct dentry *xaroot;
819+
820+ /* This needs to be created at mount-time */
821+ if (!privroot)
822+ return ERR_PTR(-EOPNOTSUPP);
823+
824+ xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
825+ if (IS_ERR (xaroot)) {
826+ goto out;
827+ } else if (!xaroot->d_inode) {
828+ int err;
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);
832+
833+ if (err) {
834+ dput (xaroot);
835+ dput (privroot);
836+ return ERR_PTR (err);
837+ }
838+ sb->u.reiserfs_sb.xattr_root = dget (xaroot);
839+ }
840+
841+out:
842+ dput (privroot);
843+ return xaroot;
844+}
845+
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)
852+{
853+ struct dentry *privroot = dget (s->u.reiserfs_sb.priv_root);
854+ struct dentry *xaroot = NULL;
855+
856+ if (IS_ERR (privroot) || !privroot)
857+ return privroot;
858+
859+ xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
860+ if (IS_ERR (xaroot)) {
861+ goto out;
862+ } else if (!xaroot->d_inode) {
863+ dput (xaroot);
864+ xaroot = NULL;
865+ goto out;
866+ }
867+
868+ s->u.reiserfs_sb.xattr_root = dget (xaroot);
869+
870+out:
871+ dput (privroot);
872+ return xaroot;
873+}
874+
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.
879+ */
880+static inline struct dentry *
881+get_xa_root (struct super_block *s)
882+{
883+ struct dentry *dentry = s->u.reiserfs_sb.xattr_root;
884+
885+ if (!dentry)
886+ dentry = __get_xa_root (s);
887+ else
888+ dget (dentry);
889+ return dentry;
890+}
891+
892+/* Same as above, but only returns a valid dentry or NULL */
893+struct dentry *
894+reiserfs_get_xa_root (struct super_block *sb)
895+{
896+ struct dentry *dentry;
897+
898+ dentry = get_xa_root (sb);
899+ if (IS_ERR (dentry)) {
900+ dentry = NULL;
901+ } else if (dentry && !dentry->d_inode) {
902+ dput (dentry);
903+ dentry = NULL;
904+ }
905+
906+ return dentry;
907+}
908+
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)
914+{
915+ struct dentry *xaroot, *xadir;
916+ char namebuf[17];
917+
918+ xaroot = get_xa_root (inode->i_sb);
919+ if (IS_ERR (xaroot)) {
920+ return 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))
925+ return xaroot;
926+ }
927+ if (!xaroot)
928+ return ERR_PTR (-ENODATA);
929+ }
930+
931+ /* ok, we have xaroot open */
932+
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)) {
938+ dput (xaroot);
939+ return xadir;
940+ }
941+
942+ if (!xadir->d_inode) {
943+ int err;
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);
949+ if (err) {
950+ dput (xaroot);
951+ dput (xadir);
952+ return ERR_PTR (err);
953+ }
954+ }
955+ if (!xadir->d_inode) {
956+ dput (xaroot);
957+ dput (xadir);
958+ return ERR_PTR (-ENODATA);
959+ }
960+ }
961+
962+ dput (xaroot);
963+ return xadir;
964+}
965+
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)
971+{
972+ struct dentry *xadir, *xafile;
973+ int err = 0;
974+
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) {
979+ dput (xadir);
980+ return ERR_PTR (-ENODATA);
981+ }
982+
983+ xafile = lookup_one_len (name, xadir, strlen (name));
984+ if (IS_ERR (xafile)) {
985+ dput (xadir);
986+ return ERR_PTR (PTR_ERR (xafile));
987+ }
988+
989+ if (xafile->d_inode) { /* file exists */
990+ if (flags & XATTR_CREATE) {
991+ err = -EEXIST;
992+ dput (xafile);
993+ goto out;
994+ }
995+ } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
996+ goto out;
997+ } else {
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,
1001+ 0700|S_IFREG);
1002+
1003+ if (err) {
1004+ dput (xafile);
1005+ goto out;
1006+ }
1007+ }
1008+
1009+out:
1010+ dput (xadir);
1011+ if (err)
1012+ xafile = ERR_PTR (err);
1013+ return xafile;
1014+}
1015+
1016+
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)
1020+{
1021+ struct dentry *xafile;
1022+ struct file *fp;
1023+
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) {
1028+ dput (xafile);
1029+ return ERR_PTR (-ENODATA);
1030+ }
1031+
1032+ fp = dentry_open (xafile, NULL, O_RDWR);
1033+ /* dentry_open dputs the dentry if it fails */
1034+
1035+ return fp;
1036+}
1037+
1038+
1039+/*
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
1044+ *
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.
1048+ *
1049+ * we're called with i_sem held, so there are no worries about the directory
1050+ * changing underneath us.
1051+ */
1052+static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir)
1053+{
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;
1058+ int entry_num;
1059+ struct item_head * ih, tmp_ih;
1060+ int search_res;
1061+ char * local_buf;
1062+ loff_t next_pos;
1063+ char small_buf[32] ; /* avoid kmalloc if we can */
1064+ struct reiserfs_de_head *deh;
1065+ int d_reclen;
1066+ char * d_name;
1067+ off_t d_off;
1068+ ino_t d_ino;
1069+ struct reiserfs_dir_entry de;
1070+
1071+
1072+ /* form key for search the next directory entry using f_pos field of
1073+ file structure */
1074+ next_pos = max_reiserfs_offset(inode);
1075+
1076+ while (1) {
1077+research:
1078+ if (next_pos <= DOT_DOT_OFFSET)
1079+ break;
1080+ make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
1081+
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
1085+ // not be read
1086+ pathrelse(&path_to_entry);
1087+ return -EIO;
1088+ }
1089+
1090+ if (search_res == NAME_NOT_FOUND)
1091+ de.de_entry_num--;
1092+
1093+ set_de_name_and_namelen(&de);
1094+ entry_num = de.de_entry_num;
1095+ deh = &(de.de_deh[entry_num]);
1096+
1097+ bh = de.de_bh;
1098+ ih = de.de_ih;
1099+
1100+ if (!is_direntry_le_ih(ih)) {
d871ed22 1101+reiserfs_warning(inode->i_sb, "not direntry %h\n", ih);
2416a217
JR
1102+ break;
1103+ }
1104+ copy_item_head(&tmp_ih, ih);
1105+
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",
1109+ ih, &pos_key);
1110+
1111+ if (deh_offset(deh) <= DOT_DOT_OFFSET) {
1112+ break;
1113+ }
1114+
1115+ /* look for the previous entry in the directory */
1116+ next_pos = deh_offset (deh) - 1;
1117+
1118+ if (!de_visible (deh))
1119+ /* it is hidden entry */
1120+ continue;
1121+
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);
1126+
1127+ if (!d_name[d_reclen - 1])
1128+ d_reclen = strlen (d_name);
1129+
1130+ if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
1131+ /* too big to send back to VFS */
1132+ continue ;
1133+ }
1134+
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))
1139+ continue;
1140+
1141+ if (d_reclen <= 32) {
1142+ local_buf = small_buf ;
1143+ } else {
1144+ local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
1145+ if (!local_buf) {
1146+ pathrelse (&path_to_entry);
1147+ return -ENOMEM ;
1148+ }
1149+ if (item_moved (&tmp_ih, &path_to_entry)) {
1150+ reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
1151+
1152+ /* sigh, must retry. Do this same offset again */
1153+ next_pos = d_off;
1154+ goto research;
1155+ }
1156+ }
1157+
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);
1163+
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
1167+ */
1168+ pathrelse (&path_to_entry);
1169+
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) ;
1174+ }
1175+ goto end;
1176+ }
1177+ if (local_buf != small_buf) {
1178+ reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
1179+ }
1180+ } /* while */
1181+
1182+end:
1183+ pathrelse (&path_to_entry);
1184+ return 0;
1185+}
1186+
1187+/*
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
1191+ *
1192+ */
1193+static
1194+int xattr_readdir(struct file *file, filldir_t filler, void *buf)
1195+{
1196+ struct inode *inode = file->f_dentry->d_inode;
1197+ int res = -ENOTDIR;
1198+ if (!file->f_op || !file->f_op->readdir)
1199+ goto out;
1200+ down(&inode->i_sem);
1201+ down(&inode->i_zombie);
1202+ res = -ENOENT;
1203+ if (!IS_DEADDIR(inode)) {
1204+ lock_kernel();
1205+ res = __xattr_readdir(file, buf, filler);
1206+ unlock_kernel();
1207+ }
1208+ up(&inode->i_zombie);
1209+ up(&inode->i_sem);
1210+out:
1211+ return res;
1212+}
1213+
1214+
1215+/* Internal operations on file data */
1216+static inline void
1217+reiserfs_put_page(struct page *page)
1218+{
1219+ kunmap(page);
1220+ page_cache_release(page);
1221+}
1222+
1223+static struct page *
1224+reiserfs_get_page(struct inode *dir, unsigned long n)
1225+{
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);
1235+ kmap(page);
1236+ if (!Page_Uptodate(page))
1237+ goto fail;
1238+
1239+ if (PageError(page))
1240+ goto fail;
1241+ }
1242+ return page;
1243+
1244+fail:
1245+ reiserfs_put_page(page);
1246+ return ERR_PTR(-EIO);
1247+}
1248+
1249+static inline __u32
1250+xattr_hash (const char *msg, int len)
1251+{
1252+ return csum_partial (msg, len, 0);
1253+}
1254+
1255+/* Generic extended attribute operations that can be used by xa plugins */
1256+
1257+/*
1258+ * inode->i_sem: down
1259+ */
1260+int
1261+reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer,
1262+ size_t buffer_size, int flags)
1263+{
1264+ int err = 0;
1265+ struct file *fp;
1266+ struct page *page;
1267+ char *data;
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;
1273+ __u32 xahash = 0;
1274+
1275+ if (get_inode_sd_version (inode) == STAT_DATA_V1)
1276+ return -EOPNOTSUPP;
1277+
1278+ /* Empty xattrs are ok, they're just empty files, no hash */
1279+ if (buffer && buffer_size)
1280+ xahash = xattr_hash (buffer, buffer_size);
1281+
1282+open_file:
1283+ fp = open_xa_file (inode, name, flags);
1284+ if (IS_ERR (fp)) {
1285+ err = PTR_ERR (fp);
1286+ goto out;
1287+ }
1288+
1289+ xinode = fp->f_dentry->d_inode;
1290+
1291+ /* we need to copy it off.. */
1292+ if (xinode->i_nlink > 1) {
1293+ fput(fp);
1294+ err = reiserfs_xattr_del (inode, name);
1295+ if (err < 0)
1296+ goto out;
1297+ /* We just killed the old one, we're not replacing anymore */
1298+ if (flags & XATTR_REPLACE)
1299+ flags &= ~XATTR_REPLACE;
1300+ goto open_file;
1301+ }
1302+
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);
1308+ if (err)
1309+ goto out_filp;
1310+
1311+ mapping = xinode->i_mapping;
1312+ while (buffer_pos < buffer_size || buffer_pos == 0) {
1313+ size_t chunk;
1314+ size_t skip = 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;
1318+ else
1319+ chunk = buffer_size - buffer_pos;
1320+
1321+ page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
1322+ if (IS_ERR (page)) {
1323+ err = PTR_ERR (page);
1324+ goto out_filp;
1325+ }
1326+
1327+ lock_page (page);
1328+ data = page_address (page);
1329+
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);
1338+ }
1339+
1340+ err = mapping->a_ops->prepare_write (fp, page, page_offset,
1341+ page_offset + chunk + skip);
1342+ if (!err) {
1343+ if (buffer)
1344+ memcpy (data + skip, buffer + buffer_pos, chunk);
1345+ err = mapping->a_ops->commit_write (fp, page, page_offset,
1346+ page_offset + chunk + skip);
1347+ }
1348+ UnlockPage (page);
1349+ reiserfs_put_page (page);
1350+ buffer_pos += chunk;
1351+ file_pos += chunk;
1352+ skip = 0;
1353+ if (err || buffer_size == 0 || !buffer)
1354+ break;
1355+ }
1356+
1357+out_filp:
1358+ up (&xinode->i_sem);
1359+ fput(fp);
1360+
1361+out:
1362+ return err;
1363+}
1364+
1365+/*
1366+ * inode->i_sem: down
1367+ */
1368+int
1369+reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer,
1370+ size_t buffer_size)
1371+{
1372+ ssize_t err = 0;
1373+ struct file *fp;
1374+ size_t isize;
1375+ size_t file_pos = 0;
1376+ size_t buffer_pos = 0;
1377+ struct page *page;
1378+ struct inode *xinode;
1379+ __u32 hash = 0;
1380+
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;
1385+
1386+ fp = open_xa_file (inode, name, FL_READONLY);
1387+ if (IS_ERR (fp)) {
1388+ err = PTR_ERR (fp);
1389+ goto out;
1390+ }
1391+
1392+ xinode = fp->f_dentry->d_inode;
1393+ isize = xinode->i_size;
1394+
1395+ /* Just return the size needed */
1396+ if (buffer == NULL) {
1397+ err = isize - sizeof (struct reiserfs_xattr_header);
1398+ goto out_dput;
1399+ }
1400+
1401+ if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) {
1402+ err = -ERANGE;
1403+ goto out_dput;
1404+ }
1405+
1406+ while (file_pos < isize) {
1407+ size_t chunk;
1408+ char *data;
1409+ size_t skip = 0;
1410+ if (isize - file_pos > PAGE_CACHE_SIZE)
1411+ chunk = PAGE_CACHE_SIZE;
1412+ else
1413+ chunk = isize - file_pos;
1414+
1415+ page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
1416+ if (IS_ERR (page)) {
1417+ err = PTR_ERR (page);
1418+ goto out_dput;
1419+ }
1420+
1421+ lock_page (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);
1427+ chunk -= skip;
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);
1432+ err = -EIO;
1433+ goto out_dput;
1434+ }
1435+ hash = le32_to_cpu (rxh->h_hash);
1436+ }
1437+ memcpy (buffer + buffer_pos, data + skip, chunk);
1438+ UnlockPage (page);
1439+ reiserfs_put_page (page);
1440+ file_pos += chunk;
1441+ buffer_pos += chunk;
1442+ skip = 0;
1443+ }
1444+ err = isize - sizeof (struct reiserfs_xattr_header);
1445+
1446+ if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash)
1447+ err = -EIO;
1448+
1449+out_dput:
1450+ fput(fp);
1451+
1452+out:
1453+ return err;
1454+}
1455+
1456+static int
1457+__reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen)
1458+{
1459+ struct dentry *file;
1460+ struct inode *dir = xadir->d_inode;
1461+ int err = 0;
1462+
1463+ file = lookup_one_len (name, xadir, namelen);
1464+ if (IS_ERR (file)) {
1465+ err = PTR_ERR (file);
1466+ goto out;
1467+ } else if (!file->d_inode) {
1468+ err = -ENODATA;
1469+ goto out_file;
1470+ }
1471+
1472+ /* Skip directories.. */
1473+ if (S_ISDIR (file->d_inode->i_mode))
1474+ goto out_file;
1475+
1476+ if (!is_reiserfs_priv_object (file->d_inode)) {
d871ed22 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));
2416a217
JR
1478+ dput (file);
1479+ return -EIO;
1480+ }
1481+
1482+ err = dir->i_op->unlink (dir, file);
1483+ if (!err)
1484+ d_delete (file);
1485+
1486+out_file:
1487+ dput (file);
1488+
1489+out:
1490+ return err;
1491+}
1492+
1493+
1494+int
1495+reiserfs_xattr_del (struct inode *inode, const char *name)
1496+{
1497+ struct dentry *dir;
1498+ int err;
1499+
1500+ dir = open_xa_dir (inode, FL_READONLY);
1501+ if (IS_ERR (dir)) {
1502+ err = PTR_ERR (dir);
1503+ goto out;
1504+ }
1505+
1506+ err = __reiserfs_xattr_del (dir, name, strlen (name));
1507+ dput (dir);
1508+
1509+out:
1510+ return err;
1511+}
1512+
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. */
1516+
1517+static int
1518+reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen,
1519+ loff_t offset, ino_t ino, unsigned int d_type)
1520+{
1521+ struct dentry *xadir = (struct dentry *)buf;
1522+
1523+ return __reiserfs_xattr_del (xadir, name, namelen);
1524+
1525+}
1526+
1527+int
1528+reiserfs_delete_xattrs (struct inode *inode)
1529+{
1530+ struct file *fp;
1531+ struct dentry *dir, *root;
1532+ int err = 0;
1533+
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))
1538+ {
1539+ return 0;
1540+ }
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);
1546+ goto out;
1547+ } else if (!dir->d_inode) {
1548+ dput (dir);
1549+ return 0;
1550+ }
1551+
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 */
1556+ goto out;
1557+ }
1558+
1559+ lock_kernel ();
1560+ err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir);
1561+ if (err) {
1562+ unlock_kernel ();
1563+ goto out_dir;
1564+ }
1565+
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);
1572+ dput (root);
1573+ } else {
d871ed22 1574+ reiserfs_warning (inode->i_sb, "Couldn't remove all entries in directory\n");
2416a217
JR
1575+ }
1576+ unlock_kernel ();
1577+
1578+out_dir:
1579+ fput(fp);
1580+
1581+out:
1582+ return err;
1583+}
1584+
1585+struct reiserfs_chown_buf {
1586+ struct inode *inode;
1587+ struct dentry *xadir;
1588+ struct iattr *attrs;
1589+};
1590+
1591+/* XXX: If there is a better way to do this, I'd love to hear about it */
1592+static int
1593+reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen,
1594+ loff_t offset, ino_t ino, unsigned int d_type)
1595+{
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;
1599+ int err = 0;
1600+
1601+ xafile = lookup_one_len (name, xadir, namelen);
1602+ if (IS_ERR (xafile))
1603+ return PTR_ERR (xafile);
1604+ else if (!xafile->d_inode) {
1605+ dput (xafile);
1606+ return -ENODATA;
1607+ }
1608+
1609+ if (!S_ISDIR (xafile->d_inode->i_mode))
1610+ err = notify_change (xafile, attrs);
1611+ dput (xafile);
1612+
1613+ return err;
1614+}
1615+
1616+int
1617+reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
1618+{
1619+ struct file *fp;
1620+ struct dentry *dir;
1621+ int err = 0;
1622+ struct reiserfs_chown_buf buf;
1623+ unsigned int ia_valid = attrs->ia_valid;
1624+
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))
1629+ {
1630+ return 0;
1631+ }
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);
1638+ goto out;
1639+ } else if (!dir->d_inode) {
1640+ dput (dir);
1641+ goto out;
1642+ }
1643+
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 */
1648+ goto out;
1649+ }
1650+
1651+ lock_kernel ();
1652+
1653+ attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
1654+ buf.xadir = dir;
1655+ buf.attrs = attrs;
1656+ buf.inode = inode;
1657+
1658+ err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf);
1659+ if (err) {
1660+ unlock_kernel ();
1661+ goto out_dir;
1662+ }
1663+
1664+ err = notify_change (dir, attrs);
1665+ unlock_kernel ();
1666+
1667+out_dir:
1668+ fput(fp);
1669+
1670+out:
1671+ attrs->ia_valid = ia_valid;
1672+ return err;
1673+}
1674+
1675+
1676+/* Actual operations that are exported to VFS-land */
1677+
1678+/*
1679+ * Inode operation getxattr()
1680+ * dentry->d_inode->i_sem down
1681+ * BKL held [before 2.5.x]
1682+ */
1683+ssize_t
1684+reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer,
1685+ size_t size)
1686+{
1687+ struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1688+ int err;
1689+
1690+ if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1691+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1692+ return -EOPNOTSUPP;
1693+
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);
1697+ return err;
1698+}
1699+
1700+
1701+/*
1702+ * Inode operation setxattr()
1703+ *
1704+ * dentry->d_inode->i_sem down
1705+ * BKL held [before 2.5.x]
1706+ */
1707+int
1708+reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value,
1709+ size_t size, int flags)
1710+{
1711+ struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1712+ int err;
1713+
1714+ if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1715+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1716+ return -EOPNOTSUPP;
1717+
1718+
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);
1722+ return err;
1723+}
1724+
1725+/*
1726+ * Inode operation removexattr()
1727+ *
1728+ * dentry->d_inode->i_sem down
1729+ * BKL held [before 2.5.x]
1730+ */
1731+int
1732+reiserfs_removexattr (struct dentry *dentry, const char *name)
1733+{
1734+ int err;
1735+ struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1736+
1737+ if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1738+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1739+ return -EOPNOTSUPP;
1740+
1741+ down (&dentry->d_inode->i_zombie);
1742+ reiserfs_read_lock_xattrs (dentry->d_sb);
1743+
1744+ /* Deletion pre-operation */
1745+ if (xah->del) {
1746+ err = xah->del (dentry->d_inode, name);
1747+ if (err) {
1748+ reiserfs_read_unlock_xattrs (dentry->d_sb);
1749+ up (&dentry->d_inode->i_zombie);
1750+ return err;
1751+ }
1752+ }
1753+
1754+ err = reiserfs_xattr_del (dentry->d_inode, name);
1755+ reiserfs_read_unlock_xattrs (dentry->d_sb);
1756+ up (&dentry->d_inode->i_zombie);
1757+ return err;
1758+}
1759+
1760+
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 {
1767+ int r_pos;
1768+ int r_size;
1769+ char *r_buf;
1770+ struct inode *r_inode;
1771+};
1772+
1773+static int
1774+reiserfs_listxattr_filler (void *buf, const char *name, int namelen,
1775+ loff_t offset, ino_t ino, unsigned int d_type)
1776+{
1777+ struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
1778+ int len = 0;
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 */
1782+
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);
1786+
1787+ if (len) {
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);
1791+ *p++ = '\0';
1792+ }
1793+ b->r_pos += len + 1;
1794+ }
1795+ }
1796+
1797+ return 0;
1798+}
1799+/*
1800+ * Inode operation listxattr()
1801+ *
1802+ * dentry->d_inode->i_sem down
1803+ * BKL held [before 2.5.x]
1804+ */
1805+ssize_t
1806+reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
1807+{
1808+ struct file *fp;
1809+ struct dentry *dir;
1810+ int err = 0;
1811+ struct reiserfs_listxattr_buf buf;
1812+
1813+ if (!dentry->d_inode)
1814+ return -EINVAL;
1815+
1816+ if (!reiserfs_xattrs(dentry->d_sb) ||
1817+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1818+ return -EOPNOTSUPP;
1819+
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 */
1827+ goto out;
1828+ }
1829+
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 */
1834+ goto out;
1835+ }
1836+
1837+ buf.r_buf = buffer;
1838+ buf.r_size = buffer ? size : 0;
1839+ buf.r_pos = 0;
1840+ buf.r_inode = dentry->d_inode;
1841+
1842+ err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf);
1843+ if (err)
1844+ goto out_dir;
1845+
1846+ if (buf.r_pos > buf.r_size && buffer != NULL)
1847+ err = -ERANGE;
1848+ else
1849+ err = buf.r_pos;
1850+
1851+out_dir:
1852+ fput(fp);
1853+
1854+out:
1855+ return err;
1856+}
1857+
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;
1861+
1862+static struct reiserfs_xattr_handler *
1863+find_xattr_handler_prefix (const char *prefix)
1864+{
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)
1869+ break;
1870+ read_unlock (&handler_lock);
1871+ return *xah;
1872+}
1873+
1874+int
1875+reiserfs_xattr_register_handler (struct reiserfs_xattr_handler *handler)
1876+{
1877+ int res = 0;
1878+ struct reiserfs_xattr_handler **xah;
1879+
1880+ if (!handler)
1881+ return -EINVAL;
1882+
1883+ if (handler->next)
1884+ return -EBUSY;
1885+
1886+ write_lock (&handler_lock);
1887+
1888+ for (xah = &xattr_handlers; *xah; xah=&(*xah)->next) {
1889+ if (strcmp ((*xah)->prefix, handler->prefix) == 0)
1890+ break;
1891+ }
1892+ if (*xah)
1893+ res = -EBUSY;
1894+ else
1895+ *xah = handler;
1896+
1897+ /*
1898+ if (!res)
1899+ printk ("ReiserFS: Registered xattr handler for %s\n", handler->prefix);
1900+ */
1901+
1902+ write_unlock (&handler_lock);
1903+ return res;
1904+}
1905+
1906+int
1907+reiserfs_xattr_unregister_handler (struct reiserfs_xattr_handler *handler)
1908+{
1909+ struct reiserfs_xattr_handler **xah;
1910+ write_lock (&handler_lock);
1911+
1912+ xah = &xattr_handlers;
1913+ while (*xah) {
1914+ if (handler == *xah) {
1915+ *xah = handler->next;
1916+ handler->next = NULL;
1917+ write_unlock (&handler_lock);
1918+ /*
1919+ printk ("ReiserFS: Unregistered xattr handler for %s\n",
1920+ handler->prefix);
1921+ */
1922+ return 0;
1923+ }
1924+ xah = &(*xah)->next;
1925+ }
1926+ write_unlock (&handler_lock);
1927+ return -EINVAL;
1928+}
1929+
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 */
1933+
1934+int
1935+reiserfs_xattr_init (struct super_block *s, int mount_flags)
1936+{
1937+ int err = 0;
1938+
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));
1944+ }
1945+
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));
1949+ }
1950+
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));
1956+ else
1957+ clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
1958+
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)) {
d871ed22 1963+ reiserfs_warning (s, "reiserfs: xattrs/ACLs not supported on pre v3.6 "
2416a217
JR
1964+ "format filesystem. Failing mount.\n");
1965+ err = -EOPNOTSUPP;
1966+ goto error;
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);
1977+ if (err) {
1978+ dput (dentry);
1979+ dentry = NULL;
1980+ }
1981+
1982+ if (dentry && dentry->d_inode)
d871ed22 1983+ reiserfs_warning (s, "reiserfs: Created %s on %s - reserved for "
2416a217
JR
1984+ "xattr storage.\n", PRIVROOT_NAME,
1985+ bdevname (inode->i_sb->s_dev));
1986+ }
1987+ } else
1988+ err = PTR_ERR (dentry);
1989+
1990+ if (!err) {
1991+ d_drop (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)) {
d871ed22 1999+ reiserfs_warning (s, "reiserfs: xattrs/ACLs enabled and couldn't "
2416a217
JR
2000+ "find/create .reiserfs_priv. Failing mount.\n");
2001+ err = -EOPNOTSUPP;
2002+ goto error;
2003+ }
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));
2009+ }
2010+ }
2011+ }
2012+
2013+error:
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. */
2016+
2017+ if (err) {
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));
2021+ }
2022+
2023+ s->s_flags = (s->s_flags & ~MS_POSIXACL) |
2024+ (reiserfs_posixacl (s) ? MS_POSIXACL : 0);
2025+ return err;
2026+}
2027diff -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
2030@@ -0,0 +1,653 @@
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>
2041+
2042+static int
2043+xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
2044+{
2045+ struct posix_acl *acl;
2046+ int error;
2047+
2048+ if (!reiserfs_posixacl(inode->i_sb))
2049+ return -EOPNOTSUPP;
2050+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
2051+ return -EPERM;
2052+
2053+ if (value) {
2054+ acl = posix_acl_from_xattr(value, size);
2055+ if (IS_ERR(acl)) {
2056+ return PTR_ERR(acl);
2057+ } else if (acl) {
2058+ error = posix_acl_valid(acl);
2059+ if (error)
2060+ goto release_and_out;
2061+ }
2062+ } else
2063+ acl = NULL;
2064+
2065+ error = reiserfs_set_acl (inode, type, acl);
2066+
2067+release_and_out:
2068+ posix_acl_release(acl);
2069+ return error;
2070+}
2071+
2072+
2073+static int
2074+xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
2075+{
2076+ struct posix_acl *acl;
2077+ int error;
2078+
2079+ if (!reiserfs_posixacl(inode->i_sb))
2080+ return -EOPNOTSUPP;
2081+
2082+ acl = reiserfs_get_acl (inode, type);
2083+ if (IS_ERR(acl))
2084+ return PTR_ERR(acl);
2085+ if (acl == NULL)
2086+ return -ENODATA;
2087+ error = posix_acl_to_xattr(acl, buffer, size);
2088+ posix_acl_release(acl);
2089+
2090+ return error;
2091+}
2092+
2093+
2094+/*
2095+ * Convert from filesystem to in-memory representation.
2096+ */
2097+static struct posix_acl *
2098+posix_acl_from_disk(const void *value, size_t size)
2099+{
2100+ const char *end = (char *)value + size;
2101+ int n, count;
2102+ struct posix_acl *acl;
2103+
2104+ if (!value)
2105+ return NULL;
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);
2113+ if (count < 0)
2114+ return ERR_PTR(-EINVAL);
2115+ if (count == 0)
2116+ return NULL;
2117+ acl = posix_acl_alloc(count, GFP_NOFS);
2118+ if (!acl)
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)
2124+ goto fail;
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:
2130+ case ACL_MASK:
2131+ case ACL_OTHER:
2132+ value = (char *)value +
2133+ sizeof(reiserfs_acl_entry_short);
2134+ acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
2135+ break;
2136+
2137+ case ACL_USER:
2138+ case ACL_GROUP:
2139+ value = (char *)value + sizeof(reiserfs_acl_entry);
2140+ if ((char *)value > end)
2141+ goto fail;
2142+ acl->a_entries[n].e_id =
2143+ le32_to_cpu(entry->e_id);
2144+ break;
2145+
2146+ default:
2147+ goto fail;
2148+ }
2149+ }
2150+ if (value != end)
2151+ goto fail;
2152+ return acl;
2153+
2154+fail:
2155+ posix_acl_release(acl);
2156+ return ERR_PTR(-EINVAL);
2157+}
2158+
2159+/*
2160+ * Convert from in-memory to filesystem representation.
2161+ */
2162+static void *
2163+posix_acl_to_disk(const struct posix_acl *acl, size_t *size)
2164+{
2165+ reiserfs_acl_header *ext_acl;
2166+ char *e;
2167+ int n;
2168+
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);
2172+ if (!ext_acl)
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) {
2181+ case ACL_USER:
2182+ case ACL_GROUP:
2183+ entry->e_id =
2184+ cpu_to_le32(acl->a_entries[n].e_id);
2185+ e += sizeof(reiserfs_acl_entry);
2186+ break;
2187+
2188+ case ACL_USER_OBJ:
2189+ case ACL_GROUP_OBJ:
2190+ case ACL_MASK:
2191+ case ACL_OTHER:
2192+ e += sizeof(reiserfs_acl_entry_short);
2193+ break;
2194+
2195+ default:
2196+ goto fail;
2197+ }
2198+ }
2199+ return (char *)ext_acl;
2200+
2201+fail:
2202+ kfree(ext_acl);
2203+ return ERR_PTR(-EINVAL);
2204+}
2205+
2206+/*
2207+ * Inode operation get_posix_acl().
2208+ *
2209+ * inode->i_sem: down
2210+ * BKL held [before 2.5.x]
2211+ */
2212+struct posix_acl *
2213+reiserfs_get_acl(struct inode *inode, int type)
2214+{
2215+ char *name, *value;
2216+ struct posix_acl *acl, **p_acl;
2217+ size_t size;
2218+ int retval;
2219+
2220+ switch (type) {
2221+ case ACL_TYPE_ACCESS:
2222+ name = XATTR_NAME_ACL_ACCESS;
2223+ p_acl = &inode->u.reiserfs_i.i_acl_access;
2224+ break;
2225+ case ACL_TYPE_DEFAULT:
2226+ name = XATTR_NAME_ACL_DEFAULT;
2227+ p_acl = &inode->u.reiserfs_i.i_acl_default;
2228+ break;
2229+ default:
2230+ return ERR_PTR (-EINVAL);
2231+ }
2232+
2233+ if (IS_ERR (*p_acl)) {
2234+ if (PTR_ERR (*p_acl) == -ENODATA)
2235+ return NULL;
2236+ } else if (*p_acl != NULL)
2237+ return posix_acl_dup (*p_acl);
2238+
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);
2243+ return NULL;
2244+ }
2245+ return ERR_PTR (size);
2246+ }
2247+
2248+ value = kmalloc (size, GFP_NOFS);
2249+ if (!value)
2250+ return ERR_PTR (-ENOMEM);
2251+
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 */
2256+ acl = NULL;
2257+ *p_acl = ERR_PTR (-ENODATA);
2258+ } else if (retval < 0) {
2259+ acl = ERR_PTR(retval);
2260+ } else {
2261+ acl = posix_acl_from_disk(value, retval);
2262+ *p_acl = posix_acl_dup (acl);
2263+ }
2264+
2265+ kfree(value);
2266+ return acl;
2267+}
2268+
2269+/*
2270+ * Inode operation set_posix_acl().
2271+ *
2272+ * inode->i_sem: down
2273+ * BKL held [before 2.5.x]
2274+ */
2275+int
2276+reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
2277+{
2278+ char *name;
2279+ void *value = NULL;
2280+ struct posix_acl **p_acl;
2281+ size_t size;
2282+ int error;
2283+
2284+ if (S_ISLNK(inode->i_mode))
2285+ return -EOPNOTSUPP;
2286+
2287+
2288+ switch (type) {
2289+ case ACL_TYPE_ACCESS:
2290+ name = XATTR_NAME_ACL_ACCESS;
2291+ p_acl = &inode->u.reiserfs_i.i_acl_access;
2292+ if (acl) {
2293+ mode_t mode = inode->i_mode;
2294+ error = posix_acl_equiv_mode (acl, &mode);
2295+ if (error < 0)
2296+ return error;
2297+ else {
2298+ inode->i_mode = mode;
2299+ if (error == 0)
2300+ acl = NULL;
2301+ }
2302+ }
2303+ break;
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;
2309+ break;
2310+ default:
2311+ return -EINVAL;
2312+ }
2313+
2314+ if (acl) {
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);
2319+ } else {
2320+ error = reiserfs_xattr_del (inode, name);
2321+ if (error == -ENODATA)
2322+ error = 0;
2323+ }
2324+
2325+ if (value)
2326+ kfree(value);
2327+
2328+ if (!error) {
2329+ /* Release the old one */
2330+ if (!IS_ERR (*p_acl) && *p_acl)
2331+ posix_acl_release (*p_acl);
2332+
2333+ if (acl == NULL)
2334+ *p_acl = ERR_PTR (-ENODATA);
2335+ else
2336+ *p_acl = posix_acl_dup (acl);
2337+ }
2338+
2339+ return error;
2340+}
2341+
2342+/* dir->i_sem: down,
2343+ * inode is new and not released into the wild yet */
2344+int
2345+reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode)
2346+{
2347+ struct posix_acl *acl;
2348+ int err = 0;
2349+
2350+ /* ACLs only get applied to files and directories */
2351+ if (S_ISLNK (inode->i_mode))
2352+ return 0;
2353+
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)
2357+ goto apply_umask;
2358+
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;
2364+ goto apply_umask;
2365+ }
2366+
2367+ acl = reiserfs_get_acl (dir, ACL_TYPE_DEFAULT);
2368+ if (IS_ERR (acl)) {
2369+ if (PTR_ERR (acl) == -ENODATA)
2370+ goto apply_umask;
2371+ return PTR_ERR (acl);
2372+ }
2373+
2374+ if (acl) {
2375+ struct posix_acl *acl_copy;
2376+ mode_t mode = inode->i_mode;
2377+ int need_acl;
2378+
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);
2382+ if (err)
2383+ goto cleanup;
2384+ }
2385+
2386+ /* Now we reconcile the new ACL and the mode,
2387+ potentially modifying both */
2388+ acl_copy = posix_acl_clone (acl, GFP_NOFS);
2389+ if (!acl_copy) {
2390+ err = -ENOMEM;
2391+ goto cleanup;
2392+ }
2393+
2394+
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;
2399+ }
2400+
2401+ /* If we need an ACL.. */
2402+ if (need_acl > 0) {
2403+ err = reiserfs_set_acl (inode, ACL_TYPE_ACCESS, acl_copy);
2404+ if (err)
2405+ goto cleanup_copy;
2406+ }
2407+ }
2408+cleanup_copy:
2409+ posix_acl_release (acl_copy);
2410+cleanup:
2411+ posix_acl_release (acl);
2412+ } else {
2413+apply_umask:
2414+ /* no ACL, apply umask */
2415+ inode->i_mode &= ~current->fs->umask;
2416+ }
2417+
2418+ return err;
2419+}
2420+
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 */
2424+int
2425+reiserfs_cache_default_acl (struct inode *inode)
2426+{
2427+ int ret = 0;
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);
2436+ }
2437+
2438+ return ret;
2439+}
2440+
2441+static int
2442+__reiserfs_permission (struct inode *inode, int mask, int need_lock)
2443+{
2444+ int mode = inode->i_mode;
2445+
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)))
2449+ return -EROFS;
2450+
2451+ /* Nobody gets write access to an immutable file */
2452+ if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
2453+ return -EACCES;
2454+
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))
2458+ return 0;
2459+
2460+ if (current->fsuid == inode->i_uid) {
2461+ mode >>= 6;
2462+ } else if (reiserfs_posixacl(inode->i_sb) &&
2463+ get_inode_sd_version (inode) != STAT_DATA_V1) {
2464+ struct posix_acl *acl;
2465+
2466+ /* ACL can't contain additional permissions if
2467+ the ACL_MASK entry is 0 */
2468+ if (!(mode & S_IRWXG))
2469+ goto check_groups;
2470+
2471+ if (need_lock)
2472+ reiserfs_read_lock_xattrs (inode->i_sb);
2473+ acl = reiserfs_get_acl (inode, ACL_TYPE_ACCESS);
2474+ if (need_lock)
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);
2480+ }
2481+
2482+ if (acl) {
2483+ int err = posix_acl_permission (inode, acl, mask);
2484+ posix_acl_release (acl);
2485+ if (err == -EACCES) {
2486+ goto check_capabilities;
2487+ }
2488+ return err;
2489+ } else {
2490+ goto check_groups;
2491+ }
2492+
2493+ } else {
2494+check_groups:
2495+ if (in_group_p(inode->i_gid))
2496+ mode >>= 3;
2497+ }
2498+ if ((mode & mask & S_IRWXO) == mask)
2499+ return 0;
2500+
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))
2505+ return 0;
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))))
2509+ return 0;
2510+ return -EACCES;
2511+}
2512+
2513+int
2514+reiserfs_permission (struct inode *inode, int mask)
2515+{
2516+ return __reiserfs_permission (inode, mask, 1);
2517+}
2518+
2519+int
2520+reiserfs_permission_locked (struct inode *inode, int mask)
2521+{
2522+ return __reiserfs_permission (inode, mask, 0);
2523+}
2524+
2525+int
2526+reiserfs_acl_chmod (struct inode *inode)
2527+{
2528+ struct posix_acl *acl, *clone;
2529+ int error;
2530+
2531+ if (S_ISLNK(inode->i_mode))
2532+ return -EOPNOTSUPP;
2533+
2534+ if (get_inode_sd_version (inode) == STAT_DATA_V1 ||
2535+ !reiserfs_posixacl(inode->i_sb))
2536+ {
2537+ return 0;
2538+ }
2539+
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);
2543+ if (!acl)
2544+ return 0;
2545+ if (IS_ERR(acl))
2546+ return PTR_ERR(acl);
2547+ clone = posix_acl_clone(acl, GFP_NOFS);
2548+ posix_acl_release(acl);
2549+ if (!clone)
2550+ return -ENOMEM;
2551+ error = posix_acl_chmod_masq(clone, inode->i_mode);
2552+ if (!error) {
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);
2556+ }
2557+ posix_acl_release(clone);
2558+ return error;
2559+}
2560+
2561+static int
2562+posix_acl_access_get(struct inode *inode, const char *name,
2563+ void *buffer, size_t size)
2564+{
2565+ if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
2566+ return -EINVAL;
2567+ return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
2568+}
2569+
2570+static int
2571+posix_acl_access_set(struct inode *inode, const char *name,
2572+ const void *value, size_t size, int flags)
2573+{
2574+ if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
2575+ return -EINVAL;
2576+ return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
2577+}
2578+
2579+static int
2580+posix_acl_access_del (struct inode *inode, const char *name)
2581+{
2582+ struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_access;
2583+ if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
2584+ return -EINVAL;
2585+ if (!IS_ERR (*acl) && *acl) {
2586+ posix_acl_release (*acl);
2587+ *acl = ERR_PTR (-ENODATA);
2588+ }
2589+
2590+ return 0;
2591+}
2592+
2593+static int
2594+posix_acl_access_list (struct inode *inode, const char *name, int namelen, char *out)
2595+{
2596+ int len = namelen;
2597+ if (!reiserfs_posixacl (inode->i_sb))
2598+ return 0;
2599+ if (out)
2600+ memcpy (out, name, len);
2601+
2602+ return len;
2603+}
2604+
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,
2611+};
2612+
2613+static int
2614+posix_acl_default_get (struct inode *inode, const char *name,
2615+ void *buffer, size_t size)
2616+{
2617+ if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
2618+ return -EINVAL;
2619+ return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
2620+}
2621+
2622+static int
2623+posix_acl_default_set(struct inode *inode, const char *name,
2624+ const void *value, size_t size, int flags)
2625+{
2626+ if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
2627+ return -EINVAL;
2628+ return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
2629+}
2630+
2631+static int
2632+posix_acl_default_del (struct inode *inode, const char *name)
2633+{
2634+ struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_default;
2635+ if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
2636+ return -EINVAL;
2637+ if (!IS_ERR (*acl) && *acl) {
2638+ posix_acl_release (*acl);
2639+ *acl = ERR_PTR (-ENODATA);
2640+ }
2641+
2642+ return 0;
2643+}
2644+
2645+static int
2646+posix_acl_default_list (struct inode *inode, const char *name, int namelen, char *out)
2647+{
2648+ int len = namelen;
2649+ if (!reiserfs_posixacl (inode->i_sb))
2650+ return 0;
2651+ if (out)
2652+ memcpy (out, name, len);
2653+
2654+ return len;
2655+}
2656+
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,
2663+};
2664+
2665+int __init
2666+reiserfs_xattr_posix_acl_init (void)
2667+{
2668+ int err;
2669+ err = reiserfs_xattr_register_handler (&posix_acl_access_handler);
2670+ if (!err)
2671+ err = reiserfs_xattr_register_handler (&posix_acl_default_handler);
2672+ return err;
2673+}
2674+
2675+int
2676+reiserfs_xattr_posix_acl_exit (void)
2677+{
2678+ int err;
2679+ err = reiserfs_xattr_unregister_handler (&posix_acl_access_handler);
2680+ if (!err)
2681+ err = reiserfs_xattr_unregister_handler (&posix_acl_default_handler);
2682+ return err;
2683+}
2684diff -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
2687@@ -0,0 +1,97 @@
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>
2695+
2696+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
2697+# include <linux/reiserfs_acl.h>
2698+#endif
2699+
2700+#define XATTR_TRUSTED_PREFIX "trusted."
2701+
2702+static int
2703+trusted_get (struct inode *inode, const char *name, void *buffer, size_t size)
2704+{
2705+ if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
2706+ return -EINVAL;
2707+
2708+ if (!reiserfs_xattrs_trusted (inode->i_sb))
2709+ return -EOPNOTSUPP;
2710+
2711+ if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2712+ return -EPERM;
2713+
2714+ return reiserfs_xattr_get (inode, name, buffer, size);
2715+}
2716+
2717+static int
2718+trusted_set (struct inode *inode, const char *name, const void *buffer,
2719+ size_t size, int flags)
2720+{
2721+ if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
2722+ return -EINVAL;
2723+
2724+ if (!reiserfs_xattrs_trusted (inode->i_sb))
2725+ return -EOPNOTSUPP;
2726+
2727+ if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2728+ return -EPERM;
2729+
2730+ return reiserfs_xattr_set (inode, name, buffer, size, flags);
2731+}
2732+
2733+static int
2734+trusted_del (struct inode *inode, const char *name)
2735+{
2736+ if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
2737+ return -EINVAL;
2738+
2739+ if (!reiserfs_xattrs_trusted (inode->i_sb))
2740+ return -EOPNOTSUPP;
2741+
2742+ if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2743+ return -EPERM;
2744+
2745+ return 0;
2746+}
2747+
2748+static int
2749+trusted_list (struct inode *inode, const char *name, int namelen, char *out)
2750+{
2751+ int len = namelen;
2752+
2753+ if (!reiserfs_xattrs_trusted (inode->i_sb))
2754+ return 0;
2755+
2756+ if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
2757+ return 0;
2758+
2759+ if (out)
2760+ memcpy (out, name, len);
2761+
2762+ return len;
2763+}
2764+
2765+
2766+struct reiserfs_xattr_handler trusted_handler = {
2767+ prefix: XATTR_TRUSTED_PREFIX,
2768+ get: trusted_get,
2769+ set: trusted_set,
2770+ del: trusted_del,
2771+ list: trusted_list,
2772+};
2773+
2774+int __init
2775+reiserfs_xattr_trusted_init (void)
2776+{
2777+ return reiserfs_xattr_register_handler (&trusted_handler);
2778+}
2779+
2780+int
2781+reiserfs_xattr_trusted_exit (void)
2782+{
2783+ return reiserfs_xattr_unregister_handler (&trusted_handler);
2784+}
2785diff -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
2788@@ -0,0 +1,112 @@
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>
2796+
2797+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
2798+# include <linux/reiserfs_acl.h>
2799+#endif
2800+
2801+#define XATTR_USER_PREFIX "user."
2802+
2803+static int
2804+user_get (struct inode *inode, const char *name, void *buffer, size_t size)
2805+{
2806+
2807+ int error;
2808+
2809+ if (strlen(name) < sizeof(XATTR_USER_PREFIX))
2810+ return -EINVAL;
2811+
2812+ if (!reiserfs_xattrs_user (inode->i_sb))
2813+ return -EOPNOTSUPP;
2814+
2815+ error = reiserfs_permission_locked (inode, MAY_READ);
2816+ if (error)
2817+ return error;
2818+
2819+ return reiserfs_xattr_get (inode, name, buffer, size);
2820+}
2821+
2822+static int
2823+user_set (struct inode *inode, const char *name, const void *buffer,
2824+ size_t size, int flags)
2825+{
2826+
2827+ int error;
2828+
2829+ if (strlen(name) < sizeof(XATTR_USER_PREFIX))
2830+ return -EINVAL;
2831+
2832+ if (!reiserfs_xattrs_user (inode->i_sb))
2833+ return -EOPNOTSUPP;
2834+
2835+ if (!S_ISREG (inode->i_mode) &&
2836+ (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
2837+ return -EPERM;
2838+
2839+ error = reiserfs_permission_locked (inode, MAY_WRITE);
2840+ if (error)
2841+ return error;
2842+
2843+ return reiserfs_xattr_set (inode, name, buffer, size, flags);
2844+}
2845+
2846+static int
2847+user_del (struct inode *inode, const char *name)
2848+{
2849+ int error;
2850+
2851+ if (strlen(name) < sizeof(XATTR_USER_PREFIX))
2852+ return -EINVAL;
2853+
2854+ if (!reiserfs_xattrs_user (inode->i_sb))
2855+ return -EOPNOTSUPP;
2856+
2857+ if (!S_ISREG (inode->i_mode) &&
2858+ (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
2859+ return -EPERM;
2860+
2861+ error = reiserfs_permission_locked (inode, MAY_WRITE);
2862+ if (error)
2863+ return error;
2864+
2865+ return 0;
2866+}
2867+
2868+static int
2869+user_list (struct inode *inode, const char *name, int namelen, char *out)
2870+{
2871+ int len = namelen;
2872+ if (!reiserfs_xattrs_user (inode->i_sb))
2873+ return 0;
2874+
2875+ if (out)
2876+ memcpy (out, name, len);
2877+
2878+ return len;
2879+}
2880+
2881+
2882+struct reiserfs_xattr_handler user_handler = {
2883+ prefix: XATTR_USER_PREFIX,
2884+ get: user_get,
2885+ set: user_set,
2886+ del: user_del,
2887+ list: user_list,
2888+};
2889+
2890+int __init
2891+reiserfs_xattr_user_init (void)
2892+{
2893+ return reiserfs_xattr_register_handler (&user_handler);
2894+}
2895+
2896+int
2897+reiserfs_xattr_user_exit (void)
2898+{
2899+ return reiserfs_xattr_unregister_handler (&user_handler);
2900+}
2901diff -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
2904@@ -0,0 +1,92 @@
2905+#include <linux/init.h>
2906+#include <linux/posix_acl.h>
2907+#include <linux/xattr_acl.h>
2908+
2909+#define REISERFS_ACL_VERSION 0x0001
2910+
2911+typedef struct {
2912+ __u16 e_tag;
2913+ __u16 e_perm;
2914+ __u32 e_id;
2915+} reiserfs_acl_entry;
2916+
2917+typedef struct {
2918+ __u16 e_tag;
2919+ __u16 e_perm;
2920+} reiserfs_acl_entry_short;
2921+
2922+typedef struct {
2923+ __u32 a_version;
2924+} reiserfs_acl_header;
2925+
2926+static inline size_t reiserfs_acl_size(int count)
2927+{
2928+ if (count <= 4) {
2929+ return sizeof(reiserfs_acl_header) +
2930+ count * sizeof(reiserfs_acl_entry_short);
2931+ } else {
2932+ return sizeof(reiserfs_acl_header) +
2933+ 4 * sizeof(reiserfs_acl_entry_short) +
2934+ (count - 4) * sizeof(reiserfs_acl_entry);
2935+ }
2936+}
2937+
2938+static inline int reiserfs_acl_count(size_t size)
2939+{
2940+ ssize_t s;
2941+ size -= sizeof(reiserfs_acl_header);
2942+ s = size - 4 * sizeof(reiserfs_acl_entry_short);
2943+ if (s < 0) {
2944+ if (size % sizeof(reiserfs_acl_entry_short))
2945+ return -1;
2946+ return size / sizeof(reiserfs_acl_entry_short);
2947+ } else {
2948+ if (s % sizeof(reiserfs_acl_entry))
2949+ return -1;
2950+ return s / sizeof(reiserfs_acl_entry) + 4;
2951+ }
2952+}
2953+
2954+
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);
2965+#else
2966+
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
2971+
2972+static inline int
2973+reiserfs_xattr_posix_acl_init (void)
2974+{
2975+ return 0;
2976+}
2977+
2978+static inline int
2979+reiserfs_xattr_posix_acl_exit (void)
2980+{
2981+ return 0;
2982+}
2983+
2984+static inline int
2985+reiserfs_acl_chmod (struct inode *inode)
2986+{
2987+ return 0;
2988+}
2989+
2990+static inline int
2991+reiserfs_inherit_default_acl (const struct inode *dir, struct dentry *dentry, struct inode *inode)
2992+{
2993+ return 0;
2994+}
2995+
2996+#endif
2997diff -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 @@
3001
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);
3005
3006 /* namei.c */
3007 inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
3008@@ -1969,6 +1970,7 @@
3009
3010 /* dir.c */
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;
3014
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
3019
3020+/* xattr stuff */
3021+#define REISERFS_XATTR_DIR_SEM(s) ((s)->u.reiserfs_sb.xattr_dir_sem)
3022+
3023 #endif /* _LINUX_REISER_FS_H */
3024
3025
3026diff -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
3029@@ -23,7 +23,8 @@
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;
3037
3038
3039@@ -60,6 +61,9 @@
3040 */
3041 unsigned long i_tail_trans_id;
3042 unsigned long i_tail_trans_index;
3043+
3044+ struct posix_acl *i_acl_access;
3045+ struct posix_acl *i_acl_default;
3046 };
3047
3048 #endif
3049diff -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
3052@@ -6,6 +6,7 @@
3053
3054 #ifdef __KERNEL__
3055 #include <linux/tqueue.h>
3056+#include <linux/rwsem.h>
3057 #endif
3058
3059 //
3060@@ -171,13 +172,17 @@
3061 ** transaction handle which is passed around for all journal calls
3062 */
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
3071+ */
3072+ int t_refcount;
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 */
3081 } ;
3082@@ -413,6 +418,9 @@
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;
3089 };
3090
3091 /* Definitions of reiserfs on-disk properties: */
3092@@ -459,6 +467,12 @@
3093 #define REISERFS_TEST4 14
3094
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
3101+
3102
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)
3115+#else
3116+/* If trusted xattrs are compiled in, they're "always on." */
3117+# define reiserfs_xattrs(s) (1)
3118+# define reiserfs_xattrs_trusted(s) (1)
3119+#endif
3120
3121
3122 void reiserfs_file_buffer (struct buffer_head * bh, int list);
3123diff -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
3126@@ -0,0 +1,132 @@
3127+/*
3128+ File: linux/reiserfs_xattr.h
3129+*/
3130+
3131+#include <linux/config.h>
3132+#include <linux/init.h>
3133+#include <linux/xattr.h>
3134+
3135+/* Magic value in header */
3136+#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
3137+
3138+struct reiserfs_xattr_header {
3139+ __u32 h_magic; /* magic number for identification */
3140+ __u32 h_hash; /* hash of the value */
3141+};
3142+
3143+#ifdef __KERNEL__
3144+
3145+struct reiserfs_xattr_handler {
3146+ char *prefix;
3147+ int (*get)(struct inode *inode, const char *name, void *buffer,
3148+ size_t size);
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;
3154+};
3155+
3156+
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);
3168+
3169+static inline void
3170+reiserfs_write_lock_xattrs(struct super_block *sb)
3171+{
3172+ down_write (&REISERFS_XATTR_DIR_SEM(sb));
3173+}
3174+static inline void
3175+reiserfs_write_unlock_xattrs(struct super_block *sb)
3176+{
3177+ up_write (&REISERFS_XATTR_DIR_SEM(sb));
3178+}
3179+static inline void
3180+reiserfs_read_lock_xattrs(struct super_block *sb)
3181+{
3182+ down_read (&REISERFS_XATTR_DIR_SEM(sb));
3183+}
3184+static inline void
3185+reiserfs_read_unlock_xattrs(struct super_block *sb)
3186+{
3187+ up_read (&REISERFS_XATTR_DIR_SEM(sb));
3188+}
3189+#else
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)
3199+static inline int
3200+reiserfs_xattr_init (struct super_block *s, int mount_flags)
3201+{
3202+ s->s_flags = (s->s_flags & ~MS_POSIXACL); /* to be sure */
3203+ return 0;
3204+}
3205+
3206+static inline int
3207+reiserfs_delete_xattrs (struct inode *inode)
3208+{
3209+ return 0;
3210+}
3211+
3212+static inline int
3213+reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
3214+{
3215+ return 0;
3216+}
3217+#endif
3218+
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 *,
3224+ size_t, int);
3225+#ifdef CONFIG_REISERFS_FS_XATTR_USER
3226+extern int reiserfs_xattr_user_init (void) __init;
3227+extern int reiserfs_xattr_user_exit (void);
3228+#else
3229+static inline int
3230+reiserfs_xattr_user_init (void)
3231+{
3232+ return 0;
3233+}
3234+
3235+static inline int
3236+reiserfs_xattr_user_exit (void)
3237+{
3238+ return 0;
3239+}
3240+#endif
3241+#ifdef CONFIG_REISERFS_FS_XATTR_TRUSTED
3242+extern int reiserfs_xattr_trusted_init (void) __init;
3243+extern int reiserfs_xattr_trusted_exit (void);
3244+#else
3245+static inline int
3246+reiserfs_xattr_trusted_init (void)
3247+{
3248+ return 0;
3249+}
3250+
3251+static inline int
3252+reiserfs_xattr_trusted_exit (void)
3253+{
3254+ return 0;
3255+}
3256+#endif
3257+
3258+#endif /* __KERNEL__ */
This page took 0.549804 seconds and 4 git commands to generate.