]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.22-acl+xattr.patch
- obsolete
[packages/kernel.git] / linux-2.4.22-acl+xattr.patch
1 diff -urN linux-2.4.22.org/arch/alpha/defconfig linux-2.4.22/arch/alpha/defconfig
2 --- linux-2.4.22.org/arch/alpha/defconfig       2003-11-21 15:04:31.000000000 +0100
3 +++ linux-2.4.22/arch/alpha/defconfig   2003-11-21 15:26:23.000000000 +0100
4 @@ -554,6 +554,10 @@
5  # CONFIG_AUTOFS4_FS is not set
6  CONFIG_REISERFS_FS=m
7  # CONFIG_REISERFS_CHECK is not set
8 +# CONFIG_REISERFS_FS_XATTR is not set
9 +# CONFIG_REISERFS_FS_XATTR_USER is not set
10 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
11 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
12  # CONFIG_ADFS_FS is not set
13  # CONFIG_ADFS_FS_RW is not set
14  # CONFIG_AFFS_FS is not set
15 diff -urN linux-2.4.22.org/arch/i386/config.in linux-2.4.22/arch/i386/config.in
16 --- linux-2.4.22.org/arch/i386/config.in        2003-11-21 15:04:28.000000000 +0100
17 +++ linux-2.4.22/arch/i386/config.in    2003-11-21 15:26:23.000000000 +0100
18 @@ -74,6 +74,7 @@
19     define_bool CONFIG_X86_F00F_WORKS_OK n
20  fi
21  if [ "$CONFIG_M586" = "y" ]; then
22 +   define_bool CONFIG_X86_CMPXCHG8 y
23     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
24     define_bool CONFIG_X86_USE_STRING_486 y
25     define_bool CONFIG_X86_ALIGNMENT_16 y
26 @@ -81,6 +82,7 @@
27     define_bool CONFIG_X86_F00F_WORKS_OK n
28  fi
29  if [ "$CONFIG_M586TSC" = "y" ]; then
30 +   define_bool CONFIG_X86_CMPXCHG8 y
31     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
32     define_bool CONFIG_X86_USE_STRING_486 y
33     define_bool CONFIG_X86_ALIGNMENT_16 y
34 @@ -89,6 +91,7 @@
35     define_bool CONFIG_X86_F00F_WORKS_OK n
36  fi
37  if [ "$CONFIG_M586MMX" = "y" ]; then
38 +   define_bool CONFIG_X86_CMPXCHG8 y
39     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
40     define_bool CONFIG_X86_USE_STRING_486 y
41     define_bool CONFIG_X86_ALIGNMENT_16 y
42 @@ -98,6 +101,7 @@
43     define_bool CONFIG_X86_F00F_WORKS_OK n
44  fi
45  if [ "$CONFIG_M686" = "y" ]; then
46 +   define_bool CONFIG_X86_CMPXCHG8 y
47     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
48     define_bool CONFIG_X86_HAS_TSC y
49     define_bool CONFIG_X86_GOOD_APIC y
50 @@ -107,6 +111,7 @@
51     define_bool CONFIG_X86_F00F_WORKS_OK y
52  fi
53  if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
54 +   define_bool CONFIG_X86_CMPXCHG8 y
55     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
56     define_bool CONFIG_X86_HAS_TSC y
57     define_bool CONFIG_X86_GOOD_APIC y
58 @@ -115,6 +120,7 @@
59     define_bool CONFIG_X86_F00F_WORKS_OK y
60  fi
61  if [ "$CONFIG_MPENTIUM4" = "y" ]; then
62 +   define_bool CONFIG_X86_CMPXCHG8 y
63     define_int  CONFIG_X86_L1_CACHE_SHIFT 7
64     define_bool CONFIG_X86_HAS_TSC y
65     define_bool CONFIG_X86_GOOD_APIC y
66 @@ -123,6 +129,7 @@
67     define_bool CONFIG_X86_F00F_WORKS_OK y
68  fi
69  if [ "$CONFIG_MK6" = "y" ]; then
70 +   define_bool CONFIG_X86_CMPXCHG8 y
71     define_int  CONFIG_X86_L1_CACHE_SHIFT 5
72     define_bool CONFIG_X86_ALIGNMENT_16 y
73     define_bool CONFIG_X86_HAS_TSC y
74 @@ -134,6 +141,7 @@
75     define_bool CONFIG_MK7 y
76  fi
77  if [ "$CONFIG_MK7" = "y" ]; then
78 +   define_bool CONFIG_X86_CMPXCHG8 y
79     define_int  CONFIG_X86_L1_CACHE_SHIFT 6
80     define_bool CONFIG_X86_HAS_TSC y
81     define_bool CONFIG_X86_GOOD_APIC y
82 diff -urN linux-2.4.22.org/arch/ia64/defconfig linux-2.4.22/arch/ia64/defconfig
83 --- linux-2.4.22.org/arch/ia64/defconfig        2003-11-21 15:04:31.000000000 +0100
84 +++ linux-2.4.22/arch/ia64/defconfig    2003-11-21 15:26:23.000000000 +0100
85 @@ -684,6 +684,10 @@
86  # CONFIG_REISERFS_FS is not set
87  # CONFIG_REISERFS_CHECK is not set
88  # CONFIG_REISERFS_PROC_INFO is not set
89 +# CONFIG_REISERFS_FS_XATTR is not set
90 +# CONFIG_REISERFS_FS_XATTR_USER is not set
91 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
92 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
93  # CONFIG_ADFS_FS is not set
94  # CONFIG_ADFS_FS_RW is not set
95  # CONFIG_AFFS_FS is not set
96 diff -urN linux-2.4.22.org/arch/mips/defconfig linux-2.4.22/arch/mips/defconfig
97 --- linux-2.4.22.org/arch/mips/defconfig        2003-11-21 15:04:30.000000000 +0100
98 +++ linux-2.4.22/arch/mips/defconfig    2003-11-21 15:26:23.000000000 +0100
99 @@ -524,6 +524,10 @@
100  # CONFIG_REISERFS_FS is not set
101  # CONFIG_REISERFS_CHECK is not set
102  # CONFIG_REISERFS_PROC_INFO is not set
103 +# CONFIG_REISERFS_FS_XATTR is not set
104 +# CONFIG_REISERFS_FS_XATTR_USER is not set
105 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
106 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
107  # CONFIG_ADFS_FS is not set
108  # CONFIG_ADFS_FS_RW is not set
109  # CONFIG_AFFS_FS is not set
110 diff -urN linux-2.4.22.org/arch/mips64/defconfig linux-2.4.22/arch/mips64/defconfig
111 --- linux-2.4.22.org/arch/mips64/defconfig      2003-11-21 15:04:30.000000000 +0100
112 +++ linux-2.4.22/arch/mips64/defconfig  2003-11-21 15:26:23.000000000 +0100
113 @@ -489,6 +489,10 @@
114  # CONFIG_REISERFS_FS is not set
115  # CONFIG_REISERFS_CHECK is not set
116  # CONFIG_REISERFS_PROC_INFO is not set
117 +# CONFIG_REISERFS_FS_XATTR is not set
118 +# CONFIG_REISERFS_FS_XATTR_USER is not set
119 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
120 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
121  # CONFIG_ADFS_FS is not set
122  # CONFIG_ADFS_FS_RW is not set
123  # CONFIG_AFFS_FS is not set
124 diff -urN linux-2.4.22.org/arch/ppc/defconfig linux-2.4.22/arch/ppc/defconfig
125 --- linux-2.4.22.org/arch/ppc/defconfig 2003-11-21 15:04:31.000000000 +0100
126 +++ linux-2.4.22/arch/ppc/defconfig     2003-11-21 15:26:23.000000000 +0100
127 @@ -766,6 +766,10 @@
128  # CONFIG_REISERFS_FS is not set
129  # CONFIG_REISERFS_CHECK is not set
130  # CONFIG_REISERFS_PROC_INFO is not set
131 +# CONFIG_REISERFS_FS_XATTR is not set
132 +# CONFIG_REISERFS_FS_XATTR_USER is not set
133 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
134 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
135  # CONFIG_ADFS_FS is not set
136  # CONFIG_ADFS_FS_RW is not set
137  # CONFIG_AFFS_FS is not set
138 diff -urN linux-2.4.22.org/arch/ppc64/defconfig linux-2.4.22/arch/ppc64/defconfig
139 --- linux-2.4.22.org/arch/ppc64/defconfig       2003-11-21 15:04:30.000000000 +0100
140 +++ linux-2.4.22/arch/ppc64/defconfig   2003-11-21 15:26:23.000000000 +0100
141 @@ -593,6 +593,10 @@
142  CONFIG_REISERFS_FS=y
143  # CONFIG_REISERFS_CHECK is not set
144  # CONFIG_REISERFS_PROC_INFO is not set
145 +# CONFIG_REISERFS_FS_XATTR is not set
146 +# CONFIG_REISERFS_FS_XATTR_USER is not set
147 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
148 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
149  # CONFIG_ADFS_FS is not set
150  # CONFIG_ADFS_FS_RW is not set
151  # CONFIG_AFFS_FS is not set
152 diff -urN linux-2.4.22.org/arch/s390/defconfig linux-2.4.22/arch/s390/defconfig
153 --- linux-2.4.22.org/arch/s390/defconfig        2003-11-21 15:04:31.000000000 +0100
154 +++ linux-2.4.22/arch/s390/defconfig    2003-11-21 15:26:23.000000000 +0100
155 @@ -282,6 +282,10 @@
156  # CONFIG_REISERFS_FS is not set
157  # CONFIG_REISERFS_CHECK is not set
158  # CONFIG_REISERFS_PROC_INFO is not set
159 +# CONFIG_REISERFS_FS_XATTR is not set
160 +# CONFIG_REISERFS_FS_XATTR_USER is not set
161 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
162 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
163  # CONFIG_ADFS_FS is not set
164  # CONFIG_ADFS_FS_RW is not set
165  # CONFIG_AFFS_FS is not set
166 diff -urN linux-2.4.22.org/arch/s390x/defconfig linux-2.4.22/arch/s390x/defconfig
167 --- linux-2.4.22.org/arch/s390x/defconfig       2003-11-21 15:04:30.000000000 +0100
168 +++ linux-2.4.22/arch/s390x/defconfig   2003-11-21 15:26:23.000000000 +0100
169 @@ -224,6 +224,10 @@
170  # CONFIG_REISERFS_FS is not set
171  # CONFIG_REISERFS_CHECK is not set
172  # CONFIG_REISERFS_PROC_INFO is not set
173 +# CONFIG_REISERFS_FS_XATTR is not set
174 +# CONFIG_REISERFS_FS_XATTR_USER is not set
175 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
176 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
177  # CONFIG_ADFS_FS is not set
178  # CONFIG_ADFS_FS_RW is not set
179  # CONFIG_AFFS_FS is not set
180 diff -urN linux-2.4.22.org/arch/sparc/defconfig linux-2.4.22/arch/sparc/defconfig
181 --- linux-2.4.22.org/arch/sparc/defconfig       2003-11-21 15:04:30.000000000 +0100
182 +++ linux-2.4.22/arch/sparc/defconfig   2003-11-21 15:26:23.000000000 +0100
183 @@ -294,6 +294,10 @@
184  # CONFIG_REISERFS_FS is not set
185  # CONFIG_REISERFS_CHECK is not set
186  # CONFIG_REISERFS_PROC_INFO is not set
187 +# CONFIG_REISERFS_FS_XATTR is not set
188 +# CONFIG_REISERFS_FS_XATTR_USER is not set
189 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
190 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
191  # CONFIG_ADFS_FS is not set
192  # CONFIG_ADFS_FS_RW is not set
193  CONFIG_AFFS_FS=m
194 diff -urN linux-2.4.22.org/arch/sparc64/defconfig linux-2.4.22/arch/sparc64/defconfig
195 --- linux-2.4.22.org/arch/sparc64/defconfig     2003-11-21 15:04:30.000000000 +0100
196 +++ linux-2.4.22/arch/sparc64/defconfig 2003-11-21 15:26:23.000000000 +0100
197 @@ -738,6 +738,10 @@
198  # CONFIG_REISERFS_FS is not set
199  # CONFIG_REISERFS_CHECK is not set
200  # CONFIG_REISERFS_PROC_INFO is not set
201 +# CONFIG_REISERFS_FS_XATTR is not set
202 +# CONFIG_REISERFS_FS_XATTR_USER is not set
203 +# CONFIG_REISERFS_FS_XATTR_SHARING is not set
204 +# CONFIG_REISERFS_FS_POSIX_ACL is not set
205  # CONFIG_ADFS_FS is not set
206  # CONFIG_ADFS_FS_RW is not set
207  CONFIG_AFFS_FS=m
208 diff -urN linux-2.4.22.org/fs/Config.in linux-2.4.22/fs/Config.in
209 --- linux-2.4.22.org/fs/Config.in       2003-11-21 15:04:31.000000000 +0100
210 +++ linux-2.4.22/fs/Config.in   2003-11-21 15:26:23.000000000 +0100
211 @@ -13,6 +13,10 @@
212  tristate 'Reiserfs support' CONFIG_REISERFS_FS
213  dep_mbool '  Enable reiserfs debug mode' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS
214  dep_mbool '  Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS
215 +dep_mbool '  ReiserFS extended attributes' CONFIG_REISERFS_FS_XATTR $CONFIG_REISERFS_FS
216 +dep_mbool '  ReiserFS extended user attributes' CONFIG_REISERFS_FS_XATTR_USER $CONFIG_REISERFS_FS_XATTR
217 +dep_mbool '  ReiserFS trusted extended attributes' CONFIG_REISERFS_FS_XATTR_TRUSTED $CONFIG_REISERFS_FS_XATTR
218 +dep_mbool '  ReiserFS POSIX Access Control Lists' CONFIG_REISERFS_FS_POSIX_ACL $CONFIG_REISERFS_FS_XATTR $CONFIG_FS_POSIX_ACL
219  
220  dep_tristate 'ADFS file system support (EXPERIMENTAL)' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
221  dep_mbool '  ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
222 diff -urN linux-2.4.22.org/fs/inode.c linux-2.4.22/fs/inode.c
223 --- linux-2.4.22.org/fs/inode.c 2003-11-21 15:14:23.000000000 +0100
224 +++ linux-2.4.22/fs/inode.c     2003-11-21 15:26:23.000000000 +0100
225 @@ -158,6 +158,7 @@
226         sema_init(&inode->i_zombie, 1);
227         init_rwsem(&inode->i_alloc_sem);
228         spin_lock_init(&inode->i_data.i_shared_lock);
229 +       i_size_ordered_init(inode);
230  }
231  
232  static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
233 diff -urN linux-2.4.22.org/fs/reiserfs/dir.c linux-2.4.22/fs/reiserfs/dir.c
234 --- linux-2.4.22.org/fs/reiserfs/dir.c  2003-08-25 13:44:43.000000000 +0200
235 +++ linux-2.4.22/fs/reiserfs/dir.c      2003-11-21 15:26:23.000000000 +0100
236 @@ -110,6 +110,15 @@
237                     /* too big to send back to VFS */
238                     continue ;
239                 }
240 +
241 +                /* Ignore the .reiserfs_priv entry */
242 +               if (reiserfs_xattrs (inode->i_sb) && 
243 +                    !old_format_only(inode->i_sb) &&
244 +                    inode->i_sb->u.reiserfs_sb.priv_root &&
245 +                    inode->i_sb->u.reiserfs_sb.priv_root->d_inode &&
246 +                    deh_objectid (deh) == le32_to_cpu (INODE_PKEY(inode->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid))
247 +                  continue;
248 +
249                 d_off = deh_offset (deh);
250                 filp->f_pos = d_off ;
251                 d_ino = deh_objectid (deh);
252 diff -urN linux-2.4.22.org/fs/reiserfs/file.c linux-2.4.22/fs/reiserfs/file.c
253 --- linux-2.4.22.org/fs/reiserfs/file.c 2003-11-21 15:14:23.000000000 +0100
254 +++ linux-2.4.22/fs/reiserfs/file.c     2003-11-21 15:26:23.000000000 +0100
255 @@ -5,6 +5,8 @@
256  
257  #include <linux/sched.h>
258  #include <linux/reiserfs_fs.h>
259 +#include <linux/reiserfs_acl.h>
260 +#include <linux/reiserfs_xattr.h>
261  #include <linux/smp_lock.h>
262  #include <linux/quotaops.h>
263  
264 @@ -90,61 +92,6 @@
265    return ( n_err < 0 ) ? -EIO : 0;
266  }
267  
268 -static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
269 -    struct inode *inode = dentry->d_inode ;
270 -    int error ;
271 -    unsigned int ia_valid = attr->ia_valid ;
272 -
273 -    if (ia_valid & ATTR_SIZE) {
274 -       /* version 2 items will be caught by the s_maxbytes check
275 -       ** done for us in vmtruncate
276 -       */
277 -       if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
278 -           attr->ia_size > MAX_NON_LFS)
279 -            return -EFBIG ;
280 -
281 -        /* During a truncate, we have to make sure the new i_size is in
282 -       ** the transaction before we start dropping updates to data logged
283 -       ** or ordered write data pages.
284 -       */
285 -       if (attr->ia_size < inode->i_size && reiserfs_file_data_log(inode)) {
286 -           struct reiserfs_transaction_handle th ;
287 -           journal_begin(&th, inode->i_sb, 1) ;
288 -           reiserfs_update_sd_size(&th, inode, attr->ia_size) ;
289 -           journal_end(&th, inode->i_sb, 1) ;
290 -       /* fill in hole pointers in the expanding truncate case. */
291 -        } else if (attr->ia_size > inode->i_size) {
292 -           error = generic_cont_expand(inode, attr->ia_size) ;
293 -           if (inode->u.reiserfs_i.i_prealloc_count > 0) {
294 -               struct reiserfs_transaction_handle th ;
295 -               /* we're changing at most 2 bitmaps, inode + super */
296 -               journal_begin(&th, inode->i_sb, 4) ;
297 -               reiserfs_discard_prealloc (&th, inode);
298 -               journal_end(&th, inode->i_sb, 4) ;
299 -           }
300 -           if (error)
301 -               return error ;
302 -       }
303 -    }
304 -
305 -    if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
306 -        ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
307 -       (get_inode_sd_version (inode) == STAT_DATA_V1))
308 -               /* stat data of format v3.5 has 16 bit uid and gid */
309 -           return -EINVAL;
310 -
311 -    error = inode_change_ok(inode, attr) ;
312 -    if (!error) {
313 -       if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
314 -           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
315 -               error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
316 -
317 -       if (!error)
318 -           error = inode_setattr(inode, attr) ;
319 -    }
320 -    return error ;
321 -}
322 -
323  static ssize_t
324  reiserfs_file_write(struct file *f, const char *b, size_t count, loff_t *ppos)
325  {
326 @@ -173,6 +120,15 @@
327  struct  inode_operations reiserfs_file_inode_operations = {
328      truncate:  reiserfs_vfs_truncate_file,
329      setattr:    reiserfs_setattr,
330 +    setxattr:   reiserfs_setxattr, 
331 +    getxattr:   reiserfs_getxattr, 
332 +    listxattr:   reiserfs_listxattr, 
333 +    removexattr:   reiserfs_removexattr, 
334 +    /*
335 +    set_posix_acl:  reiserfs_set_acl,
336 +    get_posix_acl:  reiserfs_get_acl,
337 +    */
338 +    permission: reiserfs_permission,
339  };
340  
341  
342 diff -urN linux-2.4.22.org/fs/reiserfs/inode.c linux-2.4.22/fs/reiserfs/inode.c
343 --- linux-2.4.22.org/fs/reiserfs/inode.c        2003-11-21 15:14:23.000000000 +0100
344 +++ linux-2.4.22/fs/reiserfs/inode.c    2003-11-21 15:26:23.000000000 +0100
345 @@ -6,6 +6,8 @@
346  #include <linux/sched.h>
347  #include <linux/fs.h>
348  #include <linux/reiserfs_fs.h>
349 +#include <linux/reiserfs_acl.h>
350 +#include <linux/reiserfs_xattr.h>
351  #include <linux/locks.h>
352  #include <linux/smp_lock.h>
353  #include <linux/quotaops.h>
354 @@ -42,6 +44,8 @@
355      if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
356         down (&inode->i_sem); 
357  
358 +        reiserfs_delete_xattrs (inode);
359 +
360         journal_begin(&th, inode->i_sb, jbegin_count) ;
361         reiserfs_update_inode_transaction(inode) ;
362         windex = push_journal_writer("delete_inode") ;
363 @@ -351,10 +355,10 @@
364         ** correct, and when direct item padding results in a few 
365         ** extra bytes at the end of the direct item
366         */
367 -        if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size)
368 +        if ((le_ih_k_offset(ih) + path.pos_in_item) > i_size_read(inode))
369             break ;
370 -       if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) {
371 -           chars = inode->i_size - (le_ih_k_offset(ih) - 1) - path.pos_in_item;
372 +       if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > i_size_read(inode)) {
373 +           chars = i_size_read(inode) - (le_ih_k_offset(ih) - 1) - path.pos_in_item;
374             done = 1 ;
375         } else {
376             chars = ih_item_len(ih) - path.pos_in_item;
377 @@ -645,7 +649,7 @@
378      ** running.  So, if we are nesting into someone else, we have to
379      ** make sure and bump the refcount
380      */
381 -    if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) {
382 +    if ((new_offset + inode->i_sb->s_blocksize - 1) > i_size_read(inode)) {
383         th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count) ;
384         if (IS_ERR(th)) {
385             retval = PTR_ERR(th) ;
386 @@ -1022,7 +1026,7 @@
387      ** tail, we add 4 bytes to pretend there really is an unformatted
388      ** node pointer
389      */
390 -    bytes = ((inode->i_size + (blocksize-1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
391 +    bytes = ((i_size_read(inode) + (blocksize-1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
392      return bytes ;
393  }
394  
395 @@ -1030,7 +1034,7 @@
396                                          int sd_size)
397  {
398      if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
399 -        return inode->i_size + (loff_t)(real_space_diff(inode, sd_size)) ;
400 +        return i_size_read(inode) + (loff_t)(real_space_diff(inode, sd_size)) ;
401      }
402      return ((loff_t)real_space_diff(inode, sd_size)) + (((loff_t)blocks) << 9);
403  }
404 @@ -1165,7 +1169,7 @@
405         inode->i_op = &reiserfs_dir_inode_operations;
406         inode->i_fop = &reiserfs_dir_operations;
407      } else if (S_ISLNK (inode->i_mode)) {
408 -       inode->i_op = &page_symlink_inode_operations;
409 +       inode->i_op = &reiserfs_symlink_inode_operations;
410         inode->i_mapping->a_ops = &reiserfs_address_space_operations;
411      } else {
412         inode->i_blocks = 0;
413 @@ -1843,6 +1847,17 @@
414         goto out_inserted_sd;
415      }
416  
417 +    if (reiserfs_posixacl (inode->i_sb)) {
418 +        retval = reiserfs_inherit_default_acl (dir, dentry, inode);
419 +        if (retval) {
420 +            err = retval;
421 +            reiserfs_check_path(&path_to_key) ;
422 +            goto out_inserted_sd;
423 +        }
424 +    } else if (inode->i_sb->s_flags & MS_POSIXACL) {
425 +        reiserfs_warning (inode->i_sb, "ACLs aren't enabled in the fs, but vfs thinks they are!\n");
426 +    }
427 +
428      insert_inode_hash (inode);
429      reiserfs_update_sd(th, inode) ;
430      reiserfs_check_path(&path_to_key) ;
431 @@ -1885,6 +1900,8 @@
432  
433      /* we want the page with the last byte in the file,
434      ** not the page that will hold the next byte for appending
435 +    **
436 +    ** we are called with i_sem held, so we don't need i_size_read()
437      */
438      unsigned long index = (p_s_inode->i_size-1) >> PAGE_CACHE_SHIFT ;
439      unsigned long pos = 0 ;
440 @@ -2132,7 +2149,7 @@
441  
442         /* are there still bytes left? */
443          if (bytes_copied < bh_result->b_size && 
444 -           (byte_offset + bytes_copied) < inode->i_size) {
445 +           (byte_offset + bytes_copied) < i_size_read(inode)) {
446             set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + copy_size) ;
447             goto research ;
448         }
449 @@ -2228,7 +2245,7 @@
450  
451  static int reiserfs_write_full_page(struct page *page) {
452      struct inode *inode = page->mapping->host ;
453 -    loff_t size = inode->i_size;
454 +    loff_t size = i_size_read(inode);
455      unsigned long end_index = size >> PAGE_CACHE_SHIFT ;
456      unsigned last_offset = PAGE_CACHE_SIZE;
457      int error = 0;
458 @@ -2482,6 +2499,7 @@
459      th.t_flags = 0 ;
460      ret = __commit_write(&th, inode, page, from, to, &need_balance) ;
461   
462 +    /* i_sem is held, i_size_read is not required */
463      if (pos > inode->i_size) {
464         lock_kernel();
465         /* If the file have grown beyond the border where it
466 @@ -2495,7 +2513,7 @@
467             journal_begin(&th, inode->i_sb, 1) ;
468         }
469         reiserfs_update_inode_transaction(inode) ;
470 -       inode->i_size = pos ;
471 +       i_size_write(inode, pos);
472         reiserfs_update_sd(&th, inode) ;
473         journal_end(&th, th.t_super, th.t_blocks_allocated) ;
474         unlock_kernel() ;
475 @@ -2685,6 +2703,79 @@
476                               reiserfs_get_block_direct_io) ;
477  }
478  
479 +int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
480 +    struct inode *inode = dentry->d_inode ;
481 +    int error ;
482 +    unsigned int ia_valid = attr->ia_valid ;
483 +
484 +    if (ia_valid & ATTR_SIZE) {
485 +       /* version 2 items will be caught by the s_maxbytes check
486 +       ** done for us in vmtruncate
487 +       */
488 +       if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
489 +           attr->ia_size > MAX_NON_LFS)
490 +            return -EFBIG ;
491 +
492 +        /* During a truncate, we have to make sure the new i_size is in
493 +       ** the transaction before we start dropping updates to data logged
494 +       ** or ordered write data pages.
495 +       */
496 +       if (attr->ia_size < i_size_read(inode) && reiserfs_file_data_log(inode)) {
497 +           struct reiserfs_transaction_handle th ;
498 +           journal_begin(&th, inode->i_sb, 1) ;
499 +           reiserfs_update_sd_size(&th, inode, attr->ia_size) ;
500 +           journal_end(&th, inode->i_sb, 1) ;
501 +       /* fill in hole pointers in the expanding truncate case. */
502 +        } else if (attr->ia_size > i_size_read(inode)) {
503 +           error = generic_cont_expand(inode, attr->ia_size) ;
504 +           if (inode->u.reiserfs_i.i_prealloc_count > 0) {
505 +               struct reiserfs_transaction_handle th ;
506 +               /* we're changing at most 2 bitmaps, inode + super */
507 +               journal_begin(&th, inode->i_sb, 4) ;
508 +               reiserfs_discard_prealloc (&th, inode);
509 +               journal_end(&th, inode->i_sb, 4) ;
510 +           }
511 +           if (error)
512 +               return error ;
513 +       }
514 +    }
515 +
516 +    if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
517 +        ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
518 +       (get_inode_sd_version (inode) == STAT_DATA_V1))
519 +               /* stat data of format v3.5 has 16 bit uid and gid */
520 +           return -EINVAL;
521 +
522 +    error = inode_change_ok(inode, attr) ;
523 +    if (!error) {
524 +       if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
525 +           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
526 +                if (!(attr->ia_valid & ATTR_SIZE))
527 +                    down (&inode->i_sem);
528 +                error = reiserfs_chown_xattrs (inode, attr);
529 +                if (!(attr->ia_valid & ATTR_SIZE))
530 +                    up (&inode->i_sem);
531 +
532 +                if (!error)
533 +                    error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
534 +        }
535 +       if (!error)
536 +           error = inode_setattr(inode, attr) ;
537 +    }
538 +
539 +    if (!error && reiserfs_posixacl (inode->i_sb) && !S_ISLNK(inode->i_mode)) {
540 +        if (attr->ia_valid & ATTR_MODE) {
541 +            if (!(attr->ia_valid & ATTR_SIZE))
542 +                down (&inode->i_sem);
543 +            error = reiserfs_acl_chmod (inode);
544 +            if (!(attr->ia_valid & ATTR_SIZE))
545 +                up (&inode->i_sem);
546 +        }
547 +    }
548 +
549 +    return error ;
550 +}
551 +
552  struct address_space_operations reiserfs_address_space_operations = {
553      writepage: reiserfs_writepage,
554      readpage: reiserfs_readpage, 
555 diff -urN linux-2.4.22.org/fs/reiserfs/ioctl.c linux-2.4.22/fs/reiserfs/ioctl.c
556 --- linux-2.4.22.org/fs/reiserfs/ioctl.c        2003-11-21 15:14:23.000000000 +0100
557 +++ linux-2.4.22/fs/reiserfs/ioctl.c    2003-11-21 15:26:23.000000000 +0100
558 @@ -110,7 +110,7 @@
559      unsigned long write_from ;
560      unsigned long blocksize = inode->i_sb->s_blocksize ;
561         
562 -    if (inode->i_size == 0) {
563 +    if (i_size_read(inode) == 0) {
564          inode->u.reiserfs_i.i_flags |= i_nopack_mask;
565          return 0 ;
566      }
567 diff -urN linux-2.4.22.org/fs/reiserfs/Makefile linux-2.4.22/fs/reiserfs/Makefile
568 --- linux-2.4.22.org/fs/reiserfs/Makefile       2003-11-21 15:14:23.000000000 +0100
569 +++ linux-2.4.22/fs/reiserfs/Makefile   2003-11-21 15:26:23.000000000 +0100
570 @@ -12,6 +12,11 @@
571  obj-y   := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o super.o prints.o objectid.o \
572  lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o item_ops.o ioctl.o procfs.o
573  
574 +obj-$(CONFIG_REISERFS_FS_XATTR) += xattr.o
575 +obj-$(CONFIG_REISERFS_FS_XATTR_USER) += xattr_user.o
576 +obj-$(CONFIG_REISERFS_FS_XATTR_TRUSTED) += xattr_trusted.o
577 +obj-$(CONFIG_REISERFS_FS_POSIX_ACL) += xattr_acl.o
578 +
579  obj-m   := $(O_TARGET)
580  
581  # gcc -O2 (the kernel default)  is overaggressive on ppc32 when many inline
582 diff -urN linux-2.4.22.org/fs/reiserfs/namei.c linux-2.4.22/fs/reiserfs/namei.c
583 --- linux-2.4.22.org/fs/reiserfs/namei.c        2003-11-21 15:14:23.000000000 +0100
584 +++ linux-2.4.22/fs/reiserfs/namei.c    2003-11-21 15:26:23.000000000 +0100
585 @@ -6,6 +6,8 @@
586  #include <linux/sched.h>
587  #include <linux/bitops.h>
588  #include <linux/reiserfs_fs.h>
589 +#include <linux/reiserfs_acl.h>
590 +#include <linux/reiserfs_xattr.h>
591  #include <linux/smp_lock.h>
592  #include <linux/quotaops.h>
593  
594 @@ -271,7 +273,7 @@
595  
596  // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND
597  // FIXME: should add something like IOERROR
598 -static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen, 
599 +int reiserfs_find_entry (struct inode * dir, const char * name, int namelen, 
600                                 struct path * path_to_entry, struct reiserfs_dir_entry * de)
601  {
602      struct cpu_key key_to_search;
603 @@ -324,10 +326,21 @@
604      retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
605      pathrelse (&path_to_entry);
606      if (retval == NAME_FOUND) {
607 +        /* Hide the .reiserfs_priv dir */
608 +       if (reiserfs_xattrs (dir->i_sb) &&
609 +            !old_format_only(dir->i_sb) &&
610 +            dir->i_sb->u.reiserfs_sb.priv_root &&
611 +            dir->i_sb->u.reiserfs_sb.priv_root->d_inode &&
612 +            de.de_objectid == le32_to_cpu (INODE_PKEY(dir->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid)) {
613 +            return ERR_PTR (-EACCES);
614 +       }
615         inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
616         if (!inode || IS_ERR(inode)) {
617             return ERR_PTR(-EACCES);
618          }
619 +        /* Propogate the priv_object flag so we know we're in the priv tree */
620 +        if (is_reiserfs_priv_object (dir))
621 +            inode->u.reiserfs_i.i_flags |= i_priv_object;
622      }
623      if ( retval == IO_ERROR ) {
624         return ERR_PTR(-EIO);
625 @@ -534,6 +547,7 @@
626      struct inode * inode;
627      int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
628      struct reiserfs_transaction_handle th ;
629 +    int locked;
630  
631      if (!(inode = new_inode(dir->i_sb))) {
632         return -ENOMEM ;
633 @@ -542,8 +556,16 @@
634      if (retval)
635         return retval ;
636  
637 +    locked = reiserfs_cache_default_acl (dir);
638 +    if (locked)                                                               
639 +       reiserfs_write_lock_xattrs (inode->i_sb);
640 +
641      journal_begin(&th, dir->i_sb, jbegin_count) ;
642      retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
643 +
644 +    if (locked)
645 +       reiserfs_write_unlock_xattrs (inode->i_sb);
646 +
647      if (retval) {
648         goto out_failed ;
649      }
650 @@ -579,6 +601,7 @@
651      struct inode * inode;
652      struct reiserfs_transaction_handle th ;
653      int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
654 +    int locked;
655  
656      if (!(inode = new_inode(dir->i_sb))) {
657         return -ENOMEM ;
658 @@ -587,9 +610,17 @@
659      if (retval)
660          return retval ;
661  
662 +    locked = reiserfs_cache_default_acl (dir);
663 +    if (locked)
664 +        reiserfs_write_lock_xattrs (inode->i_sb);
665 +
666      journal_begin(&th, dir->i_sb, jbegin_count) ;
667  
668      retval = reiserfs_new_inode(&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
669 +
670 +    if (locked)
671 +        reiserfs_write_unlock_xattrs (inode->i_sb);
672 +
673      if (retval) {
674         goto out_failed; 
675      }
676 @@ -627,6 +658,7 @@
677      struct inode * inode;
678      struct reiserfs_transaction_handle th ;
679      int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
680 +    int locked;
681  
682      mode = S_IFDIR | mode;
683      if (!(inode = new_inode(dir->i_sb))) {
684 @@ -636,6 +668,10 @@
685      if (retval)
686         return retval ;
687  
688 +    locked = reiserfs_cache_default_acl (dir);
689 +    if (locked)                                                               
690 +       reiserfs_write_lock_xattrs (inode->i_sb);
691 +
692      journal_begin(&th, dir->i_sb, jbegin_count) ;
693  
694      /* inc the link count now, so another writer doesn't overflow it while
695 @@ -651,6 +687,9 @@
696                                 old_format_only (dir->i_sb) ?
697                                 EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
698                                 dentry, inode) ;
699 +    if (locked)
700 +        reiserfs_write_unlock_xattrs (inode->i_sb);
701 +
702      if (retval) {
703         dir->i_nlink-- ;
704         goto out_failed ;
705 @@ -871,7 +910,6 @@
706      struct reiserfs_transaction_handle th ;
707      int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
708  
709 -
710      if (!(inode = new_inode(parent_dir->i_sb))) {
711         return -ENOMEM ;
712      }
713 @@ -896,11 +934,14 @@
714      memcpy (name, symname, strlen (symname));
715      padd_item (name, item_len, strlen (symname));
716  
717 +    /* We would inherit the default ACL here, but symlinks don't get ACLs */
718 +
719      journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
720  
721      retval = reiserfs_new_inode(&th, parent_dir, mode, name,
722                                 strlen(symname), dentry, inode) ;
723      reiserfs_kfree (name, item_len, parent_dir->i_sb);
724 +
725      if (retval) {
726         goto out_failed ;
727      }
728 @@ -908,7 +949,7 @@
729      reiserfs_update_inode_transaction(inode) ;
730      reiserfs_update_inode_transaction(parent_dir) ;
731  
732 -    inode->i_op = &page_symlink_inode_operations;
733 +    inode->i_op = &reiserfs_symlink_inode_operations;
734      inode->i_mapping->a_ops = &reiserfs_address_space_operations;
735  
736      // must be sure this inode is written with this transaction
737 @@ -934,10 +975,9 @@
738  }
739  
740  
741 -static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
742 +int __reiserfs_link (struct inode * inode, struct inode * dir, struct dentry * dentry)
743  {
744      int retval;
745 -    struct inode *inode = old_dentry->d_inode;
746      int windex ;
747      struct reiserfs_transaction_handle th ;
748      int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
749 @@ -986,6 +1026,10 @@
750      return 0;
751  }
752  
753 +static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
754 +{
755 +    return __reiserfs_link (old_dentry->d_inode, dir, dentry);
756 +}
757  
758  // de contains information pointing to an entry which 
759  static int de_still_valid (const char * name, int len, struct reiserfs_dir_entry * de)
760 @@ -1280,5 +1324,33 @@
761      rmdir:     reiserfs_rmdir,
762      mknod:     reiserfs_mknod,
763      rename:    reiserfs_rename,
764 +    setattr:   reiserfs_setattr, 
765 +    setxattr:   reiserfs_setxattr, 
766 +    getxattr:   reiserfs_getxattr, 
767 +    listxattr:   reiserfs_listxattr, 
768 +    removexattr:   reiserfs_removexattr, 
769 +    /*
770 +    set_posix_acl:  reiserfs_set_acl,
771 +    get_posix_acl:  reiserfs_get_acl,
772 +    */
773 +    permission: reiserfs_permission,
774  };
775  
776 +/*
777 + * symlink operations.. same as page_symlink_inode_operations, with xattr
778 + * stuff added
779 + */
780 +struct inode_operations reiserfs_symlink_inode_operations = {
781 +    readlink:       page_readlink,
782 +    follow_link:    page_follow_link,
783 +    setattr:        reiserfs_setattr,
784 +    setxattr:       reiserfs_setxattr,
785 +    getxattr:       reiserfs_getxattr,
786 +    listxattr:      reiserfs_listxattr,
787 +    removexattr:    reiserfs_removexattr,
788 +    /*
789 +    set_posix_acl:  reiserfs_set_acl,
790 +    get_posix_acl:  reiserfs_get_acl,
791 +    */
792 +    permission: reiserfs_permission,
793 +};
794 diff -urN linux-2.4.22.org/fs/reiserfs/stree.c linux-2.4.22/fs/reiserfs/stree.c
795 --- linux-2.4.22.org/fs/reiserfs/stree.c        2003-11-21 15:14:25.000000000 +0100
796 +++ linux-2.4.22/fs/reiserfs/stree.c    2003-11-21 15:26:23.000000000 +0100
797 @@ -1451,7 +1451,7 @@
798  
799  void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * inode)
800  {
801 -    inode->i_size = 0;
802 +    i_size_write(inode, 0);
803  
804      /* for directory this deletes item containing "." and ".." */
805      reiserfs_do_truncate (th, inode, NULL, 0/*no timestamp updates*/);
806 @@ -1483,6 +1483,7 @@
807      int n_block_size = p_s_sb->s_blocksize;
808      int cut_bytes;
809  
810 +    /* i_sem is held, i_size_read not required */
811      if (n_new_file_size != p_s_inode->i_size)
812         BUG ();
813  
814 diff -urN linux-2.4.22.org/fs/reiserfs/super.c linux-2.4.22/fs/reiserfs/super.c
815 --- linux-2.4.22.org/fs/reiserfs/super.c        2003-11-21 15:14:25.000000000 +0100
816 +++ linux-2.4.22/fs/reiserfs/super.c    2003-11-21 15:26:23.000000000 +0100
817 @@ -9,6 +9,8 @@
818  #include <linux/vmalloc.h>
819  #include <asm/uaccess.h>
820  #include <linux/reiserfs_fs.h>
821 +#include <linux/reiserfs_acl.h>
822 +#include <linux/reiserfs_xattr.h>
823  #include <linux/smp_lock.h>
824  #include <linux/locks.h>
825  #include <linux/init.h>
826 @@ -354,7 +356,19 @@
827  {
828    int i;
829    struct reiserfs_transaction_handle th ;
830 +
831 +  reiserfs_xattr_cache_clear (s->s_dev);
832 +
833 +  if (s->u.reiserfs_sb.xattr_root) {
834 +    d_invalidate (s->u.reiserfs_sb.xattr_root);
835 +    dput (s->u.reiserfs_sb.xattr_root);
836 +  }
837    
838 +  if (s->u.reiserfs_sb.priv_root) {
839 +    d_invalidate (s->u.reiserfs_sb.priv_root);
840 +    dput (s->u.reiserfs_sb.priv_root);
841 +  }
842 +
843    /* change file system state to current state if it was mounted with read-write permissions */
844    if (!(s->s_flags & MS_RDONLY)) {
845      journal_begin(&th, s, 10) ;
846 @@ -419,6 +433,22 @@
847      unlock_kernel() ;
848  }
849  
850 +static void reiserfs_clear_inode (struct inode *inode)
851 +{
852 +    struct posix_acl *acl;
853 +
854 +    acl = inode->u.reiserfs_i.i_acl_access;
855 +    if (acl && !IS_ERR (acl))
856 +        posix_acl_release (acl);
857 +    inode->u.reiserfs_i.i_acl_access = NULL;
858 +
859 +    acl = inode->u.reiserfs_i.i_acl_default;
860 +    if (acl && !IS_ERR (acl))
861 +        posix_acl_release (acl);
862 +    inode->u.reiserfs_i.i_acl_default = NULL;
863 +}
864 +
865 +
866  struct super_operations reiserfs_sops = 
867  {
868    read_inode: reiserfs_read_inode,
869 @@ -426,6 +456,7 @@
870    write_inode: reiserfs_write_inode,
871    dirty_inode: reiserfs_dirty_inode,
872    delete_inode: reiserfs_delete_inode,
873 +  clear_inode: reiserfs_clear_inode,
874    put_super: reiserfs_put_super,
875    write_super: reiserfs_write_super,
876    write_super_lockfs: reiserfs_write_super_lockfs,
877 @@ -639,7 +670,16 @@
878                 {"noattrs", 0, 0, 0, 1<<REISERFS_ATTRS},
879                 {"usrquota", 0, 0, 0, 0},
880                 {"grpquota", 0, 0, 0, 0},
881 -
882 +#ifdef CONFIG_REISERFS_FS_XATTR
883 +# ifdef CONFIG_REISERFS_FS_XATTR_USER
884 +               {"user_xattr", 0, 0, 1<<REISERFS_XATTRS_USER},
885 +               {"nouser_xattr", 0, 0, 1<<REISERFS_NO_XATTRS_USER},
886 +# endif
887 +# ifdef CONFIG_REISERFS_FS_POSIX_ACL
888 +               {"acl", 0, 0, 1<<REISERFS_POSIXACL},
889 +               {"noacl", 0, 0, 1<<REISERFS_NO_POSIXACL},
890 +# endif
891 +#endif
892                 {NULL, 0, 0, 0, 0}
893      };
894         
895 @@ -757,6 +797,10 @@
896    safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
897    safe_mask |= 1 << REISERFS_TEST4;
898    safe_mask |= 1 << REISERFS_ATTRS;
899 +  safe_mask |= 1 << REISERFS_XATTRS_USER;
900 +  safe_mask |= 1 << REISERFS_NO_XATTRS_USER;
901 +  safe_mask |= 1 << REISERFS_POSIXACL;
902 +  safe_mask |= 1 << REISERFS_NO_POSIXACL;
903  
904    /* Update the bitmask, taking care to keep
905     * the bits we're not allowed to change here */
906 @@ -771,6 +815,7 @@
907    }
908  
909    if (*mount_flags & MS_RDONLY) {
910 +    reiserfs_xattr_init (s, *mount_flags);
911      /* remount read-only */
912      if (s->s_flags & MS_RDONLY)
913        /* it is read-only already */
914 @@ -789,6 +834,7 @@
915    } else {
916      /* remount read-write */
917      if (!(s->s_flags & MS_RDONLY)) {
918 +        reiserfs_xattr_init (s, *mount_flags);
919         handle_data_mode(s, mount_options);
920         return 0; /* We are read-write already */
921      }
922 @@ -812,6 +858,7 @@
923    if (!( *mount_flags & MS_RDONLY ) ) {
924      finish_unfinished( s );
925      handle_data_mode(s, mount_options);
926 +    reiserfs_xattr_init (s, *mount_flags);
927    }
928    return 0;
929  }
930 @@ -1236,6 +1283,8 @@
931      s->u.reiserfs_sb.s_alloc_options.preallocmin = 4;
932      /* Preallocate by 8 blocks (9-1) at once */
933      s->u.reiserfs_sb.s_alloc_options.preallocsize = 9;
934 +    /* Initialize the rwsem for xattr dir */
935 +    init_rwsem(&s->u.reiserfs_sb.xattr_dir_sem);
936  
937      if (reiserfs_parse_options (s, (char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
938        return NULL;
939 @@ -1378,11 +1427,23 @@
940                 
941         journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
942         journal_end(&th, s, 1) ;
943 -       
944 +
945 +        if (reiserfs_xattr_init (s, s->s_flags)) {
946 +            dput (s->s_root);
947 +            s->s_root = NULL;
948 +            goto error;
949 +        }
950 +
951         /* look for files which were to be removed in previous session */
952         finish_unfinished (s);
953  
954         s->s_dirt = 0;
955 +    } else {
956 +        if (reiserfs_xattr_init (s, s->s_flags)) {
957 +            dput (s->s_root);
958 +            s->s_root = NULL;
959 +            goto error;
960 +        }
961      }
962  
963      // mark hash in super block: it could be unset. overwrite should be ok
964 @@ -1445,10 +1506,37 @@
965         reiserfs_proc_info_global_init();
966         reiserfs_proc_register_global( "version", 
967                                        reiserfs_global_version_in_proc );
968 +
969         ret = reiserfs_journal_cache_init();
970 -       if (ret)
971 -           return ret;
972 -        return register_filesystem(&reiserfs_fs_type);
973 +       if (ret) goto failed_reiserfs_journal_cache_init;
974 +
975 +       ret = reiserfs_xattr_cache_init();
976 +       if (ret) goto failed_xattr_cache_init;
977 +
978 +       ret = reiserfs_xattr_user_init();
979 +       if (ret) goto failed_xattr_user_init;
980 +
981 +       ret = reiserfs_xattr_trusted_init();
982 +       if (ret) goto failed_xattr_trusted_init;
983 +
984 +       ret = reiserfs_xattr_posix_acl_init();
985 +       if (ret) goto failed_xattr_posix_acl_init;
986 +
987 +       return register_filesystem(&reiserfs_fs_type);
988 +
989 +failed_xattr_posix_acl_init:
990 +       reiserfs_xattr_trusted_exit();
991 +failed_xattr_trusted_init:
992 +       reiserfs_xattr_user_exit();
993 +failed_xattr_user_init:
994 +       reiserfs_xattr_cache_exit();
995 +failed_xattr_cache_init:
996 +       /* reiserfs_journal_cache_exit(); */
997 +failed_reiserfs_journal_cache_init:
998 +
999 +       reiserfs_proc_unregister_global( "version" );
1000 +       reiserfs_proc_info_global_done();
1001 +       return ret;
1002  }
1003  
1004  MODULE_DESCRIPTION("ReiserFS journaled filesystem");
1005 @@ -1457,6 +1545,10 @@
1006  
1007  static void __exit exit_reiserfs_fs(void)
1008  {
1009 +        reiserfs_xattr_posix_acl_exit ();
1010 +        reiserfs_xattr_trusted_exit ();
1011 +        reiserfs_xattr_user_exit ();
1012 +        reiserfs_xattr_cache_exit ();
1013         reiserfs_proc_unregister_global( "version" );
1014         reiserfs_proc_info_global_done();
1015          unregister_filesystem(&reiserfs_fs_type);
1016 diff -urN linux-2.4.22.org/fs/reiserfs/xattr_acl.c linux-2.4.22/fs/reiserfs/xattr_acl.c
1017 --- linux-2.4.22.org/fs/reiserfs/xattr_acl.c    1970-01-01 01:00:00.000000000 +0100
1018 +++ linux-2.4.22/fs/reiserfs/xattr_acl.c        2003-11-21 15:26:23.000000000 +0100
1019 @@ -0,0 +1,653 @@
1020 +#include <linux/posix_acl.h>
1021 +#include <linux/reiserfs_fs.h>
1022 +#include <linux/errno.h>
1023 +#include <linux/fs.h>
1024 +#include <linux/pagemap.h>
1025 +#include <linux/xattr.h>
1026 +#include <linux/xattr_acl.h>
1027 +#include <linux/reiserfs_xattr.h>
1028 +#include <linux/reiserfs_acl.h>
1029 +#include <asm/uaccess.h>
1030 +
1031 +static int
1032 +xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
1033 +{
1034 +       struct posix_acl *acl;
1035 +       int error;
1036 +
1037 +       if (!reiserfs_posixacl(inode->i_sb))
1038 +               return -EOPNOTSUPP;
1039 +       if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
1040 +               return -EPERM;
1041 +
1042 +       if (value) {
1043 +               acl = posix_acl_from_xattr(value, size);
1044 +               if (IS_ERR(acl)) {
1045 +                       return PTR_ERR(acl);
1046 +               } else if (acl) {
1047 +                       error = posix_acl_valid(acl);
1048 +                       if (error)
1049 +                               goto release_and_out;
1050 +               }
1051 +       } else
1052 +               acl = NULL;
1053 +
1054 +       error = reiserfs_set_acl (inode, type, acl);
1055 +
1056 +release_and_out:
1057 +       posix_acl_release(acl);
1058 +       return error;
1059 +}
1060 +
1061 +
1062 +static int
1063 +xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
1064 +{
1065 +       struct posix_acl *acl;
1066 +       int error;
1067 +
1068 +       if (!reiserfs_posixacl(inode->i_sb))
1069 +               return -EOPNOTSUPP;
1070 +
1071 +       acl = reiserfs_get_acl (inode, type);
1072 +       if (IS_ERR(acl))
1073 +               return PTR_ERR(acl);
1074 +       if (acl == NULL)
1075 +               return -ENODATA;
1076 +       error = posix_acl_to_xattr(acl, buffer, size);
1077 +       posix_acl_release(acl);
1078 +
1079 +       return error;
1080 +}
1081 +
1082 +
1083 +/*
1084 + * Convert from filesystem to in-memory representation.
1085 + */
1086 +static struct posix_acl *
1087 +posix_acl_from_disk(const void *value, size_t size)
1088 +{
1089 +       const char *end = (char *)value + size;
1090 +       int n, count;
1091 +       struct posix_acl *acl;
1092 +
1093 +       if (!value)
1094 +               return NULL;
1095 +       if (size < sizeof(reiserfs_acl_header))
1096 +                return ERR_PTR(-EINVAL);
1097 +       if (((reiserfs_acl_header *)value)->a_version !=
1098 +           cpu_to_le32(REISERFS_ACL_VERSION))
1099 +               return ERR_PTR(-EINVAL);
1100 +       value = (char *)value + sizeof(reiserfs_acl_header);
1101 +       count = reiserfs_acl_count(size);
1102 +       if (count < 0)
1103 +               return ERR_PTR(-EINVAL);
1104 +       if (count == 0)
1105 +               return NULL;
1106 +       acl = posix_acl_alloc(count, GFP_NOFS);
1107 +       if (!acl)
1108 +               return ERR_PTR(-ENOMEM);
1109 +       for (n=0; n < count; n++) {
1110 +               reiserfs_acl_entry *entry =
1111 +                       (reiserfs_acl_entry *)value;
1112 +               if ((char *)value + sizeof(reiserfs_acl_entry_short) > end)
1113 +                       goto fail;
1114 +               acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
1115 +               acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
1116 +               switch(acl->a_entries[n].e_tag) {
1117 +                       case ACL_USER_OBJ:
1118 +                       case ACL_GROUP_OBJ:
1119 +                       case ACL_MASK:
1120 +                       case ACL_OTHER:
1121 +                               value = (char *)value +
1122 +                                       sizeof(reiserfs_acl_entry_short);
1123 +                               acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
1124 +                               break;
1125 +
1126 +                       case ACL_USER:
1127 +                       case ACL_GROUP:
1128 +                               value = (char *)value + sizeof(reiserfs_acl_entry);
1129 +                               if ((char *)value > end)
1130 +                                       goto fail;
1131 +                               acl->a_entries[n].e_id =
1132 +                                       le32_to_cpu(entry->e_id);
1133 +                               break;
1134 +
1135 +                       default:
1136 +                               goto fail;
1137 +               }
1138 +       }
1139 +       if (value != end)
1140 +               goto fail;
1141 +       return acl;
1142 +
1143 +fail:
1144 +       posix_acl_release(acl);
1145 +       return ERR_PTR(-EINVAL);
1146 +}
1147 +
1148 +/*
1149 + * Convert from in-memory to filesystem representation.
1150 + */
1151 +static void *
1152 +posix_acl_to_disk(const struct posix_acl *acl, size_t *size)
1153 +{
1154 +       reiserfs_acl_header *ext_acl;
1155 +       char *e;
1156 +       int n;
1157 +
1158 +       *size = reiserfs_acl_size(acl->a_count);
1159 +       ext_acl = (reiserfs_acl_header *)kmalloc(sizeof(reiserfs_acl_header) +
1160 +               acl->a_count * sizeof(reiserfs_acl_entry), GFP_NOFS);
1161 +       if (!ext_acl)
1162 +               return ERR_PTR(-ENOMEM);
1163 +       ext_acl->a_version = cpu_to_le32(REISERFS_ACL_VERSION);
1164 +       e = (char *)ext_acl + sizeof(reiserfs_acl_header);
1165 +       for (n=0; n < acl->a_count; n++) {
1166 +               reiserfs_acl_entry *entry = (reiserfs_acl_entry *)e;
1167 +               entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
1168 +               entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
1169 +               switch(acl->a_entries[n].e_tag) {
1170 +                       case ACL_USER:
1171 +                       case ACL_GROUP:
1172 +                               entry->e_id =
1173 +                                       cpu_to_le32(acl->a_entries[n].e_id);
1174 +                               e += sizeof(reiserfs_acl_entry);
1175 +                               break;
1176 +
1177 +                       case ACL_USER_OBJ:
1178 +                       case ACL_GROUP_OBJ:
1179 +                       case ACL_MASK:
1180 +                       case ACL_OTHER:
1181 +                               e += sizeof(reiserfs_acl_entry_short);
1182 +                               break;
1183 +
1184 +                       default:
1185 +                               goto fail;
1186 +               }
1187 +       }
1188 +       return (char *)ext_acl;
1189 +
1190 +fail:
1191 +       kfree(ext_acl);
1192 +       return ERR_PTR(-EINVAL);
1193 +}
1194 +
1195 +/*
1196 + * Inode operation get_posix_acl().
1197 + *
1198 + * inode->i_sem: down
1199 + * BKL held [before 2.5.x]
1200 + */
1201 +struct posix_acl *
1202 +reiserfs_get_acl(struct inode *inode, int type)
1203 +{
1204 +       char *name, *value;
1205 +       struct posix_acl *acl, **p_acl;
1206 +       size_t size;
1207 +       int retval;
1208 +
1209 +        switch (type) {
1210 +            case ACL_TYPE_ACCESS:
1211 +                name = XATTR_NAME_ACL_ACCESS;
1212 +                p_acl = &inode->u.reiserfs_i.i_acl_access;
1213 +                break;
1214 +            case ACL_TYPE_DEFAULT:
1215 +                name = XATTR_NAME_ACL_DEFAULT;
1216 +                p_acl = &inode->u.reiserfs_i.i_acl_default;
1217 +                break;
1218 +            default:
1219 +                return ERR_PTR (-EINVAL);
1220 +        }
1221 +
1222 +        if (IS_ERR (*p_acl)) {
1223 +            if (PTR_ERR (*p_acl) == -ENODATA)
1224 +                return NULL;
1225 +        } else if (*p_acl != NULL)
1226 +            return posix_acl_dup (*p_acl);
1227 +
1228 +        size = reiserfs_xattr_get (inode, name, NULL, 0);
1229 +        if ((int)size < 0) {
1230 +            if (size == -ENODATA || size == -ENOSYS) {
1231 +               *p_acl = ERR_PTR (-ENODATA);
1232 +               return NULL;
1233 +            }
1234 +            return ERR_PTR (size);
1235 +        }
1236 +
1237 +        value = kmalloc (size, GFP_NOFS);
1238 +        if (!value)
1239 +            return ERR_PTR (-ENOMEM);
1240 +
1241 +       retval = reiserfs_xattr_get(inode, name, value, size);
1242 +       if (retval == -ENODATA || retval == -ENOSYS) {
1243 +               /* This shouldn't actually happen as it should have
1244 +                  been caught above.. but just in case */
1245 +               acl = NULL;
1246 +               *p_acl = ERR_PTR (-ENODATA);
1247 +        } else if (retval < 0) {
1248 +               acl = ERR_PTR(retval);
1249 +       } else {
1250 +               acl = posix_acl_from_disk(value, retval);
1251 +               *p_acl = posix_acl_dup (acl);
1252 +        }
1253 +
1254 +       kfree(value);
1255 +       return acl;
1256 +}
1257 +
1258 +/*
1259 + * Inode operation set_posix_acl().
1260 + *
1261 + * inode->i_sem: down
1262 + * BKL held [before 2.5.x]
1263 + */
1264 +int
1265 +reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
1266 +{
1267 +        char *name;
1268 +       void *value = NULL;
1269 +       struct posix_acl **p_acl;
1270 +       size_t size;
1271 +       int error;
1272 +
1273 +       if (S_ISLNK(inode->i_mode))
1274 +               return -EOPNOTSUPP;
1275 +
1276 +
1277 +        switch (type) {
1278 +            case ACL_TYPE_ACCESS:
1279 +                name = XATTR_NAME_ACL_ACCESS;
1280 +                p_acl = &inode->u.reiserfs_i.i_acl_access;
1281 +                if (acl) {
1282 +                    mode_t mode = inode->i_mode;
1283 +                    error = posix_acl_equiv_mode (acl, &mode);
1284 +                    if (error < 0)
1285 +                        return error;
1286 +                    else {
1287 +                        inode->i_mode = mode;
1288 +                        if (error == 0)
1289 +                            acl = NULL;
1290 +                    }
1291 +                }
1292 +                break;
1293 +            case ACL_TYPE_DEFAULT:
1294 +                name = XATTR_NAME_ACL_DEFAULT;
1295 +                p_acl = &inode->u.reiserfs_i.i_acl_default;
1296 +                if (!S_ISDIR (inode->i_mode))
1297 +                    return acl ? -EACCES : 0;
1298 +                break;
1299 +            default:
1300 +                return -EINVAL;
1301 +        }
1302 +
1303 +       if (acl) {
1304 +            value = posix_acl_to_disk(acl, &size);
1305 +            if (IS_ERR(value))
1306 +                return (int)PTR_ERR(value);
1307 +            error = reiserfs_xattr_set(inode, name, value, size, 0);
1308 +       } else {
1309 +            error = reiserfs_xattr_del (inode, name);
1310 +            if (error == -ENODATA)
1311 +                error = 0;
1312 +        }
1313 +
1314 +       if (value)
1315 +               kfree(value);
1316 +
1317 +        if (!error) {
1318 +            /* Release the old one */
1319 +            if (!IS_ERR (*p_acl) && *p_acl)
1320 +                posix_acl_release (*p_acl);
1321 +
1322 +            if (acl == NULL)
1323 +                *p_acl = ERR_PTR (-ENODATA);
1324 +            else 
1325 +                *p_acl = posix_acl_dup (acl);
1326 +        }
1327 +
1328 +       return error;
1329 +}
1330 +
1331 +/* dir->i_sem: down,
1332 + * inode is new and not released into the wild yet */
1333 +int
1334 +reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode)
1335 +{
1336 +    struct posix_acl *acl;
1337 +    int err = 0;
1338 +
1339 +    /* ACLs only get applied to files and directories */
1340 +    if (S_ISLNK (inode->i_mode))
1341 +        return 0;
1342 +
1343 +    /* ACLs can only be used on "new" objects, so if it's an old object
1344 +     * there is nothing to inherit from */
1345 +    if (get_inode_sd_version (dir) == STAT_DATA_V1)
1346 +        goto apply_umask;
1347 +
1348 +    /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
1349 +     * would be useless since permissions are ignored, and a pain because
1350 +     * it introduces locking cycles */
1351 +    if (is_reiserfs_priv_object (dir)) {
1352 +        inode->u.reiserfs_i.i_flags |= i_priv_object;
1353 +        goto apply_umask;
1354 +    }
1355 +
1356 +    acl = reiserfs_get_acl (dir, ACL_TYPE_DEFAULT);
1357 +    if (IS_ERR (acl)) {
1358 +        if (PTR_ERR (acl) == -ENODATA)
1359 +            goto apply_umask;
1360 +        return PTR_ERR (acl);
1361 +    }
1362 +
1363 +    if (acl) {
1364 +        struct posix_acl *acl_copy;
1365 +        mode_t mode = inode->i_mode;
1366 +        int need_acl;
1367 +
1368 +        /* Copy the default ACL to the default ACL of a new directory */
1369 +        if (S_ISDIR (inode->i_mode)) {
1370 +            err = reiserfs_set_acl (inode, ACL_TYPE_DEFAULT, acl);
1371 +            if (err)
1372 +                goto cleanup;
1373 +        }
1374 +
1375 +        /* Now we reconcile the new ACL and the mode,
1376 +           potentially modifying both */
1377 +        acl_copy = posix_acl_clone (acl, GFP_NOFS);
1378 +        if (!acl_copy) {
1379 +            err = -ENOMEM;
1380 +            goto cleanup;
1381 +        }
1382 +
1383 +
1384 +        need_acl = posix_acl_create_masq (acl_copy, &mode);
1385 +        if (need_acl >= 0) {
1386 +            if (mode != inode->i_mode) {
1387 +                inode->i_mode = mode;
1388 +            }
1389 +
1390 +            /* If we need an ACL.. */
1391 +            if (need_acl > 0) {
1392 +                err = reiserfs_set_acl (inode, ACL_TYPE_ACCESS, acl_copy);
1393 +                if (err) 
1394 +                    goto cleanup_copy;
1395 +            }
1396 +        }
1397 +cleanup_copy:
1398 +        posix_acl_release (acl_copy);
1399 +cleanup:
1400 +        posix_acl_release (acl);
1401 +    } else {
1402 +apply_umask:
1403 +        /* no ACL, apply umask */
1404 +        inode->i_mode &= ~current->fs->umask;
1405 +    }
1406 +
1407 +    return err;
1408 +}
1409 +
1410 +/* Looks up and caches the result of the default ACL.
1411 + * We do this so that we don't need to carry the xattr_sem into
1412 + * reiserfs_new_inode if we don't need to */
1413 +int
1414 +reiserfs_cache_default_acl (struct inode *inode)
1415 +{
1416 +    int ret = 0;
1417 +    if (reiserfs_posixacl (inode->i_sb) &&
1418 +        !is_reiserfs_priv_object (inode)) {
1419 +        struct posix_acl *acl;
1420 +        reiserfs_read_lock_xattrs (inode->i_sb);
1421 +        acl = reiserfs_get_acl (inode, ACL_TYPE_DEFAULT);
1422 +        reiserfs_read_unlock_xattrs (inode->i_sb);
1423 +        ret = acl ? 1 : 0;
1424 +        posix_acl_release (acl);
1425 +    }
1426 +
1427 +    return ret;
1428 +}
1429 +
1430 +static int
1431 +__reiserfs_permission (struct inode *inode, int mask, int need_lock)
1432 +{
1433 +       int mode = inode->i_mode;
1434 +
1435 +       /* Nobody gets write access to a read-only fs */
1436 +       if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
1437 +           (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
1438 +               return -EROFS;
1439 +
1440 +       /* Nobody gets write access to an immutable file */
1441 +       if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
1442 +           return -EACCES;
1443 +
1444 +        /* We don't do permission checks on the internal objects.
1445 +         * Permissions are determined by the "owning" object. */
1446 +        if (is_reiserfs_priv_object (inode))
1447 +            return 0;
1448 +
1449 +       if (current->fsuid == inode->i_uid) {
1450 +               mode >>= 6;
1451 +       } else if (reiserfs_posixacl(inode->i_sb) &&
1452 +                   get_inode_sd_version (inode) != STAT_DATA_V1) {
1453 +                struct posix_acl *acl;
1454 +
1455 +               /* ACL can't contain additional permissions if
1456 +                  the ACL_MASK entry is 0 */
1457 +               if (!(mode & S_IRWXG))
1458 +                       goto check_groups;
1459 +
1460 +                if (need_lock)
1461 +                    reiserfs_read_lock_xattrs (inode->i_sb);
1462 +                acl = reiserfs_get_acl (inode, ACL_TYPE_ACCESS);
1463 +                if (need_lock)
1464 +                    reiserfs_read_unlock_xattrs (inode->i_sb);
1465 +                if (IS_ERR (acl)) {
1466 +                    if (PTR_ERR (acl) == -ENODATA)
1467 +                        goto check_groups;
1468 +                    return PTR_ERR (acl);
1469 +                }
1470 +
1471 +                if (acl) {
1472 +                    int err = posix_acl_permission (inode, acl, mask);
1473 +                    posix_acl_release (acl);
1474 +                    if (err == -EACCES) {
1475 +                        goto check_capabilities;
1476 +                    }
1477 +                    return err;
1478 +               } else {
1479 +                       goto check_groups;
1480 +                }
1481 +
1482 +       } else {
1483 +check_groups:
1484 +               if (in_group_p(inode->i_gid))
1485 +                       mode >>= 3;
1486 +       }
1487 +       if ((mode & mask & S_IRWXO) == mask)
1488 +               return 0;
1489 +
1490 +check_capabilities:
1491 +       /* Allowed to override Discretionary Access Control? */
1492 +        if ((mask & (MAY_READ|MAY_WRITE)) || (inode->i_mode & S_IXUGO))
1493 +                if (capable(CAP_DAC_OVERRIDE))
1494 +                        return 0;
1495 +        /* Read and search granted if capable(CAP_DAC_READ_SEARCH) */
1496 +        if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) ||
1497 +            (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))))
1498 +                return 0;
1499 +       return -EACCES;
1500 +}
1501 +
1502 +int
1503 +reiserfs_permission (struct inode *inode, int mask)
1504 +{
1505 +    return __reiserfs_permission (inode, mask, 1);
1506 +}
1507 +
1508 +int
1509 +reiserfs_permission_locked (struct inode *inode, int mask)
1510 +{
1511 +    return __reiserfs_permission (inode, mask, 0);
1512 +}
1513 +
1514 +int
1515 +reiserfs_acl_chmod (struct inode *inode)
1516 +{
1517 +        struct posix_acl *acl, *clone;
1518 +        int error;
1519 +
1520 +        if (S_ISLNK(inode->i_mode))
1521 +                return -EOPNOTSUPP;
1522 +
1523 +       if (get_inode_sd_version (inode) == STAT_DATA_V1 ||
1524 +           !reiserfs_posixacl(inode->i_sb))
1525 +        {
1526 +           return 0;
1527 +       }
1528 +
1529 +        reiserfs_read_lock_xattrs (inode->i_sb);
1530 +        acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
1531 +        reiserfs_read_unlock_xattrs (inode->i_sb);
1532 +        if (!acl)
1533 +                return 0;
1534 +        if (IS_ERR(acl))
1535 +                return PTR_ERR(acl);
1536 +        clone = posix_acl_clone(acl, GFP_NOFS);
1537 +        posix_acl_release(acl);
1538 +        if (!clone)
1539 +                return -ENOMEM;
1540 +        error = posix_acl_chmod_masq(clone, inode->i_mode);
1541 +        if (!error) {
1542 +                reiserfs_write_lock_xattrs (inode->i_sb);
1543 +                error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
1544 +                reiserfs_write_unlock_xattrs (inode->i_sb);
1545 +        }
1546 +        posix_acl_release(clone);
1547 +        return error;
1548 +}
1549 +
1550 +static int
1551 +posix_acl_access_get(struct inode *inode, const char *name,
1552 +                         void *buffer, size_t size)
1553 +{
1554 +       if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
1555 +               return -EINVAL;
1556 +       return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
1557 +}
1558 +
1559 +static int
1560 +posix_acl_access_set(struct inode *inode, const char *name,
1561 +                         const void *value, size_t size, int flags)
1562 +{
1563 +       if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
1564 +               return -EINVAL;
1565 +       return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
1566 +}
1567 +
1568 +static int
1569 +posix_acl_access_del (struct inode *inode, const char *name)
1570 +{
1571 +    struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_access;
1572 +    if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
1573 +       return -EINVAL;
1574 +    if (!IS_ERR (*acl) && *acl) {
1575 +        posix_acl_release (*acl);
1576 +        *acl = ERR_PTR (-ENODATA);
1577 +    }
1578 +
1579 +    return 0;
1580 +}
1581 +
1582 +static int
1583 +posix_acl_access_list (struct inode *inode, const char *name, int namelen, char *out)
1584 +{
1585 +    int len = namelen;
1586 +    if (!reiserfs_posixacl (inode->i_sb))
1587 +        return 0;
1588 +    if (out)
1589 +        memcpy (out, name, len);
1590 +
1591 +    return len;
1592 +}
1593 +
1594 +struct reiserfs_xattr_handler posix_acl_access_handler = {
1595 +    prefix: XATTR_NAME_ACL_ACCESS,
1596 +    get: posix_acl_access_get,
1597 +    set: posix_acl_access_set,
1598 +    del: posix_acl_access_del,
1599 +    list: posix_acl_access_list,
1600 +};
1601 +
1602 +static int
1603 +posix_acl_default_get (struct inode *inode, const char *name,
1604 +                          void *buffer, size_t size)
1605 +{
1606 +       if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
1607 +               return -EINVAL;
1608 +       return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
1609 +}
1610 +
1611 +static int
1612 +posix_acl_default_set(struct inode *inode, const char *name,
1613 +                          const void *value, size_t size, int flags)
1614 +{
1615 +       if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
1616 +               return -EINVAL;
1617 +       return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
1618 +}
1619 +
1620 +static int
1621 +posix_acl_default_del (struct inode *inode, const char *name)
1622 +{
1623 +    struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_default;
1624 +    if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
1625 +       return -EINVAL;
1626 +    if (!IS_ERR (*acl) && *acl) {
1627 +        posix_acl_release (*acl);
1628 +        *acl = ERR_PTR (-ENODATA);
1629 +    }
1630 +
1631 +    return 0;
1632 +}
1633 +
1634 +static int
1635 +posix_acl_default_list (struct inode *inode, const char *name, int namelen, char *out)
1636 +{
1637 +    int len = namelen;
1638 +    if (!reiserfs_posixacl (inode->i_sb))
1639 +        return 0;
1640 +    if (out)
1641 +        memcpy (out, name, len);
1642 +
1643 +    return len;
1644 +}
1645 +
1646 +struct reiserfs_xattr_handler posix_acl_default_handler = {
1647 +    prefix: XATTR_NAME_ACL_DEFAULT,
1648 +    get: posix_acl_default_get,
1649 +    set: posix_acl_default_set,
1650 +    del: posix_acl_default_del,
1651 +    list: posix_acl_default_list,
1652 +};
1653 +
1654 +int __init
1655 +reiserfs_xattr_posix_acl_init (void)
1656 +{
1657 +    int err;
1658 +    err = reiserfs_xattr_register_handler (&posix_acl_access_handler);
1659 +    if (!err)
1660 +        err = reiserfs_xattr_register_handler (&posix_acl_default_handler);
1661 +    return err;
1662 +}
1663 +
1664 +int
1665 +reiserfs_xattr_posix_acl_exit (void)
1666 +{
1667 +    int err;
1668 +    err = reiserfs_xattr_unregister_handler (&posix_acl_access_handler);
1669 +    if (!err)
1670 +        err = reiserfs_xattr_unregister_handler (&posix_acl_default_handler);
1671 +    return err;
1672 +}
1673 diff -urN linux-2.4.22.org/fs/reiserfs/xattr.c linux-2.4.22/fs/reiserfs/xattr.c
1674 --- linux-2.4.22.org/fs/reiserfs/xattr.c        1970-01-01 01:00:00.000000000 +0100
1675 +++ linux-2.4.22/fs/reiserfs/xattr.c    2003-11-21 15:26:23.000000000 +0100
1676 @@ -0,0 +1,1665 @@
1677 +/*
1678 + * linux/fs/reiserfs/xattr.c
1679 + *
1680 + * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com>
1681 + *
1682 + */
1683 +
1684 +/*
1685 + * In order to implement EA/ACLs in a clean, backwards compatible manner,
1686 + * they are implemented as files in a "private" directory.
1687 + * Each EA is in it's own file, with the directory layout like so (/ is assumed
1688 + * to be relative to fs root). Inside the /.reiserfs_priv/xattrs directory,
1689 + * directories named using the capital-hex form of the objectid and
1690 + * generation number are used. Inside each directory are individual files
1691 + * named with the name of the extended attribute.
1692 + *
1693 + * So, for objectid 12648430, we could have:
1694 + * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_access
1695 + * /.reiserfs_priv/xattrs/C0FFEE.0/system.posix_acl_default
1696 + * /.reiserfs_priv/xattrs/C0FFEE.0/user.Content-Type
1697 + * .. or similar.
1698 + *
1699 + * The file contents are the text of the EA. The size is known based on the
1700 + * stat data describing the file.
1701 + *
1702 + * In the case of system.posix_acl_access and system.posix_acl_default, since
1703 + * these are special cases for filesystem ACLs, they are interpreted by the
1704 + * kernel, in addition, they are negatively and positively cached and attached
1705 + * to the inode so that unnecessary lookups are avoided.
1706 + */
1707 +
1708 +#include <linux/reiserfs_fs.h>
1709 +#include <linux/dcache.h>
1710 +#include <linux/errno.h>
1711 +#include <linux/fs.h>
1712 +#include <linux/file.h>
1713 +#include <linux/pagemap.h>
1714 +#include <linux/xattr.h>
1715 +#include <linux/reiserfs_xattr.h>
1716 +#include <linux/mbcache.h>
1717 +#include <asm/uaccess.h>
1718 +#include <asm/checksum.h>
1719 +#include <linux/smp_lock.h>
1720 +#include <linux/stat.h>
1721 +#include <asm/semaphore.h>
1722 +
1723 +#define FL_READONLY 128
1724 +#define FL_DIR_SEM_HELD 256
1725 +#define PRIVROOT_NAME ".reiserfs_priv"
1726 +#define XAROOT_NAME   "xattrs"
1727 +
1728 +#ifdef CONFIG_REISERFS_FS_XATTR_SHARING
1729 +# error "xattr sharing is not fully implemented and buggy. DO NOT USE."
1730 +static int reiserfs_xattr_link_to_inode (struct inode *xattr_inode,
1731 +                                         struct inode *dst_inode,
1732 +                                         const char *dst_name);
1733 +#endif
1734 +
1735 +static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix);
1736 +
1737 +/* Return a dentry (or NULL) for the root of the reiserfs-private directory.
1738 + * The "xattrs" directory is contained here, as may other things in the future
1739 + */
1740 +static struct dentry *
1741 +reiserfs_get_priv_root (struct super_block *s)
1742 +{
1743 +    struct dentry *dentry = NULL;
1744 +    struct qstr privroot;
1745 +    int retval;
1746 +    struct reiserfs_dir_entry de;
1747 +    INITIALIZE_PATH (path);
1748 +
1749 +    privroot.name = PRIVROOT_NAME;
1750 +    privroot.len = strlen (privroot.name);
1751 +
1752 +    de.de_gen_number_bit_string = 0;
1753 +    retval = reiserfs_find_entry (s->s_root->d_inode, privroot.name,
1754 +                                  privroot.len, &path, &de);
1755 +    pathrelse (&path);
1756 +    if (retval == NAME_FOUND) {
1757 +        struct inode *inode;
1758 +        inode = reiserfs_iget (s, (struct cpu_key *)&(de.de_dir_id));
1759 +
1760 +        /* We don't want this entry hashed. Otherwise, we can't
1761 +         * poison lookup() and readdir() against it */
1762 +        if (inode && !IS_ERR (inode)) {
1763 +            privroot.hash = full_name_hash (privroot.name, privroot.len);
1764 +            dentry = d_alloc (s->s_root, &privroot);
1765 +
1766 +            if (dentry)
1767 +                d_instantiate (dentry, inode);
1768 +            inode->u.reiserfs_i.i_flags |= i_priv_object;
1769 +        }
1770 +    }
1771 +
1772 +    return dentry;
1773 +}
1774 +
1775 +
1776 +static struct dentry *
1777 +reiserfs_create_priv_root (struct super_block *sb)
1778 +{
1779 +    int ret;
1780 +    struct inode *inode = sb->s_root->d_inode;
1781 +    struct dentry *privroot;
1782 +    struct qstr xa;
1783 +
1784 +    xa.name = PRIVROOT_NAME;
1785 +    xa.len = strlen (xa.name);
1786 +    xa.hash = full_name_hash (xa.name, xa.len);
1787 +    privroot = d_alloc (sb->s_root, &xa);
1788 +    if (!privroot)
1789 +        return ERR_PTR (-ENOMEM);
1790 +
1791 +    down (&inode->i_sem);
1792 +    ret = inode->i_op->mkdir (inode, privroot, 0700);
1793 +    up (&inode->i_sem);
1794 +
1795 +    if (ret) {
1796 +        dput (privroot);
1797 +        return ERR_PTR (ret);
1798 +    }
1799 +
1800 +    if (privroot->d_inode) {
1801 +        reiserfs_warning ("reiserfs: Created %s on %s - reserved for "
1802 +                          "xattr storage.\n", PRIVROOT_NAME, 
1803 +                          bdevname (sb->s_dev));
1804 +        privroot->d_inode->u.reiserfs_i.i_flags |= i_priv_object;
1805 +        d_drop (privroot);
1806 +    }
1807 +    return privroot;
1808 +}
1809 +
1810 +static struct dentry *
1811 +create_xa_root (struct super_block *sb)
1812 +{
1813 +    struct dentry *privroot = dget (sb->u.reiserfs_sb.priv_root);
1814 +    struct dentry *xaroot;
1815 +
1816 +    /* This needs to be created at mount-time */
1817 +    if (!privroot)
1818 +        return ERR_PTR(-EOPNOTSUPP);
1819 +
1820 +    xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
1821 +    if (IS_ERR (xaroot)) {
1822 +        goto out;
1823 +    } else if (!xaroot->d_inode) {
1824 +        int err;
1825 +        down (&privroot->d_inode->i_sem);
1826 +        err = privroot->d_inode->i_op->mkdir (privroot->d_inode, xaroot, 0700);
1827 +        up (&privroot->d_inode->i_sem);
1828 +
1829 +        if (err) {
1830 +            dput (xaroot);
1831 +            dput (privroot);
1832 +            return ERR_PTR (err);
1833 +        }
1834 +        sb->u.reiserfs_sb.xattr_root = dget (xaroot);
1835 +    }
1836 +
1837 +out:
1838 +    dput (privroot);
1839 +    return xaroot;
1840 +}
1841 +
1842 +/* This will return a dentry, or error, refering to the xa root directory.
1843 + * If the xa root doesn't exist yet, the dentry will be returned without
1844 + * an associated inode. This dentry can be used with ->mkdir to create
1845 + * the xa directory. */
1846 +static struct dentry *
1847 +__get_xa_root (struct super_block *s)
1848 +{
1849 +    struct dentry *privroot = dget (s->u.reiserfs_sb.priv_root);
1850 +    struct dentry *xaroot = NULL;
1851 +
1852 +    if (IS_ERR (privroot) || !privroot)
1853 +        return privroot;
1854 +
1855 +    xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
1856 +    if (IS_ERR (xaroot)) {
1857 +        goto out;
1858 +    } else if (!xaroot->d_inode) {
1859 +        dput (xaroot);
1860 +        xaroot = NULL;
1861 +        goto out;
1862 +    }
1863 +
1864 +    s->u.reiserfs_sb.xattr_root = dget (xaroot);
1865 +
1866 +out:
1867 +    dput (privroot);
1868 +    return xaroot;
1869 +}
1870 +
1871 +/* Returns the dentry (or NULL) referring to the root of the extended
1872 + * attribute directory tree. If it has already been retreived, it is used.
1873 + * Otherwise, we attempt to retreive it from disk. It may also return
1874 + * a pointer-encoded error.
1875 + */
1876 +static inline struct dentry *
1877 +get_xa_root (struct super_block *s)
1878 +{
1879 +    struct dentry *dentry = s->u.reiserfs_sb.xattr_root;
1880 +
1881 +    if (!dentry)
1882 +        dentry = __get_xa_root (s);
1883 +    else
1884 +        dget (dentry);
1885 +    return dentry;
1886 +}
1887 +
1888 +/* Same as above, but only returns a valid dentry or NULL */
1889 +struct dentry *
1890 +reiserfs_get_xa_root (struct super_block *sb)
1891 +{
1892 +    struct dentry *dentry;
1893 +
1894 +    dentry = get_xa_root (sb);
1895 +    if (IS_ERR (dentry)) {
1896 +        dentry = NULL;
1897 +    } else if (dentry && !dentry->d_inode) {
1898 +        dput (dentry);
1899 +        dentry = NULL;
1900 +    }
1901 +
1902 +    return dentry;
1903 +}
1904 +
1905 +/* Opens the directory corresponding to the inode's extended attribute store.
1906 + * If flags allow, the tree to the directory may be created. If creation is
1907 + * prohibited, -ENODATA is returned. */
1908 +static struct dentry *
1909 +open_xa_dir (const struct inode *inode, int flags)
1910 +{
1911 +    struct dentry *xaroot, *xadir;
1912 +    char namebuf[17];
1913 +
1914 +    xaroot = get_xa_root (inode->i_sb);
1915 +    if (IS_ERR (xaroot)) {
1916 +        return xaroot;
1917 +    } else if (!xaroot) {
1918 +        if (flags == 0 || flags & XATTR_CREATE) {
1919 +            xaroot = create_xa_root (inode->i_sb);
1920 +            if (IS_ERR (xaroot))
1921 +                return xaroot;
1922 +        }
1923 +        if (!xaroot)
1924 +            return ERR_PTR (-ENODATA);
1925 +    }
1926 +
1927 +    /* ok, we have xaroot open */
1928 +
1929 +    snprintf (namebuf, sizeof (namebuf), "%X.%X",
1930 +              le32_to_cpu (INODE_PKEY (inode)->k_objectid),
1931 +              inode->i_generation);
1932 +    xadir = lookup_one_len (namebuf, xaroot, strlen (namebuf));
1933 +    if (IS_ERR (xadir)) {
1934 +        dput (xaroot);
1935 +        return xadir;
1936 +    }
1937 +    
1938 +    if (!xadir->d_inode) {
1939 +        int err;
1940 +        if (flags == 0 || flags & XATTR_CREATE) {
1941 +            /* Although there is nothing else trying to create this directory,
1942 +             * another directory with the same hash may be created, so we need
1943 +             * to protect against that */
1944 +            err = xaroot->d_inode->i_op->mkdir (xaroot->d_inode, xadir, 0700);
1945 +            if (err) {
1946 +                dput (xaroot);
1947 +                dput (xadir);
1948 +                return ERR_PTR (err);
1949 +            }
1950 +        }
1951 +        if (!xadir->d_inode) {
1952 +            dput (xaroot);
1953 +            dput (xadir);
1954 +            return ERR_PTR (-ENODATA);
1955 +        }
1956 +    }
1957 +
1958 +    dput (xaroot);
1959 +    return xadir;
1960 +}
1961 +
1962 +/* Returns a dentry corresponding to a specific extended attribute file
1963 + * for the inode. If flags allow, the file is created. Otherwise, a
1964 + * valid or negative dentry, or an error is returned. */
1965 +static struct dentry *
1966 +get_xa_file_dentry (const struct inode *inode, const char *name, int flags)
1967 +{
1968 +    struct dentry *xadir, *xafile;
1969 +    int err = 0;
1970 +
1971 +    xadir = open_xa_dir (inode, flags);
1972 +    if (IS_ERR (xadir)) {
1973 +        return ERR_PTR (PTR_ERR (xadir));
1974 +    } else if (xadir && !xadir->d_inode) {
1975 +        dput (xadir);
1976 +        return ERR_PTR (-ENODATA);
1977 +    }
1978 +
1979 +    xafile = lookup_one_len (name, xadir, strlen (name));
1980 +    if (IS_ERR (xafile)) {
1981 +        dput (xadir);
1982 +        return ERR_PTR (PTR_ERR (xafile));
1983 +    }
1984 +
1985 +    if (xafile->d_inode) { /* file exists */
1986 +        if (flags & XATTR_CREATE) {
1987 +            err = -EEXIST;
1988 +            dput (xafile);
1989 +            goto out;
1990 +        }
1991 +    } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
1992 +        goto out;
1993 +    } else {
1994 +        /* inode->i_sem is down, so nothing else can try to create
1995 +         * the same xattr */
1996 +        err = xadir->d_inode->i_op->create (xadir->d_inode, xafile,
1997 +                                            0700|S_IFREG);
1998 +
1999 +        if (err) {
2000 +            dput (xafile);
2001 +            goto out;
2002 +        }
2003 +    }
2004 +
2005 +out:
2006 +    dput (xadir);
2007 +    if (err)
2008 +        xafile = ERR_PTR (err);
2009 +    return xafile;
2010 +}
2011 +
2012 +
2013 +/* Opens a file pointer to the attribute associated with inode */
2014 +static struct file *
2015 +open_xa_file (const struct inode *inode, const char *name, int flags)
2016 +{
2017 +    struct dentry *xafile;
2018 +    struct file *fp;
2019 +
2020 +    xafile = get_xa_file_dentry (inode, name, flags);
2021 +    if (IS_ERR (xafile))
2022 +        return ERR_PTR (PTR_ERR (xafile));
2023 +    else if (!xafile->d_inode) {
2024 +        dput (xafile);
2025 +        return ERR_PTR (-ENODATA);
2026 +    }
2027 +
2028 +    fp = dentry_open (xafile, NULL, O_RDWR);
2029 +    /* dentry_open dputs the dentry if it fails */
2030 +
2031 +    return fp;
2032 +}
2033 +
2034 +
2035 +/*
2036 + * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but
2037 + * we need to drop the path before calling the filldir struct.  That
2038 + * would be a big performance hit to the non-xattr case, so I've copied
2039 + * the whole thing for now. --clm
2040 + *
2041 + * the big difference is that I go backwards through the directory, 
2042 + * and don't mess with f->f_pos, but the idea is the same.  Do some
2043 + * action on each and every entry in the directory.
2044 + *
2045 + * we're called with i_sem held, so there are no worries about the directory
2046 + * changing underneath us.
2047 + */
2048 +static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir)
2049 +{
2050 +    struct inode *inode = filp->f_dentry->d_inode;
2051 +    struct cpu_key pos_key;    /* key of current position in the directory (key of directory entry) */
2052 +    INITIALIZE_PATH (path_to_entry);
2053 +    struct buffer_head * bh;
2054 +    int entry_num;
2055 +    struct item_head * ih, tmp_ih;
2056 +    int search_res;
2057 +    char * local_buf;
2058 +    loff_t next_pos;
2059 +    char small_buf[32] ; /* avoid kmalloc if we can */
2060 +    struct reiserfs_de_head *deh;
2061 +    int d_reclen;
2062 +    char * d_name;
2063 +    off_t d_off;
2064 +    ino_t d_ino;
2065 +    struct reiserfs_dir_entry de;
2066 +
2067 +
2068 +    /* form key for search the next directory entry using f_pos field of
2069 +       file structure */
2070 +    next_pos = max_reiserfs_offset(inode);
2071 +
2072 +    while (1) {
2073 +research:
2074 +       if (next_pos <= DOT_DOT_OFFSET)
2075 +           break;
2076 +       make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
2077 +
2078 +       search_res = search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, &de);
2079 +       if (search_res == IO_ERROR) {
2080 +           // FIXME: we could just skip part of directory which could
2081 +           // not be read
2082 +           pathrelse(&path_to_entry);
2083 +           return -EIO;
2084 +       }
2085 +
2086 +       if (search_res == NAME_NOT_FOUND)
2087 +           de.de_entry_num--;
2088 +
2089 +       set_de_name_and_namelen(&de);
2090 +       entry_num = de.de_entry_num;
2091 +       deh = &(de.de_deh[entry_num]);
2092 +
2093 +       bh = de.de_bh;
2094 +       ih = de.de_ih;
2095 +
2096 +       if (!is_direntry_le_ih(ih)) {
2097 +reiserfs_warning("not direntry %h\n", ih);
2098 +           break;
2099 +        }
2100 +       copy_item_head(&tmp_ih, ih);
2101 +               
2102 +       /* we must have found item, that is item of this directory, */
2103 +       RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key),
2104 +               "vs-9000: found item %h does not match to dir we readdir %K",
2105 +               ih, &pos_key);
2106 +
2107 +       if (deh_offset(deh) <= DOT_DOT_OFFSET) {
2108 +           break;
2109 +       }
2110 +
2111 +       /* look for the previous entry in the directory */
2112 +       next_pos = deh_offset (deh) - 1;
2113 +
2114 +       if (!de_visible (deh))
2115 +           /* it is hidden entry */
2116 +           continue;
2117 +
2118 +       d_reclen = entry_length(bh, ih, entry_num);
2119 +       d_name = B_I_DEH_ENTRY_FILE_NAME (bh, ih, deh);
2120 +       d_off = deh_offset (deh);
2121 +       d_ino = deh_objectid (deh);
2122 +
2123 +       if (!d_name[d_reclen - 1])
2124 +           d_reclen = strlen (d_name);
2125 +
2126 +       if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
2127 +           /* too big to send back to VFS */
2128 +           continue ;
2129 +       }
2130 +
2131 +        /* Ignore the .reiserfs_priv entry */
2132 +        if (reiserfs_xattrs (inode->i_sb) && 
2133 +            !old_format_only(inode->i_sb) &&
2134 +            deh_objectid (deh) == le32_to_cpu (INODE_PKEY(inode->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid))
2135 +          continue;
2136 +
2137 +       if (d_reclen <= 32) {
2138 +         local_buf = small_buf ;
2139 +       } else {
2140 +           local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
2141 +           if (!local_buf) {
2142 +               pathrelse (&path_to_entry);
2143 +               return -ENOMEM ;
2144 +           }
2145 +           if (item_moved (&tmp_ih, &path_to_entry)) {
2146 +               reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
2147 +
2148 +               /* sigh, must retry.  Do this same offset again */
2149 +               next_pos = d_off;
2150 +               goto research;
2151 +           }
2152 +       }
2153 +
2154 +       // Note, that we copy name to user space via temporary
2155 +       // buffer (local_buf) because filldir will block if
2156 +       // user space buffer is swapped out. At that time
2157 +       // entry can move to somewhere else
2158 +       memcpy (local_buf, d_name, d_reclen);
2159 +
2160 +       /* the filldir function might need to start transactions,
2161 +        * or do who knows what.  Release the path now that we've
2162 +        * copied all the important stuff out of the deh
2163 +        */
2164 +       pathrelse (&path_to_entry);
2165 +
2166 +       if (filldir (dirent, local_buf, d_reclen, d_off, d_ino, 
2167 +                    DT_UNKNOWN) < 0) {
2168 +           if (local_buf != small_buf) {
2169 +               reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
2170 +           }
2171 +           goto end;
2172 +       }
2173 +       if (local_buf != small_buf) {
2174 +           reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
2175 +       }
2176 +    } /* while */
2177 +
2178 +end:
2179 +    pathrelse (&path_to_entry);
2180 +    return 0;
2181 +}
2182 +
2183 +/* 
2184 + * this could be done with dedicated readdir ops for the xattr files,
2185 + * but I want to get something working asap
2186 + * this is stolen from vfs_readdir
2187 + *
2188 + */
2189 +static
2190 +int xattr_readdir(struct file *file, filldir_t filler, void *buf)
2191 +{
2192 +        struct inode *inode = file->f_dentry->d_inode;
2193 +        int res = -ENOTDIR;
2194 +        if (!file->f_op || !file->f_op->readdir)
2195 +                goto out;
2196 +        down(&inode->i_sem);
2197 +        down(&inode->i_zombie);
2198 +        res = -ENOENT;
2199 +        if (!IS_DEADDIR(inode)) {
2200 +                lock_kernel();
2201 +                res = __xattr_readdir(file, buf, filler);
2202 +                unlock_kernel();
2203 +        }
2204 +        up(&inode->i_zombie);
2205 +        up(&inode->i_sem);
2206 +out:
2207 +        return res;
2208 +}
2209 +
2210 +
2211 +/* Internal operations on file data */
2212 +static inline void
2213 +reiserfs_put_page(struct page *page)
2214 +{
2215 +        kunmap(page);
2216 +        page_cache_release(page);
2217 +}
2218 +
2219 +static struct page *
2220 +reiserfs_get_page(struct inode *dir, unsigned long n)
2221 +{
2222 +        struct address_space *mapping = dir->i_mapping; 
2223 +        struct page *page;
2224 +        /* We can deadlock if we try to free dentries,
2225 +           and an unlink/rmdir has just occured - GFP_NOFS avoids this */
2226 +        mapping->gfp_mask = GFP_NOFS;
2227 +        page = read_cache_page (mapping, n,
2228 +                                (filler_t*)mapping->a_ops->readpage, NULL);
2229 +        if (!IS_ERR(page)) {
2230 +                wait_on_page(page);
2231 +                kmap(page);
2232 +                if (!Page_Uptodate(page))
2233 +                        goto fail;
2234 +/*
2235 +                if (!PageChecked(page))
2236 +                        ext2_check_page(page);
2237 +*/
2238 +                if (PageError(page))
2239 +                        goto fail;
2240 +        }
2241 +        return page;
2242 +
2243 +fail:
2244 +        reiserfs_put_page(page);
2245 +        return ERR_PTR(-EIO);
2246 +}
2247 +
2248 +static inline __u32
2249 +xattr_hash (const char *msg, int len)
2250 +{
2251 +    return csum_partial (msg, len, 0);
2252 +}
2253 +
2254 +
2255 +
2256 +/* Cache handling */
2257 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
2258 +static struct mb_cache *reiserfs_xattr_cache;
2259 +
2260 +static void
2261 +xa_cache_free_entry (struct mb_cache_entry *ce)
2262 +{
2263 +    struct inode *inode;
2264 +    if (!ce)
2265 +        return;
2266 +
2267 +    inode = (struct inode *)ce->e_block;
2268 +    if (inode) /* inode may not be set if this is called in an error case */
2269 +        iput (inode);
2270 +}
2271 +
2272 +static struct mb_cache_op reiserfs_xa_cache_ops = {
2273 +    xa_cache_free_entry
2274 +};
2275 +
2276 +int __init
2277 +reiserfs_xattr_cache_init (void)
2278 +{
2279 +    reiserfs_xattr_cache = mb_cache_create ("reiser_xa_cache",
2280 +                                           &reiserfs_xa_cache_ops,
2281 +                                           sizeof (struct mb_cache_entry) +
2282 +                                           sizeof (struct mb_cache_entry_index),
2283 +                                           1, 61);
2284 +    if (!reiserfs_xattr_cache)
2285 +        return -ENOMEM;
2286 +
2287 +    return 0;
2288 +}
2289 +
2290 +void
2291 +reiserfs_xattr_cache_exit (void)
2292 +{
2293 +    if (reiserfs_xattr_cache)
2294 +        mb_cache_destroy (reiserfs_xattr_cache);
2295 +}
2296 +
2297 +void
2298 +reiserfs_xattr_cache_clear (kdev_t dev)
2299 +{
2300 +    if (reiserfs_xattr_cache)
2301 +        mb_cache_shrink (reiserfs_xattr_cache, dev);
2302 +}
2303 +
2304 +static struct inode *
2305 +xa_cache_lookup (struct inode *inode, __u32 hash)
2306 +{
2307 +    struct mb_cache_entry *ce;
2308 +    struct inode *xattr_inode;
2309 +
2310 +    if (!reiserfs_xattr_cache)
2311 +        return NULL;
2312 +
2313 +    ce = mb_cache_entry_find_first (reiserfs_xattr_cache, 0,
2314 +                                    inode->i_dev, hash);
2315 +    while (ce) {
2316 +        struct inode *xattr_inode = (struct inode *)ce->e_block;
2317 +        if (!xattr_inode) {
2318 +            ce = mb_cache_entry_find_next (ce, 0, inode->i_dev, hash);
2319 +            continue;
2320 +        }
2321 +        if (xattr_inode->i_uid == inode->i_uid &&
2322 +            xattr_inode->i_gid == inode->i_gid) {
2323 +                break;
2324 +        }
2325 +        ce = mb_cache_entry_find_next (ce, 0, inode->i_dev, hash);
2326 +    }
2327 +
2328 +    if (!ce)
2329 +        return NULL;
2330 +
2331 +    xattr_inode = (struct inode *)ce->e_block;
2332 +    mb_cache_entry_release (ce);
2333 +
2334 +    if (xattr_inode)
2335 +        return igrab (xattr_inode);
2336 +    else
2337 +        return NULL;
2338 +}
2339 +
2340 +/* We don't actually care about the errors since if it's not inserted,
2341 + * we clean up after ourselves.. and then xa_cache_lookup just fails causing
2342 + * a lookup. Performance loss, not corruption. */
2343 +static int
2344 +xa_cache_insert (struct inode *xattr_inode, __u32 hash)
2345 +{
2346 +    struct mb_cache_entry *ce;
2347 +    int error;
2348 +    struct inode *inode = igrab (xattr_inode);
2349 +    if (!reiserfs_xattr_cache)
2350 +        return 0;
2351 +
2352 +    if (!inode)
2353 +        return -ENOENT;
2354 +
2355 +    ce = mb_cache_entry_alloc (reiserfs_xattr_cache);
2356 +    if (!ce)
2357 +        return -ENOMEM;
2358 +
2359 +    ce->e_block = 0;
2360 +    error = mb_cache_entry_insert (ce, xattr_inode->i_dev,
2361 +                                   (unsigned long)xattr_inode, &hash);
2362 +    if (error) {
2363 +        mb_cache_entry_free (ce);
2364 +        if (error == -EBUSY)
2365 +            error = 0; /* if it's already there, it's ok */
2366 +    } else
2367 +        mb_cache_entry_release (ce);
2368 +
2369 +    return error;
2370 +}
2371 +
2372 +static void
2373 +xa_cache_remove (struct inode *xattr_inode)
2374 +{
2375 +    struct mb_cache_entry *ce;
2376 +    if (!reiserfs_xattr_cache)
2377 +        return;
2378 +
2379 +    ce = mb_cache_entry_get (reiserfs_xattr_cache, xattr_inode->i_dev,
2380 +                             (unsigned long) xattr_inode);
2381 +    if (ce)
2382 +        mb_cache_entry_free (ce);
2383 +
2384 +    /* we would do an iput() here, but cache_ops->free takes care of that */
2385 +}
2386 +
2387 +#else
2388 +# define xa_cache_insert(inode, hash) while(0) {}
2389 +# define xa_cache_lookup(inode, hash) (NULL)
2390 +# define xa_cache_remove(inode) while(0) {}
2391 +#endif
2392 +
2393 +/* Generic extended attribute operations that can be used by xa plugins */
2394 +
2395 +/*
2396 + * inode->i_sem: down
2397 + */
2398 +int
2399 +reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer,
2400 +                    size_t buffer_size, int flags)
2401 +{
2402 +    int err = 0;
2403 +    struct file *fp;
2404 +    struct page *page;
2405 +    char *data;
2406 +    struct address_space *mapping;
2407 +    size_t file_pos = 0;
2408 +    size_t buffer_pos = 0;
2409 +    struct inode *xinode;
2410 +    struct iattr newattrs;
2411 +    __u32 xahash = 0;
2412 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
2413 +    struct dentry *xafile;
2414 +    struct inode *link = NULL;
2415 +#endif
2416 +
2417 +    if (get_inode_sd_version (inode) == STAT_DATA_V1)
2418 +        return -EOPNOTSUPP;
2419 +
2420 +    /* Empty xattrs are ok, they're just empty files, no hash */
2421 +    if (buffer && buffer_size)
2422 +        xahash = xattr_hash (buffer, buffer_size);
2423 +
2424 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
2425 +    link = xa_cache_lookup (inode, xahash);
2426 +    xafile = get_xa_file_dentry (inode, name, FL_READONLY);
2427 +
2428 +    if (IS_ERR (xafile) && PTR_ERR (xafile) != -ENODATA) {
2429 +        if (link)
2430 +            iput (link);
2431 +        return PTR_ERR (xafile);
2432 +    }
2433 +
2434 +    if (link) { /* Ok, we found a hit for the contents */
2435 +        if (!IS_ERR (xafile) && xafile->d_inode && xafile->d_inode == link) {
2436 +            /* nothing to do, we're not changing the contents */
2437 +            iput (link);
2438 +            dput (xafile);
2439 +            return 0;
2440 +        } else if (!IS_ERR (xafile) && xafile->d_inode) {
2441 +            /* unlink the old file, since we're linking to a new one */
2442 +            err = reiserfs_xattr_del (inode, name);
2443 +            if (err) {
2444 +                iput (link);
2445 +                dput (xafile);
2446 +                return err;
2447 +            }
2448 +        }
2449 +        dput (xafile);
2450 +        err = reiserfs_xattr_link_to_inode (link, inode, name);
2451 +        iput (link);
2452 +        return err;
2453 +    }
2454 +#endif
2455 +
2456 +open_file:
2457 +    fp = open_xa_file (inode, name, flags);
2458 +    if (IS_ERR (fp)) {
2459 +        err = PTR_ERR (fp);
2460 +        goto out;
2461 +    }
2462 +
2463 +    xinode = fp->f_dentry->d_inode;
2464 +
2465 +    /* we need to copy it off.. */
2466 +    if (xinode->i_nlink > 1) {
2467 +       fput(fp);
2468 +        err = reiserfs_xattr_del (inode, name);
2469 +        if (err < 0)
2470 +            goto out;
2471 +        /* We just killed the old one, we're not replacing anymore */
2472 +        if (flags & XATTR_REPLACE)
2473 +            flags &= ~XATTR_REPLACE;
2474 +        goto open_file;
2475 +    }
2476 +
2477 +    /* Resize it so we're ok to write there */
2478 +    newattrs.ia_size = buffer_size;
2479 +    newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
2480 +    down (&xinode->i_sem);
2481 +    err = notify_change(fp->f_dentry, &newattrs);
2482 +    if (err)
2483 +        goto out_filp;
2484 +
2485 +    mapping = xinode->i_mapping;
2486 +    while (buffer_pos < buffer_size || buffer_pos == 0) {
2487 +        size_t chunk;
2488 +        size_t skip = 0;
2489 +        size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1));
2490 +        if (buffer_size - buffer_pos > PAGE_CACHE_SIZE)
2491 +            chunk = PAGE_CACHE_SIZE;
2492 +        else
2493 +            chunk = buffer_size - buffer_pos;
2494 +
2495 +        page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
2496 +        if (IS_ERR (page)) {
2497 +            err = PTR_ERR (page);
2498 +            goto out_filp;
2499 +        }
2500 +
2501 +        lock_page (page);
2502 +        data = page_address (page);
2503 +
2504 +        if (file_pos == 0) {
2505 +            struct reiserfs_xattr_header *rxh;
2506 +            skip = file_pos = sizeof (struct reiserfs_xattr_header);
2507 +            if (chunk + skip > PAGE_CACHE_SIZE)
2508 +                chunk = PAGE_CACHE_SIZE - skip;
2509 +            rxh = (struct reiserfs_xattr_header *)data;
2510 +            rxh->h_magic = cpu_to_le32 (REISERFS_XATTR_MAGIC);
2511 +            rxh->h_hash = cpu_to_le32 (xahash);
2512 +        }
2513 +
2514 +        err = mapping->a_ops->prepare_write (fp, page, page_offset,
2515 +                                             page_offset + chunk + skip);
2516 +        if (!err) {
2517 +           if (buffer)
2518 +               memcpy (data + skip, buffer + buffer_pos, chunk);
2519 +            err = mapping->a_ops->commit_write (fp, page, page_offset,
2520 +                                                page_offset + chunk + skip);
2521 +       }
2522 +        UnlockPage (page);
2523 +        reiserfs_put_page (page);
2524 +        buffer_pos += chunk;
2525 +        file_pos += chunk;
2526 +        skip = 0;
2527 +        if (err || buffer_size == 0 || !buffer)
2528 +            break;
2529 +    }
2530 +
2531 +out_filp:
2532 +    up (&xinode->i_sem);
2533 +    xa_cache_insert (xinode, xahash);
2534 +    fput(fp);
2535 +
2536 +out:
2537 +    return err;
2538 +}
2539 +
2540 +/*
2541 + * inode->i_sem: down
2542 + */
2543 +int
2544 +reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer,
2545 +                    size_t buffer_size)
2546 +{
2547 +    ssize_t err = 0;
2548 +    struct file *fp;
2549 +    size_t isize;
2550 +    size_t file_pos = 0;
2551 +    size_t buffer_pos = 0;
2552 +    struct page *page;
2553 +    struct inode *xinode;
2554 +    __u32 hash = 0;
2555 +
2556 +    /* We can't have xattrs attached to v1 items since they don't have
2557 +     * generation numbers */
2558 +    if (get_inode_sd_version (inode) == STAT_DATA_V1)
2559 +        return -EOPNOTSUPP;
2560 +
2561 +    fp = open_xa_file (inode, name, FL_READONLY);
2562 +    if (IS_ERR (fp)) {
2563 +        err = PTR_ERR (fp);
2564 +        goto out;
2565 +    }
2566 +
2567 +    xinode = fp->f_dentry->d_inode;
2568 +    isize = xinode->i_size;
2569 +
2570 +    /* Just return the size needed */
2571 +    if (buffer == NULL) {
2572 +        err = isize - sizeof (struct reiserfs_xattr_header);
2573 +        goto out_dput;
2574 +    }
2575 +
2576 +    if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) {
2577 +        err = -ERANGE;
2578 +        goto out_dput;
2579 +    }
2580 +    
2581 +    while (file_pos < isize) {
2582 +        size_t chunk;
2583 +        char *data;
2584 +        size_t page_offset;
2585 +        size_t skip = 0;
2586 +        if (isize - file_pos > PAGE_CACHE_SIZE)
2587 +            chunk = PAGE_CACHE_SIZE;
2588 +        else
2589 +            chunk = isize - file_pos;
2590 +
2591 +        page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
2592 +        if (IS_ERR (page)) {
2593 +            err = PTR_ERR (page);
2594 +            goto out_dput;
2595 +        }
2596 +
2597 +        lock_page (page);
2598 +        data = page_address (page);
2599 +        if (file_pos == 0) {
2600 +            struct reiserfs_xattr_header *rxh =
2601 +                                        (struct reiserfs_xattr_header *)data;
2602 +            skip = file_pos = sizeof (struct reiserfs_xattr_header);
2603 +            chunk -= skip;
2604 +            /* Magic doesn't match up.. */
2605 +            if (rxh->h_magic != cpu_to_le32 (REISERFS_XATTR_MAGIC)) {
2606 +                UnlockPage (page);
2607 +                reiserfs_put_page (page);
2608 +                err = -EIO;
2609 +                goto out_dput;
2610 +            }
2611 +            hash = le32_to_cpu (rxh->h_hash);
2612 +        }
2613 +        memcpy (buffer + buffer_pos, data + skip, chunk);
2614 +        UnlockPage (page);
2615 +        reiserfs_put_page (page);
2616 +        file_pos += chunk;
2617 +        buffer_pos += chunk;
2618 +        skip = 0;
2619 +    }
2620 +    err = isize - sizeof (struct reiserfs_xattr_header);
2621 +
2622 +    if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash)
2623 +        err = -EIO;
2624 +
2625 +    /* Insert this inode into the xattr cache so we can attempt to do
2626 +     * decent sharing.. */
2627 +    if (!err)
2628 +        xa_cache_insert (xinode, hash);
2629 +
2630 +out_dput:
2631 +    fput(fp);
2632 +
2633 +out:
2634 +    return err;
2635 +}
2636 +
2637 +static int
2638 +__reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen)
2639 +{
2640 +    struct dentry *file;
2641 +    struct inode *dir = xadir->d_inode;
2642 +    int err = 0;
2643 +
2644 +    file = lookup_one_len (name, xadir, namelen);
2645 +    if (IS_ERR (file)) {
2646 +        err = PTR_ERR (file);
2647 +        goto out;
2648 +    } else if (!file->d_inode) {
2649 +        err = -ENODATA;
2650 +        goto out_file;
2651 +    }
2652 +
2653 +    /* Skip directories.. */
2654 +    if (S_ISDIR (file->d_inode->i_mode))
2655 +        goto out_file;
2656 +
2657 +    /* remove it from the xattr cache if this is the last reference to it */
2658 +    if (file->d_inode->i_nlink <= 1)
2659 +        xa_cache_remove (file->d_inode);
2660 +
2661 +    if (!is_reiserfs_priv_object (file->d_inode)) {
2662 +        reiserfs_warning ("trying to delete objectid %08x, which isn't an xattr!\n", le32_to_cpu (INODE_PKEY (file->d_inode)->k_objectid));
2663 +        dput (file);
2664 +        return -EIO;
2665 +    }
2666 +
2667 +    err = dir->i_op->unlink (dir, file);
2668 +    if (!err)
2669 +        d_delete (file);
2670 +
2671 +out_file:
2672 +    dput (file);
2673 +
2674 +out:
2675 +    return err;
2676 +}
2677 +
2678 +
2679 +int
2680 +reiserfs_xattr_del (struct inode *inode, const char *name)
2681 +{
2682 +    struct dentry *dir;
2683 +    int err;
2684 +
2685 +    dir = open_xa_dir (inode, FL_READONLY);
2686 +    if (IS_ERR (dir)) {
2687 +        err = PTR_ERR (dir);
2688 +        goto out;
2689 +    }
2690 +
2691 +    err = __reiserfs_xattr_del (dir, name, strlen (name));
2692 +    dput (dir);
2693 +
2694 +out:
2695 +    return err;
2696 +}
2697 +
2698 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
2699 +static int
2700 +reiserfs_xattr_link_to_inode (struct inode *xattr_inode,
2701 +                              struct inode *dst_inode, const char *dst_name)
2702 +{
2703 +    struct dentry *dst_dentry, *xadir;
2704 +    int err;
2705 +
2706 +    xadir = open_xa_dir (dst_inode, 0);
2707 +    if (IS_ERR (xadir))
2708 +        return PTR_ERR (xadir);
2709 +
2710 +    dst_dentry = get_xa_file_dentry (dst_inode, dst_name, FL_READONLY);
2711 +    if (IS_ERR (dst_dentry)) {
2712 +        dput (xadir);
2713 +    } else if (dst_dentry->d_inode) {
2714 +        err = -EEXIST;
2715 +        goto out;
2716 +    }
2717 +
2718 +    err = __reiserfs_link (xattr_inode, xadir->d_inode, dst_dentry);
2719 +
2720 +out:
2721 +    dput (dst_dentry);
2722 +    dput (xadir);
2723 +    return err;
2724 +}
2725 +
2726 +int
2727 +reiserfs_xattr_link (struct inode *src_inode, const char *src_name,
2728 +                     struct inode *dst_inode, const char *dst_name)
2729 +{
2730 +    struct dentry *src_dentry;
2731 +    int err;
2732 +
2733 +    src_dentry = get_xa_file_dentry (src_inode, src_name, FL_READONLY);
2734 +    if (IS_ERR (src_dentry)) {
2735 +        return PTR_ERR (src_dentry);
2736 +    } else if (!src_dentry->d_inode) {
2737 +        dput (src_dentry);
2738 +        return -ENODATA;
2739 +    }
2740 +
2741 +    err = reiserfs_xattr_link_to_inode (src_dentry->d_inode,
2742 +                                        dst_inode, dst_name);
2743 +    dput (src_dentry);
2744 +    return err;
2745 +}
2746 +#endif
2747 +
2748 +/* The following are side effects of other operations that aren't explicitly
2749 + * modifying extended attributes. This includes operations such as permissions
2750 + * or ownership changes, object deletions, etc. */
2751
2752 +static int
2753 +reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen,
2754 +                               loff_t offset, ino_t ino, unsigned int d_type)
2755 +{
2756 +    struct dentry *xadir = (struct dentry *)buf;
2757 +
2758 +    return __reiserfs_xattr_del (xadir, name, namelen);
2759 +
2760 +}
2761 +
2762 +int
2763 +reiserfs_delete_xattrs (struct inode *inode)
2764 +{
2765 +    struct file *fp;
2766 +    struct dentry *dir, *root;
2767 +    int err = 0;
2768 +
2769 +    /* Skip out, an xattr has no xattrs associated with it */
2770 +    if (is_reiserfs_priv_object (inode) ||
2771 +        get_inode_sd_version (inode) == STAT_DATA_V1 || 
2772 +        !reiserfs_xattrs(inode->i_sb))
2773 +    {
2774 +        return 0;
2775 +    }
2776 +    reiserfs_read_lock_xattrs (inode->i_sb);
2777 +    dir = open_xa_dir (inode, FL_READONLY);
2778 +    reiserfs_read_unlock_xattrs (inode->i_sb);
2779 +    if (IS_ERR (dir)) {
2780 +        err = PTR_ERR (dir);
2781 +        goto out;
2782 +    } else if (!dir->d_inode) {
2783 +        dput (dir);
2784 +        return 0;
2785 +    }
2786 +
2787 +    fp = dentry_open (dir, NULL, O_RDWR);
2788 +    if (IS_ERR (fp)) {
2789 +        err = PTR_ERR (fp);
2790 +        /* dentry_open dputs the dentry if it fails */
2791 +        goto out;
2792 +    }
2793 +
2794 +    lock_kernel ();
2795 +    err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir);
2796 +    if (err) {
2797 +        unlock_kernel ();
2798 +        goto out_dir;
2799 +    }
2800 +
2801 +    /* Leftovers besides . and .. -- that's not good. */
2802 +    if (dir->d_inode->i_nlink <= 2) {
2803 +        root = get_xa_root (inode->i_sb);
2804 +        reiserfs_write_lock_xattrs (inode->i_sb);
2805 +        err = vfs_rmdir (root->d_inode, dir);
2806 +        reiserfs_write_unlock_xattrs (inode->i_sb);
2807 +        dput (root);
2808 +    } else {
2809 +        reiserfs_warning (inode->i_sb, "Couldn't remove all entries in directory\n");
2810 +    }
2811 +    unlock_kernel ();
2812 +
2813 +out_dir:
2814 +    fput(fp);
2815 +
2816 +out:
2817 +    return err;
2818 +}
2819 +
2820 +struct reiserfs_chown_buf {
2821 +    struct inode *inode;
2822 +    struct dentry *xadir;
2823 +    struct iattr *attrs;
2824 +};
2825 +
2826 +/* XXX: If there is a better way to do this, I'd love to hear about it */
2827 +static int
2828 +reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen,
2829 +                               loff_t offset, ino_t ino, unsigned int d_type)
2830 +{
2831 +    struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
2832 +    struct dentry *xafile, *xadir = chown_buf->xadir;
2833 +    struct iattr *attrs = chown_buf->attrs;
2834 +    int err = 0;
2835 +
2836 +    xafile = lookup_one_len (name, xadir, namelen);
2837 +    if (IS_ERR (xafile))
2838 +        return PTR_ERR (xafile);
2839 +    else if (!xafile->d_inode) {
2840 +        dput (xafile);
2841 +        return -ENODATA;
2842 +    }
2843 +
2844 +#if 0
2845 +    /* In this case we need to duplicate the file, since we're changing
2846 +     * the ownership of a shared file */
2847 +    if (!S_ISDIR (xafile->d_inode->i_mode) && xafile->d_inode->i_nlink > 1) {
2848 +        struct inode *inode = chown_buf->inode;
2849 +        char *value;
2850 +        int ret, size;
2851 +        char namebuf[32];
2852 +        char *nameptr;
2853 +
2854 +        if (namelen > 31)
2855 +            nameptr = reiserfs_kmalloc (namelen+1, GFP_NOFS, inode->i_sb);
2856 +        else
2857 +            nameptr = namebuf;
2858 +
2859 +        memcpy (nameptr, name, namelen);
2860 +        nameptr[namelen] = 0;
2861 +        size = reiserfs_xattr_get (inode, nameptr, NULL, 0);
2862 +        if (size < 0) {
2863 +            if (nameptr != namebuf)
2864 +                reiserfs_kfree (nameptr, namelen, inode->i_sb);
2865 +            dput (xafile);
2866 +            return size;
2867 +        }
2868 +
2869 +        value = reiserfs_kmalloc (size, GFP_NOFS, inode->i_sb);
2870 +        if (!value) {
2871 +            if (nameptr != namebuf)
2872 +                reiserfs_kfree (nameptr, namelen, inode->i_sb);
2873 +            dput (xafile);
2874 +            return -ENOMEM;
2875 +        }
2876 +
2877 +        ret = reiserfs_xattr_get (inode, nameptr, value, size);
2878 +        if (ret < 0) {
2879 +            if (nameptr != namebuf)
2880 +                reiserfs_kfree (nameptr, namelen, inode->i_sb);
2881 +            reiserfs_kfree (value, size, inode->i_sb);
2882 +            dput (xafile);
2883 +            return ret;
2884 +        }
2885 +
2886 +        ret = reiserfs_xattr_del (inode, nameptr);
2887 +        dput (xafile);
2888 +
2889 +        if (ret < 0) {
2890 +            if (nameptr != namebuf)
2891 +                reiserfs_kfree (nameptr, namelen, inode->i_sb);
2892 +            reiserfs_kfree (value, size, inode->i_sb);
2893 +            return ret;
2894 +        }
2895 +
2896 +        ret = reiserfs_xattr_set (inode, nameptr, value, size, FL_DIR_SEM_HELD);
2897 +        reiserfs_kfree (value, size, inode->i_sb);
2898 +
2899 +        if (nameptr != namebuf)
2900 +            reiserfs_kfree (nameptr, namelen, inode->i_sb);
2901 +
2902 +        if (ret < 0)
2903 +            return ret;
2904 +
2905 +        xafile = lookup_one_len (nameptr, xadir, namelen);
2906 +        if (IS_ERR (xafile))
2907 +            return PTR_ERR (xafile);
2908 +        else if (!xafile->d_inode) {
2909 +            dput (xafile);
2910 +            return -ENODATA;
2911 +        }
2912 +    }
2913 +#endif
2914 +
2915 +    if (!S_ISDIR (xafile->d_inode->i_mode))
2916 +        err = notify_change (xafile, attrs);
2917 +    dput (xafile);
2918 +
2919 +    return err;
2920 +}
2921 +
2922 +int
2923 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
2924 +{
2925 +    struct file *fp;
2926 +    struct dentry *dir;
2927 +    int err = 0;
2928 +    struct reiserfs_chown_buf buf;
2929 +    unsigned int ia_valid = attrs->ia_valid;
2930 +
2931 +    /* Skip out, an xattr has no xattrs associated with it */
2932 +    if (is_reiserfs_priv_object (inode) ||
2933 +        get_inode_sd_version (inode) == STAT_DATA_V1 || 
2934 +        !reiserfs_xattrs(inode->i_sb))
2935 +    {
2936 +        return 0;
2937 +    }
2938 +    reiserfs_read_lock_xattrs (inode->i_sb);
2939 +    dir = open_xa_dir (inode, FL_READONLY);
2940 +    reiserfs_read_unlock_xattrs (inode->i_sb);
2941 +    if (IS_ERR (dir)) {
2942 +        if (PTR_ERR (dir) != -ENODATA)
2943 +            err = PTR_ERR (dir);
2944 +        goto out;
2945 +    } else if (!dir->d_inode) {
2946 +        dput (dir);
2947 +        goto out;
2948 +    }
2949 +
2950 +    fp = dentry_open (dir, NULL, O_RDWR);
2951 +    if (IS_ERR (fp)) {
2952 +        err = PTR_ERR (fp);
2953 +        /* dentry_open dputs the dentry if it fails */
2954 +        goto out;
2955 +    }
2956 +
2957 +    lock_kernel ();
2958 +
2959 +    attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
2960 +    buf.xadir = dir;
2961 +    buf.attrs = attrs;
2962 +    buf.inode = inode;
2963 +
2964 +    err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf);
2965 +    if (err) {
2966 +        unlock_kernel ();
2967 +        goto out_dir;
2968 +    }
2969 +
2970 +    err = notify_change (dir, attrs);
2971 +    unlock_kernel ();
2972 +
2973 +out_dir:
2974 +    fput(fp);
2975 +
2976 +out:
2977 +    attrs->ia_valid = ia_valid;
2978 +    return err;
2979 +}
2980 +
2981 +
2982 +/* Actual operations that are exported to VFS-land */
2983 +
2984 +/*
2985 + * Inode operation getxattr()
2986 + * dentry->d_inode->i_sem down
2987 + * BKL held [before 2.5.x]
2988 + */
2989 +ssize_t
2990 +reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer,
2991 +                   size_t size)
2992 +{
2993 +    struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
2994 +    int err;
2995 +
2996 +    if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
2997 +        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
2998 +        return -EOPNOTSUPP;
2999 +    
3000 +    reiserfs_read_lock_xattrs (dentry->d_sb);
3001 +    down(&dentry->d_inode->i_sem);
3002 +    err = xah->get (dentry->d_inode, name, buffer, size);
3003 +    up(&dentry->d_inode->i_sem);
3004 +    reiserfs_read_unlock_xattrs (dentry->d_sb);
3005 +    return err;
3006 +}
3007 +
3008 +
3009 +/*
3010 + * Inode operation setxattr()
3011 + *
3012 + * dentry->d_inode->i_sem down
3013 + * BKL held [before 2.5.x]
3014 + */
3015 +int
3016 +reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value,
3017 +                   size_t size, int flags)
3018 +{
3019 +    struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
3020 +    int err;
3021 +
3022 +    if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
3023 +        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
3024 +        return -EOPNOTSUPP;
3025 +    
3026 +    
3027 +    reiserfs_write_lock_xattrs (dentry->d_sb);
3028 +    err = xah->set (dentry->d_inode, name, value, size, flags);
3029 +    reiserfs_write_unlock_xattrs (dentry->d_sb);
3030 +
3031 +    dentry->d_inode->i_ctime = CURRENT_TIME;
3032 +    mark_inode_dirty (dentry->d_inode);
3033 +
3034 +    return err;
3035 +}
3036 +
3037 +/*
3038 + * Inode operation removexattr()
3039 + *
3040 + * dentry->d_inode->i_sem down
3041 + * BKL held [before 2.5.x]
3042 + */
3043 +int
3044 +reiserfs_removexattr (struct dentry *dentry, const char *name)
3045 +{
3046 +    int err;
3047 +    struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
3048 +
3049 +    if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
3050 +        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
3051 +        return -EOPNOTSUPP;
3052 +
3053 +    down (&dentry->d_inode->i_zombie);
3054 +    reiserfs_read_lock_xattrs (dentry->d_sb);
3055 +
3056 +    /* Deletion pre-operation */
3057 +    if (xah->del) {
3058 +        err = xah->del (dentry->d_inode, name);
3059 +        if (err) {
3060 +            reiserfs_read_unlock_xattrs (dentry->d_sb);
3061 +            up (&dentry->d_inode->i_zombie);
3062 +            return err;
3063 +        }
3064 +    }
3065 +
3066 +    err = reiserfs_xattr_del (dentry->d_inode, name);
3067 +    reiserfs_read_unlock_xattrs (dentry->d_sb);
3068 +    up (&dentry->d_inode->i_zombie);
3069 +
3070 +    dentry->d_inode->i_ctime = CURRENT_TIME;
3071 +    mark_inode_dirty (dentry->d_inode);
3072 +    return err;
3073 +}
3074 +
3075 +
3076 +/* This is what filldir will use:
3077 + * r_pos will always contain the amount of space required for the entire
3078 + * list. If r_pos becomes larger than r_size, we need more space and we
3079 + * return an error indicating this. If r_pos is less than r_size, then we've
3080 + * filled the buffer successfully and we return success */
3081 +struct reiserfs_listxattr_buf {
3082 +    int r_pos;
3083 +    int r_size;
3084 +    char *r_buf;
3085 +    struct inode *r_inode;
3086 +};
3087 +
3088 +static int
3089 +reiserfs_listxattr_filler (void *buf, const char *name, int namelen,
3090 +                           loff_t offset, ino_t ino, unsigned int d_type)
3091 +{
3092 +    struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
3093 +    int len = 0;
3094 +    if (name[0] != '.' || (namelen != 1 && (name[1] != '.' || namelen != 2))) {
3095 +        struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
3096 +        if (!xah) return 0; /* Unsupported xattr name, skip it */
3097 +
3098 +        /* We call ->list() twice because the operation isn't required to just
3099 +         * return the name back - we want to make sure we have enough space */
3100 +        len += xah->list (b->r_inode, name, namelen, NULL);
3101 +
3102 +        if (len) {
3103 +            if (b->r_pos + len + 1 <= b->r_size) {
3104 +                char *p = b->r_buf + b->r_pos;
3105 +                p += xah->list (b->r_inode, name, namelen, p);
3106 +                *p++ = '\0';
3107 +            }
3108 +            b->r_pos += len + 1;
3109 +        }
3110 +    }
3111 +
3112 +    return 0;
3113 +}
3114 +
3115 +static ssize_t
3116 +__reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
3117 +{
3118 +    struct file *fp;
3119 +    struct dentry *dir;
3120 +    int err = 0;
3121 +    struct reiserfs_listxattr_buf buf;
3122 +
3123 +    if (!dentry->d_inode)
3124 +        return -EINVAL;
3125 +
3126 +    if (!reiserfs_xattrs(dentry->d_sb) ||
3127 +        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
3128 +        return -EOPNOTSUPP;
3129 +
3130 +    reiserfs_read_lock_xattrs (dentry->d_sb);
3131 +    dir = open_xa_dir (dentry->d_inode, FL_READONLY);
3132 +    reiserfs_read_unlock_xattrs (dentry->d_sb);
3133 +    if (IS_ERR (dir)) {
3134 +        err = PTR_ERR (dir);
3135 +        if (err == -ENODATA)
3136 +            err = 0; /* Not an error if there aren't any xattrs */
3137 +        goto out;
3138 +    }
3139 +
3140 +    fp = dentry_open (dir, NULL, O_RDWR);
3141 +    if (IS_ERR (fp)) {
3142 +        err = PTR_ERR (fp);
3143 +        /* dentry_open dputs the dentry if it fails */
3144 +        goto out;
3145 +    }
3146 +
3147 +    buf.r_buf = buffer;
3148 +    buf.r_size = buffer ? size : 0;
3149 +    buf.r_pos = 0;
3150 +    buf.r_inode = dentry->d_inode;
3151 +
3152 +    err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf);
3153 +    if (err)
3154 +        goto out_dir;
3155 +
3156 +    if (buf.r_pos > buf.r_size && buffer != NULL)
3157 +        err = -ERANGE;
3158 +    else
3159 +        err = buf.r_pos;
3160 +
3161 +out_dir:
3162 +    fput(fp);
3163 +
3164 +out:
3165 +    return err;
3166 +}
3167 +
3168 +/*
3169 + * Inode operation listxattr()
3170 + *
3171 + * dentry->d_inode->i_sem down
3172 + * BKL held [before 2.5.x]
3173 + */
3174 +ssize_t
3175 +reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
3176 +{
3177 +    int error;
3178 +
3179 +    down(&dentry->d_inode->i_sem);
3180 +    error = __reiserfs_listxattr(dentry, buffer, size);
3181 +    up(&dentry->d_inode->i_sem);
3182 +
3183 +    return error;
3184 +}
3185 +
3186 +/* This is the implementation for the xattr plugin infrastructure */
3187 +static struct reiserfs_xattr_handler *xattr_handlers;
3188 +static rwlock_t handler_lock = RW_LOCK_UNLOCKED;
3189 +
3190 +static struct reiserfs_xattr_handler *
3191 +find_xattr_handler_prefix (const char *prefix)
3192 +{
3193 +    struct reiserfs_xattr_handler **xah;
3194 +    read_lock (&handler_lock);
3195 +    for (xah = &xattr_handlers; *xah; xah=&(*xah)->next)
3196 +        if (strncmp ((*xah)->prefix, prefix, strlen ((*xah)->prefix)) == 0)
3197 +            break;
3198 +    read_unlock (&handler_lock);
3199 +    return *xah;
3200 +}
3201 +
3202 +int
3203 +reiserfs_xattr_register_handler (struct reiserfs_xattr_handler *handler)
3204 +{
3205 +    int res = 0;
3206 +    struct reiserfs_xattr_handler **xah;
3207 +
3208 +    if (!handler)
3209 +        return -EINVAL;
3210 +
3211 +    if (handler->next)
3212 +        return -EBUSY;
3213 +
3214 +    write_lock (&handler_lock);
3215 +
3216 +    for (xah = &xattr_handlers; *xah; xah=&(*xah)->next) {
3217 +        if (strcmp ((*xah)->prefix, handler->prefix) == 0)
3218 +            break;
3219 +    }
3220 +    if (*xah)
3221 +        res = -EBUSY;
3222 +    else
3223 +        *xah = handler;
3224 +
3225 +    /*
3226 +    if (!res)
3227 +        printk ("ReiserFS: Registered xattr handler for %s\n", handler->prefix);
3228 +    */
3229 +
3230 +    write_unlock (&handler_lock);
3231 +    return res;
3232 +}
3233 +
3234 +int
3235 +reiserfs_xattr_unregister_handler (struct reiserfs_xattr_handler *handler)
3236 +{
3237 +    struct reiserfs_xattr_handler **xah;
3238 +    write_lock (&handler_lock);
3239 +
3240 +    xah = &xattr_handlers;
3241 +    while (*xah) {
3242 +        if (handler == *xah) {
3243 +            *xah = handler->next;
3244 +            handler->next = NULL;
3245 +            write_unlock (&handler_lock);
3246 +            /*
3247 +            printk ("ReiserFS: Unregistered xattr handler for %s\n",
3248 +                    handler->prefix);
3249 +            */
3250 +            return 0;
3251 +        }
3252 +        xah = &(*xah)->next;
3253 +    }
3254 +    write_unlock (&handler_lock);
3255 +    return -EINVAL;
3256 +}
3257 +
3258 +
3259 +/* We need to take a copy of the mount flags since things like
3260 + * MS_RDONLY don't get set until *after* we're called.
3261 + * mount_flags != mount_options */
3262 +int
3263 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
3264 +{
3265 +  int err = 0;
3266 +
3267 +  /* I hate using the _NO_ variant to clear bits. We use the normal variant
3268 +   * everywhere else, so just clear them both here */
3269 +  if (test_bit (REISERFS_NO_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt))) {
3270 +    clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
3271 +    clear_bit (REISERFS_NO_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
3272 +  }
3273 +
3274 +  if (test_bit (REISERFS_NO_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt))) {
3275 +    clear_bit (REISERFS_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
3276 +    clear_bit (REISERFS_NO_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
3277 +  }
3278 +
3279 +
3280 +#ifdef CONFIG_REISERFS_FS_XATTR_TRUSTED
3281 +  /* If we're a v3.6 filesystem, trusted xattrs are enabled across the board */
3282 +  if (!old_format_only(s))
3283 +    set_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
3284 +#endif
3285 +
3286 +  /* If the user has requested an optional xattrs type (e.g. user/acl), then
3287 +   * enable xattrs. If we're a v3.5 filesystem, this will get caught and
3288 +   * error out. If no optional xattrs are enabled, and trusted xattrs aren't
3289 +   * enabled, then disable xattrs */
3290 +  if (reiserfs_xattrs_optional (s))
3291 +    set_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
3292 +  else if (!reiserfs_xattrs_trusted (s))
3293 +    clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
3294 +
3295 +  if (reiserfs_xattrs (s)) {
3296 +    /* We need generation numbers to ensure that the oid mapping is correct
3297 +     * v3.5 filesystems don't have them. */
3298 +    if (old_format_only (s)) {
3299 +      reiserfs_warning (s, "reiserfs: xattrs/ACLs not supported on pre v3.6 "
3300 +                        "format filesystem. Failing mount.\n");
3301 +      err = -EOPNOTSUPP;
3302 +      goto error;
3303 +    } else if (!s->u.reiserfs_sb.priv_root) {
3304 +      struct dentry *dentry = reiserfs_get_priv_root (s);
3305 +      if (!dentry && !(mount_flags & MS_RDONLY))
3306 +          dentry = reiserfs_create_priv_root (s);
3307 +      if (!IS_ERR (dentry) && dentry)
3308 +          s->u.reiserfs_sb.priv_root = dentry;
3309 +      else { /* xattrs are unavailable */
3310 +          /* If we're read-only it just means that the dir hasn't been
3311 +           * created. Not an error -- just no xattrs on the fs. We'll
3312 +           * check again if we go read-write */
3313 +          if (!(mount_flags & MS_RDONLY)) {
3314 +              reiserfs_warning (s, "reiserfs: xattrs/ACLS enabled and couldn't "
3315 +                             "find/create .reiserfs_priv. Failing mount.\n");
3316 +            err = -EOPNOTSUPP;
3317 +            goto error;
3318 +          }
3319 +          /* Just to speed things up a bit since it won't find anything and
3320 +           * we're read-only */
3321 +          clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
3322 +          clear_bit (REISERFS_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
3323 +      }
3324 +    } /* otherwise, already mounted, and remounting */
3325 +  }
3326 +
3327 +
3328 +error:
3329 +   /* This is only nonzero if there was an error initializing the xattr
3330 +    * directory or if there is a condition where we don't support them. */
3331 +
3332 +    if (err) {
3333 +          clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
3334 +          clear_bit (REISERFS_POSIXACL, &(s->u.reiserfs_sb.s_mount_opt));
3335 +          clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
3336 +    }
3337 +
3338 +    s->s_flags = (s->s_flags & ~MS_POSIXACL) |
3339 +                 (reiserfs_posixacl (s) ? MS_POSIXACL : 0);
3340 +    return err;
3341 +}
3342 diff -urN linux-2.4.22.org/fs/reiserfs/xattr_trusted.c linux-2.4.22/fs/reiserfs/xattr_trusted.c
3343 --- linux-2.4.22.org/fs/reiserfs/xattr_trusted.c        1970-01-01 01:00:00.000000000 +0100
3344 +++ linux-2.4.22/fs/reiserfs/xattr_trusted.c    2003-11-21 15:26:24.000000000 +0100
3345 @@ -0,0 +1,97 @@
3346 +#include <linux/reiserfs_fs.h>
3347 +#include <linux/errno.h>
3348 +#include <linux/fs.h>
3349 +#include <linux/pagemap.h>
3350 +#include <linux/xattr.h>
3351 +#include <linux/reiserfs_xattr.h>
3352 +#include <asm/uaccess.h>
3353 +
3354 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
3355 +# include <linux/reiserfs_acl.h>
3356 +#endif
3357 +
3358 +#define XATTR_TRUSTED_PREFIX "trusted."
3359 +
3360 +static int
3361 +trusted_get (struct inode *inode, const char *name, void *buffer, size_t size)
3362 +{
3363 +    if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
3364 +        return -EINVAL;
3365 +
3366 +    if (!reiserfs_xattrs_trusted (inode->i_sb))
3367 +        return -EOPNOTSUPP;
3368 +
3369 +    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3370 +        return -EPERM;
3371 +
3372 +    return reiserfs_xattr_get (inode, name, buffer, size);
3373 +}
3374 +
3375 +static int
3376 +trusted_set (struct inode *inode, const char *name, const void *buffer,
3377 +          size_t size, int flags)
3378 +{
3379 +    if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
3380 +        return -EINVAL;
3381 +
3382 +    if (!reiserfs_xattrs_trusted (inode->i_sb))
3383 +        return -EOPNOTSUPP;
3384 +
3385 +    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3386 +        return -EPERM;
3387 +
3388 +    return reiserfs_xattr_set (inode, name, buffer, size, flags);
3389 +}
3390 +
3391 +static int
3392 +trusted_del (struct inode *inode, const char *name)
3393 +{
3394 +    if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
3395 +        return -EINVAL;
3396 +
3397 +    if (!reiserfs_xattrs_trusted (inode->i_sb))
3398 +        return -EOPNOTSUPP;
3399 +
3400 +    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3401 +        return -EPERM;
3402 +
3403 +    return 0;
3404 +}
3405 +
3406 +static int
3407 +trusted_list (struct inode *inode, const char *name, int namelen, char *out)
3408 +{
3409 +    int len = namelen;
3410 +
3411 +    if (!reiserfs_xattrs_trusted (inode->i_sb))
3412 +        return 0;
3413 +
3414 +    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3415 +        return 0;
3416 +
3417 +    if (out)
3418 +        memcpy (out, name, len);
3419 +
3420 +    return len;
3421 +}
3422 +
3423 +
3424 +struct reiserfs_xattr_handler trusted_handler = {
3425 +    prefix: XATTR_TRUSTED_PREFIX,
3426 +    get: trusted_get,
3427 +    set: trusted_set,
3428 +    del: trusted_del,
3429 +    list: trusted_list,
3430 +};
3431 +
3432 +int __init
3433 +reiserfs_xattr_trusted_init (void)
3434 +{
3435 +    return reiserfs_xattr_register_handler (&trusted_handler);
3436 +}
3437 +
3438 +int
3439 +reiserfs_xattr_trusted_exit (void)
3440 +{
3441 +    return reiserfs_xattr_unregister_handler (&trusted_handler);
3442 +}
3443 diff -urN linux-2.4.22.org/fs/reiserfs/xattr_user.c linux-2.4.22/fs/reiserfs/xattr_user.c
3444 --- linux-2.4.22.org/fs/reiserfs/xattr_user.c   1970-01-01 01:00:00.000000000 +0100
3445 +++ linux-2.4.22/fs/reiserfs/xattr_user.c       2003-11-21 15:26:24.000000000 +0100
3446 @@ -0,0 +1,112 @@
3447 +#include <linux/reiserfs_fs.h>
3448 +#include <linux/errno.h>
3449 +#include <linux/fs.h>
3450 +#include <linux/pagemap.h>
3451 +#include <linux/xattr.h>
3452 +#include <linux/reiserfs_xattr.h>
3453 +#include <asm/uaccess.h>
3454 +
3455 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
3456 +# include <linux/reiserfs_acl.h>
3457 +#endif
3458 +
3459 +#define XATTR_USER_PREFIX "user."
3460 +
3461 +static int
3462 +user_get (struct inode *inode, const char *name, void *buffer, size_t size)
3463 +{
3464 +
3465 +    int error;
3466 +
3467 +    if (strlen(name) < sizeof(XATTR_USER_PREFIX))
3468 +        return -EINVAL;
3469 +
3470 +    if (!reiserfs_xattrs_user (inode->i_sb))
3471 +        return -EOPNOTSUPP;
3472 +
3473 +    error = reiserfs_permission_locked (inode, MAY_READ);
3474 +    if (error)
3475 +        return error;
3476 +
3477 +    return reiserfs_xattr_get (inode, name, buffer, size);
3478 +}
3479 +
3480 +static int
3481 +user_set (struct inode *inode, const char *name, const void *buffer,
3482 +          size_t size, int flags)
3483 +{
3484 +
3485 +    int error;
3486 +
3487 +    if (strlen(name) < sizeof(XATTR_USER_PREFIX))
3488 +        return -EINVAL;
3489 +
3490 +    if (!reiserfs_xattrs_user (inode->i_sb))
3491 +        return -EOPNOTSUPP;
3492 +
3493 +    if (!S_ISREG (inode->i_mode) &&
3494 +        (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
3495 +        return -EPERM;
3496 +
3497 +    error = reiserfs_permission_locked (inode, MAY_WRITE);
3498 +    if (error)
3499 +        return error;
3500 +
3501 +    return reiserfs_xattr_set (inode, name, buffer, size, flags);
3502 +}
3503 +
3504 +static int
3505 +user_del (struct inode *inode, const char *name)
3506 +{
3507 +    int error;
3508 +
3509 +    if (strlen(name) < sizeof(XATTR_USER_PREFIX))
3510 +        return -EINVAL;
3511 +
3512 +    if (!reiserfs_xattrs_user (inode->i_sb))
3513 +        return -EOPNOTSUPP;
3514 +
3515 +    if (!S_ISREG (inode->i_mode) &&
3516 +        (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
3517 +        return -EPERM;
3518 +
3519 +    error = reiserfs_permission_locked (inode, MAY_WRITE);
3520 +    if (error)
3521 +        return error;
3522 +
3523 +    return 0;
3524 +}
3525 +
3526 +static int
3527 +user_list (struct inode *inode, const char *name, int namelen, char *out)
3528 +{
3529 +    int len = namelen;
3530 +    if (!reiserfs_xattrs_user (inode->i_sb))
3531 +        return 0;
3532 +
3533 +    if (out)
3534 +        memcpy (out, name, len);
3535 +
3536 +    return len;
3537 +}
3538 +
3539 +
3540 +struct reiserfs_xattr_handler user_handler = {
3541 +    prefix: XATTR_USER_PREFIX,
3542 +    get: user_get,
3543 +    set: user_set,
3544 +    del: user_del,
3545 +    list: user_list,
3546 +};
3547 +
3548 +int __init
3549 +reiserfs_xattr_user_init (void)
3550 +{
3551 +    return reiserfs_xattr_register_handler (&user_handler);
3552 +}
3553 +
3554 +int
3555 +reiserfs_xattr_user_exit (void)
3556 +{
3557 +    return reiserfs_xattr_unregister_handler (&user_handler);
3558 +}
3559 diff -urN linux-2.4.22.org/include/asm-i386/bugs.h linux-2.4.22/include/asm-i386/bugs.h
3560 --- linux-2.4.22.org/include/asm-i386/bugs.h    2002-08-03 02:39:45.000000000 +0200
3561 +++ linux-2.4.22/include/asm-i386/bugs.h        2003-11-21 15:26:24.000000000 +0100
3562 @@ -200,6 +200,11 @@
3563             && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11))
3564                 panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!");
3565  #endif
3566 +
3567 +#ifdef CONFIG_X86_CMPXCHG8
3568 +       if (!cpu_has_cx8)
3569 +               panic("Kernel compiled for Pentium+, requires CMPXCHG8B feature!");
3570 +#endif
3571  }
3572  
3573  static void __init check_bugs(void)
3574 diff -urN linux-2.4.22.org/include/asm-i386/cpufeature.h linux-2.4.22/include/asm-i386/cpufeature.h
3575 --- linux-2.4.22.org/include/asm-i386/cpufeature.h      2003-11-21 15:04:19.000000000 +0100
3576 +++ linux-2.4.22/include/asm-i386/cpufeature.h  2003-11-21 15:27:01.000000000 +0100
3577 @@ -89,6 +89,7 @@
3578  #define cpu_has_pge            boot_cpu_has(X86_FEATURE_PGE)
3579  #define cpu_has_sse2           boot_cpu_has(X86_FEATURE_XMM2)
3580  #define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
3581 +#define cpu_has_cx8            boot_cpu_has(X86_FEATURE_CX8)
3582  #define cpu_has_sep            boot_cpu_has(X86_FEATURE_SEP)
3583  #define cpu_has_mtrr           boot_cpu_has(X86_FEATURE_MTRR)
3584  #define cpu_has_mmx            boot_cpu_has(X86_FEATURE_MMX)
3585 diff -urN linux-2.4.22.org/include/asm-i386/system.h linux-2.4.22/include/asm-i386/system.h
3586 --- linux-2.4.22.org/include/asm-i386/system.h  2003-11-21 15:04:24.000000000 +0100
3587 +++ linux-2.4.22/include/asm-i386/system.h      2003-11-21 15:26:24.000000000 +0100
3588 @@ -143,6 +143,8 @@
3589  #define __xg(x) ((struct __xchg_dummy *)(x))
3590  
3591  
3592 +#ifdef CONFIG_X86_CMPXCHG8
3593 +#define __ARCH_HAS_GET_SET_64BIT 1
3594  /*
3595   * The semantics of XCHGCMP8B are a bit strange, this is why
3596   * there is a loop and the loading of %%eax and %%edx has to
3597 @@ -167,7 +169,7 @@
3598                 "lock cmpxchg8b (%0)\n\t"
3599                 "jnz 1b"
3600                 : /* no outputs */
3601 -               :       "D"(ptr),
3602 +               :       "r"(ptr),
3603                         "b"(low),
3604                         "c"(high)
3605                 :       "ax","dx","memory");
3606 @@ -197,6 +199,32 @@
3607   __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
3608   __set_64bit(ptr, ll_low(value), ll_high(value)) )
3609  
3610 +
3611 +/*
3612 + * The memory clobber is needed in the read side only if
3613 + * there is an unsafe writer before the get_64bit, which should
3614 + * never be the case, but just to be safe.
3615 + */
3616 +static inline unsigned long long get_64bit(unsigned long long * ptr)
3617 +{
3618 +        unsigned long low, high;
3619 +
3620 +        __asm__ __volatile__ (
3621 +                "\n1:\t"
3622 +                "movl (%2), %%eax\n\t"
3623 +                "movl 4(%2), %%edx\n\t"
3624 +                "movl %%eax, %%ebx\n\t"
3625 +                "movl %%edx, %%ecx\n\t"
3626 +                "lock cmpxchg8b (%2)\n\t"
3627 +                "jnz 1b"
3628 +                : "=&b" (low), "=&c" (high)
3629 +                : "r" (ptr)
3630 +                : "ax","dx","memory");
3631 +
3632 +        return low | ((unsigned long long) high << 32);
3633 +}
3634 +#endif /* CONFIG_X86_CMPXCHG */
3635 +
3636  /*
3637   * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
3638   * Note 2: xchg has side effect, so that attribute volatile is necessary,
3639 diff -urN linux-2.4.22.org/include/linux/fs.h linux-2.4.22/include/linux/fs.h
3640 --- linux-2.4.22.org/include/linux/fs.h 2003-11-21 15:14:25.000000000 +0100
3641 +++ linux-2.4.22/include/linux/fs.h     2003-11-21 15:26:24.000000000 +0100
3642 @@ -441,6 +441,13 @@
3643         struct list_head        bd_inodes;
3644  };
3645  
3646 +#if BITS_PER_LONG==32 && defined(CONFIG_SMP) && !defined(__ARCH_HAS_GET_SET_64BIT)
3647 +#define __NEED_I_SIZE_ORDERED
3648 +#define i_size_ordered_init(inode) do { (inode)->i_size_version1 = (inode)->i_size_version2 = 0; } while (0)
3649 +#else
3650 +#define i_size_ordered_init(inode) do { } while (0)
3651 +#endif
3652 +
3653  struct inode {
3654         struct list_head        i_hash;
3655         struct list_head        i_list;
3656 @@ -527,8 +534,65 @@
3657                 struct jffs2_inode_info         jffs2_i;
3658                 void                            *generic_ip;
3659         } u;
3660 +#ifdef __NEED_I_SIZE_ORDERED
3661 +       volatile int            i_size_version1;
3662 +       volatile int            i_size_version2;
3663 +#endif
3664  };
3665  
3666 +/*
3667 + * NOTE: in a 32bit arch with a preemptable kernel and
3668 + * an UP compile the i_size_read/write must be atomic
3669 + * with respect to the local cpu (unlike with preempt disabled),
3670 + * but they don't need to be atomic with respect to other cpus like in
3671 + * true SMP (so they need either to either locally disable irq around
3672 + * the read or for example on x86 they can be still implemented as a
3673 + * cmpxchg8b without the need of the lock prefix). For SMP compiles
3674 + * and 64bit archs it makes no difference if preempt is enabled or not.
3675 + */
3676 +static inline loff_t i_size_read(struct inode * inode)
3677 +{
3678 +#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
3679 +#ifdef __ARCH_HAS_GET_SET_64BIT
3680 +       return (loff_t) get_64bit((unsigned long long *) &inode->i_size);
3681 +#else
3682 +       loff_t i_size;
3683 +       int v1, v2;
3684 +
3685 +       /* Retry if i_size was possibly modified while sampling. */
3686 +       do {
3687 +               v1 = inode->i_size_version1;
3688 +               rmb();
3689 +               i_size = inode->i_size;
3690 +               rmb();
3691 +               v2 = inode->i_size_version2;
3692 +       } while (v1 != v2);
3693 +
3694 +       return i_size;
3695 +#endif
3696 +#elif BITS_PER_LONG==64 || !defined(CONFIG_SMP)
3697 +       return inode->i_size;
3698 +#endif
3699 +}
3700 +
3701 +static inline void i_size_write(struct inode * inode, loff_t i_size)
3702 +{
3703 +#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
3704 +#ifdef __ARCH_HAS_GET_SET_64BIT
3705 +       set_64bit((unsigned long long *) &inode->i_size, (unsigned long long) i_size);
3706 +#else
3707 +       inode->i_size_version2++;
3708 +       wmb();
3709 +       inode->i_size = i_size;
3710 +       wmb();
3711 +       inode->i_size_version1++;
3712 +       wmb(); /* make it visible ASAP */
3713 +#endif
3714 +#elif BITS_PER_LONG==64 || !defined(CONFIG_SMP)
3715 +       inode->i_size = i_size;
3716 +#endif
3717 +}
3718 +
3719  static inline void inode_add_bytes(struct inode *inode, loff_t bytes)
3720  {
3721         inode->i_blocks += bytes >> 9;
3722 @@ -824,6 +888,7 @@
3723  extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
3724  extern int vfs_symlink(struct inode *, struct dentry *, const char *);
3725  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
3726 +extern int __vfs_rmdir(struct inode *, struct dentry *);
3727  extern int vfs_rmdir(struct inode *, struct dentry *);
3728  extern int vfs_unlink(struct inode *, struct dentry *);
3729  extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
3730 @@ -1402,6 +1467,7 @@
3731  extern int follow_down(struct vfsmount **, struct dentry **);
3732  extern int follow_up(struct vfsmount **, struct dentry **);
3733  extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
3734 +extern struct dentry * __lookup_hash(struct qstr *, struct dentry *);
3735  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
3736  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
3737  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
3738 diff -urN linux-2.4.22.org/include/linux/reiserfs_acl.h linux-2.4.22/include/linux/reiserfs_acl.h
3739 --- linux-2.4.22.org/include/linux/reiserfs_acl.h       1970-01-01 01:00:00.000000000 +0100
3740 +++ linux-2.4.22/include/linux/reiserfs_acl.h   2003-11-21 15:26:24.000000000 +0100
3741 @@ -0,0 +1,92 @@
3742 +#include <linux/init.h>
3743 +#include <linux/posix_acl.h>
3744 +#include <linux/xattr_acl.h>
3745 +
3746 +#define REISERFS_ACL_VERSION   0x0001
3747 +
3748 +typedef struct {
3749 +       __u16           e_tag;
3750 +       __u16           e_perm;
3751 +       __u32           e_id;
3752 +} reiserfs_acl_entry;
3753 +
3754 +typedef struct {
3755 +       __u16           e_tag;
3756 +       __u16           e_perm;
3757 +} reiserfs_acl_entry_short;
3758 +
3759 +typedef struct {
3760 +       __u32           a_version;
3761 +} reiserfs_acl_header;
3762 +
3763 +static inline size_t reiserfs_acl_size(int count)
3764 +{
3765 +       if (count <= 4) {
3766 +               return sizeof(reiserfs_acl_header) +
3767 +                      count * sizeof(reiserfs_acl_entry_short);
3768 +       } else {
3769 +               return sizeof(reiserfs_acl_header) +
3770 +                      4 * sizeof(reiserfs_acl_entry_short) +
3771 +                      (count - 4) * sizeof(reiserfs_acl_entry);
3772 +       }
3773 +}
3774 +
3775 +static inline int reiserfs_acl_count(size_t size)
3776 +{
3777 +       ssize_t s;
3778 +       size -= sizeof(reiserfs_acl_header);
3779 +       s = size - 4 * sizeof(reiserfs_acl_entry_short);
3780 +       if (s < 0) {
3781 +               if (size % sizeof(reiserfs_acl_entry_short))
3782 +                       return -1;
3783 +               return size / sizeof(reiserfs_acl_entry_short);
3784 +       } else {
3785 +               if (s % sizeof(reiserfs_acl_entry))
3786 +                       return -1;
3787 +               return s / sizeof(reiserfs_acl_entry) + 4;
3788 +       }
3789 +}
3790 +
3791 +
3792 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
3793 +struct posix_acl * reiserfs_get_acl(struct inode *inode, int type);
3794 +int reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl);
3795 +int reiserfs_permission (struct inode *inode, int mask);
3796 +int reiserfs_permission_locked (struct inode *inode, int mask);
3797 +int reiserfs_acl_chmod (struct inode *inode);
3798 +int reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode);
3799 +int reiserfs_cache_default_acl (struct inode *dir);
3800 +extern int reiserfs_xattr_posix_acl_init (void) __init;
3801 +extern int reiserfs_xattr_posix_acl_exit (void);
3802 +#else
3803 +
3804 +#define reiserfs_permission NULL
3805 +#define reiserfs_set_acl NULL
3806 +#define reiserfs_get_acl NULL
3807 +#define reiserfs_cache_default_acl(inode) 0
3808 +
3809 +static inline int
3810 +reiserfs_xattr_posix_acl_init (void)
3811 +{
3812 +    return 0;
3813 +}
3814 +
3815 +static inline int
3816 +reiserfs_xattr_posix_acl_exit (void)
3817 +{
3818 +    return 0;
3819 +}
3820 +
3821 +static inline int
3822 +reiserfs_acl_chmod (struct inode *inode)
3823 +{
3824 +    return 0;
3825 +}
3826 +
3827 +static inline int
3828 +reiserfs_inherit_default_acl (const struct inode *dir, struct dentry *dentry, struct inode *inode)
3829 +{
3830 +    return 0;
3831 +}
3832 +
3833 +#endif
3834 diff -urN linux-2.4.22.org/include/linux/reiserfs_fs.h linux-2.4.22/include/linux/reiserfs_fs.h
3835 --- linux-2.4.22.org/include/linux/reiserfs_fs.h        2003-11-21 15:14:25.000000000 +0100
3836 +++ linux-2.4.22/include/linux/reiserfs_fs.h    2003-11-21 15:26:24.000000000 +0100
3837 @@ -2007,17 +2007,23 @@
3838  static inline void reiserfs_update_sd(struct reiserfs_transaction_handle *th,
3839                                        struct inode *inode)
3840  {
3841 -    reiserfs_update_sd_size(th, inode, inode->i_size) ;
3842 +    reiserfs_update_sd_size(th, inode, i_size_read(inode)) ;
3843  }
3844  
3845  void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
3846  void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
3847 +int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
3848  
3849  /* namei.c */
3850  inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
3851  int search_by_entry_key (struct super_block * sb, const struct cpu_key * key, 
3852                          struct path * path, 
3853                          struct reiserfs_dir_entry * de);
3854 +int __reiserfs_link (struct inode *inode, struct inode *dir, struct dentry *dentry);
3855 +int reiserfs_find_entry (struct inode * dir, const char * name, int namelen,
3856 +                        struct path * path_to_entry,
3857 +                        struct reiserfs_dir_entry * de);
3858 +
3859  /* procfs.c */
3860  
3861  #if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO )
3862 @@ -2081,6 +2087,7 @@
3863  
3864  /* dir.c */
3865  extern struct inode_operations reiserfs_dir_inode_operations;
3866 +extern struct inode_operations reiserfs_symlink_inode_operations;
3867  extern struct file_operations reiserfs_dir_operations;
3868  
3869  /* tail_conversion.c */
3870 @@ -2301,6 +2308,9 @@
3871  #define REISERFS_IOC_GETVERSION        EXT2_IOC_GETVERSION
3872  #define REISERFS_IOC_SETVERSION         EXT2_IOC_SETVERSION
3873                                  
3874 +/* xattr stuff */
3875 +#define REISERFS_XATTR_DIR_SEM(s) ((s)->u.reiserfs_sb.xattr_dir_sem)
3876 +
3877  #endif /* _LINUX_REISER_FS_H */
3878  
3879  
3880 diff -urN linux-2.4.22.org/include/linux/reiserfs_fs_i.h linux-2.4.22/include/linux/reiserfs_fs_i.h
3881 --- linux-2.4.22.org/include/linux/reiserfs_fs_i.h      2003-11-21 15:14:25.000000000 +0100
3882 +++ linux-2.4.22/include/linux/reiserfs_fs_i.h  2003-11-21 15:26:24.000000000 +0100
3883 @@ -28,6 +28,7 @@
3884      i_link_saved_truncate_mask =  0x0020,
3885      /** are we logging data blocks for this file? */
3886      i_data_log                 =  0x0040,
3887 +    i_priv_object              =  0x0080,
3888  } reiserfs_inode_flags;
3889  
3890  
3891 @@ -64,6 +65,9 @@
3892       */
3893      unsigned long i_tail_trans_id;
3894      struct reiserfs_journal_list *i_tail_jl;
3895 +
3896 +    struct posix_acl *i_acl_access;
3897 +    struct posix_acl *i_acl_default;
3898  };
3899  
3900  #endif
3901 diff -urN linux-2.4.22.org/include/linux/reiserfs_fs_sb.h linux-2.4.22/include/linux/reiserfs_fs_sb.h
3902 --- linux-2.4.22.org/include/linux/reiserfs_fs_sb.h     2003-11-21 15:14:25.000000000 +0100
3903 +++ linux-2.4.22/include/linux/reiserfs_fs_sb.h 2003-11-21 15:26:24.000000000 +0100
3904 @@ -6,6 +6,7 @@
3905  
3906  #ifdef __KERNEL__
3907  #include <linux/tqueue.h>
3908 +#include <linux/rwsem.h>
3909  #endif
3910  
3911  //
3912 @@ -442,6 +443,9 @@
3913      struct proc_dir_entry *procdir;
3914      int reserved_blocks; /* amount of blocks reserved for further allocations */
3915      struct list_head s_reiserfs_supers;
3916 +    struct dentry *priv_root; /* root of /.reiserfs_priv */
3917 +    struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
3918 +    struct rw_semaphore xattr_dir_sem;
3919  };
3920  
3921  /* Definitions of reiserfs on-disk properties: */
3922 @@ -486,6 +490,11 @@
3923      REISERFS_DATA_WRITEBACK,
3924      REISERFS_ATTRS,
3925      REISERFS_TEST4,
3926 +    REISERFS_XATTRS,
3927 +    REISERFS_XATTRS_USER,
3928 +    REISERFS_POSIXACL,
3929 +    REISERFS_NO_XATTRS_USER,
3930 +    REISERFS_NO_POSIXACL,
3931  };
3932  
3933  #define reiserfs_r5_hash(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << FORCE_R5_HASH))
3934 @@ -507,6 +516,15 @@
3935  #define reiserfs_attrs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_ATTRS))
3936  #define old_format_only(s) ((s)->u.reiserfs_sb.s_properties & (1 << REISERFS_3_5))
3937  #define convert_reiserfs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_CONVERT))
3938 +#define reiserfs_xattrs_user(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_XATTRS_USER))
3939 +#define reiserfs_posixacl(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_POSIXACL))
3940 +#define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s))
3941 +#define reiserfs_xattrs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_XATTRS))
3942 +#ifdef CONFIG_REISERFS_FS_XATTR_TRUSTED
3943 +# define reiserfs_xattrs_trusted(s) reiserfs_xattrs(s)
3944 +#else
3945 +# define reiserfs_xattrs_trusted(s) (0)
3946 +#endif
3947  
3948  
3949  void reiserfs_file_buffer (struct buffer_head * bh, int list);
3950 diff -urN linux-2.4.22.org/include/linux/reiserfs_xattr.h linux-2.4.22/include/linux/reiserfs_xattr.h
3951 --- linux-2.4.22.org/include/linux/reiserfs_xattr.h     1970-01-01 01:00:00.000000000 +0100
3952 +++ linux-2.4.22/include/linux/reiserfs_xattr.h 2003-11-21 15:26:24.000000000 +0100
3953 @@ -0,0 +1,155 @@
3954 +/*
3955 +  File: linux/reiserfs_xattr.h
3956 +*/
3957 +
3958 +#include <linux/config.h>
3959 +#include <linux/init.h>
3960 +#include <linux/xattr.h>
3961 +
3962 +/* Magic value in header */
3963 +#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
3964 +
3965 +struct reiserfs_xattr_header {
3966 +    __u32 h_magic;              /* magic number for identification */
3967 +    __u32 h_hash;               /* hash of the value */
3968 +};
3969 +
3970 +#ifdef __KERNEL__
3971 +
3972 +struct reiserfs_xattr_handler {
3973 +       char *prefix;
3974 +       int (*get)(struct inode *inode, const char *name, void *buffer,
3975 +                  size_t size);
3976 +       int (*set)(struct inode *inode, const char *name, const void *buffer,
3977 +                  size_t size, int flags);
3978 +       int (*del)(struct inode *inode, const char *name);
3979 +        int (*list)(struct inode *inode, const char *name, int namelen, char *out);
3980 +        struct reiserfs_xattr_handler *next;
3981 +};
3982 +
3983 +
3984 +#ifdef CONFIG_REISERFS_FS_XATTR
3985 +#define is_reiserfs_priv_object(inode) (((inode)->u.reiserfs_i.i_flags & i_priv_object) == i_priv_object)
3986 +ssize_t reiserfs_getxattr (struct dentry *dentry, const char *name,
3987 +                          void *buffer, size_t size);
3988 +int reiserfs_setxattr (struct dentry *dentry, const char *name,
3989 +                       const void *value, size_t size, int flags);
3990 +ssize_t reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size);
3991 +int reiserfs_removexattr (struct dentry *dentry, const char *name);
3992 +int reiserfs_delete_xattrs (struct inode *inode);
3993 +int reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs);
3994 +int reiserfs_xattr_init (struct super_block *sb, int mount_flags);
3995 +
3996 +static inline void
3997 +reiserfs_write_lock_xattrs(struct super_block *sb)
3998 +{
3999 +    down_write (&REISERFS_XATTR_DIR_SEM(sb));
4000 +}
4001 +static inline void
4002 +reiserfs_write_unlock_xattrs(struct super_block *sb)
4003 +{
4004 +    up_write (&REISERFS_XATTR_DIR_SEM(sb));
4005 +}
4006 +static inline void
4007 +reiserfs_read_lock_xattrs(struct super_block *sb)
4008 +{
4009 +    down_read (&REISERFS_XATTR_DIR_SEM(sb));
4010 +}
4011 +static inline void
4012 +reiserfs_read_unlock_xattrs(struct super_block *sb)
4013 +{
4014 +    up_read (&REISERFS_XATTR_DIR_SEM(sb));
4015 +}
4016 +#else
4017 +#define is_reiserfs_priv_object(inode) 0
4018 +#define reiserfs_getxattr NULL
4019 +#define reiserfs_setxattr NULL
4020 +#define reiserfs_listxattr NULL
4021 +#define reiserfs_removexattr NULL
4022 +#define reiserfs_write_lock_xattrs(sb)
4023 +#define reiserfs_write_unlock_xattrs(sb)
4024 +#define reiserfs_read_lock_xattrs(sb)
4025 +#define reiserfs_read_unlock_xattrs(sb)
4026 +static inline int
4027 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
4028 +{
4029 +    s->s_flags = (s->s_flags & ~MS_POSIXACL); /* to be sure */
4030 +    return 0;
4031 +}
4032 +
4033 +static inline int
4034 +reiserfs_delete_xattrs (struct inode *inode)
4035 +{
4036 +    return 0;
4037 +}
4038 +
4039 +static inline int
4040 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
4041 +{
4042 +    return 0;
4043 +}
4044 +#endif
4045 +
4046 +extern int reiserfs_xattr_register_handler(struct reiserfs_xattr_handler *);
4047 +extern int reiserfs_xattr_unregister_handler(struct reiserfs_xattr_handler *);
4048 +extern int reiserfs_xattr_del (struct inode *, const char *);
4049 +extern int reiserfs_xattr_get (const struct inode *, const char *, void *, size_t);
4050 +extern int reiserfs_xattr_set (struct inode *, const char *, const void *,
4051 +                               size_t, int);
4052 +
4053 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
4054 +int reiserfs_xattr_cache_init (void) __init;
4055 +void reiserfs_xattr_cache_exit (void);
4056 +void reiserfs_xattr_cache_clear (kdev_t dev);
4057 +#else
4058 +static inline int 
4059 +reiserfs_xattr_cache_init (void)
4060 +{
4061 +    return 0;
4062 +}
4063 +
4064 +static inline int 
4065 +reiserfs_xattr_cache_exit (void)
4066 +{
4067 +    return 0;
4068 +}
4069 +
4070 +static inline void
4071 +reiserfs_xattr_cache_clear (kdev_t dev)
4072 +{
4073 +};
4074 +#endif
4075 +#ifdef CONFIG_REISERFS_FS_XATTR_USER
4076 +extern int reiserfs_xattr_user_init (void) __init;
4077 +extern int reiserfs_xattr_user_exit (void);
4078 +#else
4079 +static inline int
4080 +reiserfs_xattr_user_init (void)
4081 +{
4082 +    return 0;
4083 +}
4084 +
4085 +static inline int
4086 +reiserfs_xattr_user_exit (void)
4087 +{
4088 +    return 0;
4089 +}
4090 +#endif
4091 +#ifdef CONFIG_REISERFS_FS_XATTR_TRUSTED
4092 +extern int reiserfs_xattr_trusted_init (void) __init;
4093 +extern int reiserfs_xattr_trusted_exit (void);
4094 +#else
4095 +static inline int
4096 +reiserfs_xattr_trusted_init (void)
4097 +{
4098 +    return 0;
4099 +}
4100 +
4101 +static inline int
4102 +reiserfs_xattr_trusted_exit (void)
4103 +{
4104 +    return 0;
4105 +}
4106 +#endif
4107 +
4108 +#endif  /* __KERNEL__ */
This page took 0.346277 seconds and 3 git commands to generate.