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
5 # CONFIG_AUTOFS4_FS is not set
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
19 define_bool CONFIG_X86_F00F_WORKS_OK n
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
27 define_bool CONFIG_X86_F00F_WORKS_OK n
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
35 define_bool CONFIG_X86_F00F_WORKS_OK n
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
43 define_bool CONFIG_X86_F00F_WORKS_OK n
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
51 define_bool CONFIG_X86_F00F_WORKS_OK y
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
59 define_bool CONFIG_X86_F00F_WORKS_OK y
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
67 define_bool CONFIG_X86_F00F_WORKS_OK y
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
75 define_bool CONFIG_MK7 y
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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);
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
237 /* too big to send back to VFS */
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))
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
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>
265 return ( n_err < 0 ) ? -EIO : 0;
268 -static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
269 - struct inode *inode = dentry->d_inode ;
271 - unsigned int ia_valid = attr->ia_valid ;
273 - if (ia_valid & ATTR_SIZE) {
274 - /* version 2 items will be caught by the s_maxbytes check
275 - ** done for us in vmtruncate
277 - if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
278 - attr->ia_size > MAX_NON_LFS)
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.
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) ;
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 */
311 - error = inode_change_ok(inode, attr) ;
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;
318 - error = inode_setattr(inode, attr) ;
324 reiserfs_file_write(struct file *f, const char *b, size_t count, loff_t *ppos)
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,
335 + set_posix_acl: reiserfs_set_acl,
336 + get_posix_acl: reiserfs_get_acl,
338 + permission: reiserfs_permission,
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
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>
355 if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
356 down (&inode->i_sem);
358 + reiserfs_delete_xattrs (inode);
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
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))
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;
376 chars = ih_item_len(ih) - path.pos_in_item;
378 ** running. So, if we are nesting into someone else, we have to
379 ** make sure and bump the refcount
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) ;
385 retval = PTR_ERR(th) ;
386 @@ -1022,7 +1026,7 @@
387 ** tail, we add 4 bytes to pretend there really is an unformatted
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;
395 @@ -1030,7 +1034,7 @@
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)) ;
402 return ((loff_t)real_space_diff(inode, sd_size)) + (((loff_t)blocks) << 9);
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;
413 @@ -1843,6 +1847,17 @@
414 goto out_inserted_sd;
417 + if (reiserfs_posixacl (inode->i_sb)) {
418 + retval = reiserfs_inherit_default_acl (dir, dentry, inode);
421 + reiserfs_check_path(&path_to_key) ;
422 + goto out_inserted_sd;
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");
428 insert_inode_hash (inode);
429 reiserfs_update_sd(th, inode) ;
430 reiserfs_check_path(&path_to_key) ;
431 @@ -1885,6 +1900,8 @@
433 /* we want the page with the last byte in the file,
434 ** not the page that will hold the next byte for appending
436 + ** we are called with i_sem held, so we don't need i_size_read()
438 unsigned long index = (p_s_inode->i_size-1) >> PAGE_CACHE_SHIFT ;
439 unsigned long pos = 0 ;
440 @@ -2132,7 +2149,7 @@
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) ;
449 @@ -2228,7 +2245,7 @@
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;
458 @@ -2482,6 +2499,7 @@
460 ret = __commit_write(&th, inode, page, from, to, &need_balance) ;
462 + /* i_sem is held, i_size_read is not required */
463 if (pos > inode->i_size) {
465 /* If the file have grown beyond the border where it
466 @@ -2495,7 +2513,7 @@
467 journal_begin(&th, inode->i_sb, 1) ;
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) ;
475 @@ -2685,6 +2703,79 @@
476 reiserfs_get_block_direct_io) ;
479 +int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
480 + struct inode *inode = dentry->d_inode ;
482 + unsigned int ia_valid = attr->ia_valid ;
484 + if (ia_valid & ATTR_SIZE) {
485 + /* version 2 items will be caught by the s_maxbytes check
486 + ** done for us in vmtruncate
488 + if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
489 + attr->ia_size > MAX_NON_LFS)
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.
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) ;
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 */
522 + error = inode_change_ok(inode, attr) ;
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);
533 + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
536 + error = inode_setattr(inode, attr) ;
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);
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
559 unsigned long write_from ;
560 unsigned long blocksize = inode->i_sb->s_blocksize ;
562 - if (inode->i_size == 0) {
563 + if (i_size_read(inode) == 0) {
564 inode->u.reiserfs_i.i_flags |= i_nopack_mask;
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
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
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
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
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>
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)
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);
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);
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;
623 if ( retval == IO_ERROR ) {
624 return ERR_PTR(-EIO);
626 struct inode * inode;
627 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
628 struct reiserfs_transaction_handle th ;
631 if (!(inode = new_inode(dir->i_sb))) {
637 + locked = reiserfs_cache_default_acl (dir);
639 + reiserfs_write_lock_xattrs (inode->i_sb);
641 journal_begin(&th, dir->i_sb, jbegin_count) ;
642 retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
645 + reiserfs_write_unlock_xattrs (inode->i_sb);
651 struct inode * inode;
652 struct reiserfs_transaction_handle th ;
653 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
656 if (!(inode = new_inode(dir->i_sb))) {
662 + locked = reiserfs_cache_default_acl (dir);
664 + reiserfs_write_lock_xattrs (inode->i_sb);
666 journal_begin(&th, dir->i_sb, jbegin_count) ;
668 retval = reiserfs_new_inode(&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
671 + reiserfs_write_unlock_xattrs (inode->i_sb);
677 struct inode * inode;
678 struct reiserfs_transaction_handle th ;
679 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
682 mode = S_IFDIR | mode;
683 if (!(inode = new_inode(dir->i_sb))) {
688 + locked = reiserfs_cache_default_acl (dir);
690 + reiserfs_write_lock_xattrs (inode->i_sb);
692 journal_begin(&th, dir->i_sb, jbegin_count) ;
694 /* inc the link count now, so another writer doesn't overflow it while
696 old_format_only (dir->i_sb) ?
697 EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
700 + reiserfs_write_unlock_xattrs (inode->i_sb);
706 struct reiserfs_transaction_handle th ;
707 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
710 if (!(inode = new_inode(parent_dir->i_sb))) {
713 @@ -896,11 +934,14 @@
714 memcpy (name, symname, strlen (symname));
715 padd_item (name, item_len, strlen (symname));
717 + /* We would inherit the default ACL here, but symlinks don't get ACLs */
719 journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
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);
729 reiserfs_update_inode_transaction(inode) ;
730 reiserfs_update_inode_transaction(parent_dir) ;
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;
736 // must be sure this inode is written with this transaction
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)
745 - struct inode *inode = old_dentry->d_inode;
747 struct reiserfs_transaction_handle th ;
748 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
749 @@ -986,6 +1026,10 @@
753 +static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
755 + return __reiserfs_link (old_dentry->d_inode, dir, dentry);
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,
770 + set_posix_acl: reiserfs_set_acl,
771 + get_posix_acl: reiserfs_get_acl,
773 + permission: reiserfs_permission,
777 + * symlink operations.. same as page_symlink_inode_operations, with xattr
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,
789 + set_posix_acl: reiserfs_set_acl,
790 + get_posix_acl: reiserfs_get_acl,
792 + permission: reiserfs_permission,
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 @@
799 void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * inode)
802 + i_size_write(inode, 0);
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;
810 + /* i_sem is held, i_size_read not required */
811 if (n_new_file_size != p_s_inode->i_size)
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
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>
829 struct reiserfs_transaction_handle th ;
831 + reiserfs_xattr_cache_clear (s->s_dev);
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);
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);
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) ;
850 +static void reiserfs_clear_inode (struct inode *inode)
852 + struct posix_acl *acl;
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;
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;
866 struct super_operations reiserfs_sops =
868 read_inode: reiserfs_read_inode,
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,
878 {"noattrs", 0, 0, 0, 1<<REISERFS_ATTRS},
879 {"usrquota", 0, 0, 0, 0},
880 {"grpquota", 0, 0, 0, 0},
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},
887 +# ifdef CONFIG_REISERFS_FS_POSIX_ACL
888 + {"acl", 0, 0, 1<<REISERFS_POSIXACL},
889 + {"noacl", 0, 0, 1<<REISERFS_NO_POSIXACL},
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;
904 /* Update the bitmask, taking care to keep
905 * the bits we're not allowed to change here */
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 */
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 */
923 if (!( *mount_flags & MS_RDONLY ) ) {
924 finish_unfinished( s );
925 handle_data_mode(s, mount_options);
926 + reiserfs_xattr_init (s, *mount_flags);
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);
937 if (reiserfs_parse_options (s, (char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
939 @@ -1378,11 +1427,23 @@
941 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
942 journal_end(&th, s, 1) ;
945 + if (reiserfs_xattr_init (s, s->s_flags)) {
951 /* look for files which were to be removed in previous session */
952 finish_unfinished (s);
956 + if (reiserfs_xattr_init (s, s->s_flags)) {
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 );
969 ret = reiserfs_journal_cache_init();
972 - return register_filesystem(&reiserfs_fs_type);
973 + if (ret) goto failed_reiserfs_journal_cache_init;
975 + ret = reiserfs_xattr_cache_init();
976 + if (ret) goto failed_xattr_cache_init;
978 + ret = reiserfs_xattr_user_init();
979 + if (ret) goto failed_xattr_user_init;
981 + ret = reiserfs_xattr_trusted_init();
982 + if (ret) goto failed_xattr_trusted_init;
984 + ret = reiserfs_xattr_posix_acl_init();
985 + if (ret) goto failed_xattr_posix_acl_init;
987 + return register_filesystem(&reiserfs_fs_type);
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:
999 + reiserfs_proc_unregister_global( "version" );
1000 + reiserfs_proc_info_global_done();
1004 MODULE_DESCRIPTION("ReiserFS journaled filesystem");
1005 @@ -1457,6 +1545,10 @@
1007 static void __exit exit_reiserfs_fs(void)
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
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>
1032 +xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
1034 + struct posix_acl *acl;
1037 + if (!reiserfs_posixacl(inode->i_sb))
1038 + return -EOPNOTSUPP;
1039 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
1043 + acl = posix_acl_from_xattr(value, size);
1044 + if (IS_ERR(acl)) {
1045 + return PTR_ERR(acl);
1047 + error = posix_acl_valid(acl);
1049 + goto release_and_out;
1054 + error = reiserfs_set_acl (inode, type, acl);
1057 + posix_acl_release(acl);
1063 +xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
1065 + struct posix_acl *acl;
1068 + if (!reiserfs_posixacl(inode->i_sb))
1069 + return -EOPNOTSUPP;
1071 + acl = reiserfs_get_acl (inode, type);
1073 + return PTR_ERR(acl);
1076 + error = posix_acl_to_xattr(acl, buffer, size);
1077 + posix_acl_release(acl);
1084 + * Convert from filesystem to in-memory representation.
1086 +static struct posix_acl *
1087 +posix_acl_from_disk(const void *value, size_t size)
1089 + const char *end = (char *)value + size;
1091 + struct posix_acl *acl;
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);
1103 + return ERR_PTR(-EINVAL);
1106 + acl = posix_acl_alloc(count, GFP_NOFS);
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)
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:
1121 + value = (char *)value +
1122 + sizeof(reiserfs_acl_entry_short);
1123 + acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
1128 + value = (char *)value + sizeof(reiserfs_acl_entry);
1129 + if ((char *)value > end)
1131 + acl->a_entries[n].e_id =
1132 + le32_to_cpu(entry->e_id);
1144 + posix_acl_release(acl);
1145 + return ERR_PTR(-EINVAL);
1149 + * Convert from in-memory to filesystem representation.
1152 +posix_acl_to_disk(const struct posix_acl *acl, size_t *size)
1154 + reiserfs_acl_header *ext_acl;
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);
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) {
1173 + cpu_to_le32(acl->a_entries[n].e_id);
1174 + e += sizeof(reiserfs_acl_entry);
1177 + case ACL_USER_OBJ:
1178 + case ACL_GROUP_OBJ:
1181 + e += sizeof(reiserfs_acl_entry_short);
1188 + return (char *)ext_acl;
1192 + return ERR_PTR(-EINVAL);
1196 + * Inode operation get_posix_acl().
1198 + * inode->i_sem: down
1199 + * BKL held [before 2.5.x]
1202 +reiserfs_get_acl(struct inode *inode, int type)
1204 + char *name, *value;
1205 + struct posix_acl *acl, **p_acl;
1210 + case ACL_TYPE_ACCESS:
1211 + name = XATTR_NAME_ACL_ACCESS;
1212 + p_acl = &inode->u.reiserfs_i.i_acl_access;
1214 + case ACL_TYPE_DEFAULT:
1215 + name = XATTR_NAME_ACL_DEFAULT;
1216 + p_acl = &inode->u.reiserfs_i.i_acl_default;
1219 + return ERR_PTR (-EINVAL);
1222 + if (IS_ERR (*p_acl)) {
1223 + if (PTR_ERR (*p_acl) == -ENODATA)
1225 + } else if (*p_acl != NULL)
1226 + return posix_acl_dup (*p_acl);
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);
1234 + return ERR_PTR (size);
1237 + value = kmalloc (size, GFP_NOFS);
1239 + return ERR_PTR (-ENOMEM);
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 */
1246 + *p_acl = ERR_PTR (-ENODATA);
1247 + } else if (retval < 0) {
1248 + acl = ERR_PTR(retval);
1250 + acl = posix_acl_from_disk(value, retval);
1251 + *p_acl = posix_acl_dup (acl);
1259 + * Inode operation set_posix_acl().
1261 + * inode->i_sem: down
1262 + * BKL held [before 2.5.x]
1265 +reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
1268 + void *value = NULL;
1269 + struct posix_acl **p_acl;
1273 + if (S_ISLNK(inode->i_mode))
1274 + return -EOPNOTSUPP;
1278 + case ACL_TYPE_ACCESS:
1279 + name = XATTR_NAME_ACL_ACCESS;
1280 + p_acl = &inode->u.reiserfs_i.i_acl_access;
1282 + mode_t mode = inode->i_mode;
1283 + error = posix_acl_equiv_mode (acl, &mode);
1287 + inode->i_mode = mode;
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;
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);
1309 + error = reiserfs_xattr_del (inode, name);
1310 + if (error == -ENODATA)
1318 + /* Release the old one */
1319 + if (!IS_ERR (*p_acl) && *p_acl)
1320 + posix_acl_release (*p_acl);
1323 + *p_acl = ERR_PTR (-ENODATA);
1325 + *p_acl = posix_acl_dup (acl);
1331 +/* dir->i_sem: down,
1332 + * inode is new and not released into the wild yet */
1334 +reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode)
1336 + struct posix_acl *acl;
1339 + /* ACLs only get applied to files and directories */
1340 + if (S_ISLNK (inode->i_mode))
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)
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;
1356 + acl = reiserfs_get_acl (dir, ACL_TYPE_DEFAULT);
1357 + if (IS_ERR (acl)) {
1358 + if (PTR_ERR (acl) == -ENODATA)
1360 + return PTR_ERR (acl);
1364 + struct posix_acl *acl_copy;
1365 + mode_t mode = inode->i_mode;
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);
1375 + /* Now we reconcile the new ACL and the mode,
1376 + potentially modifying both */
1377 + acl_copy = posix_acl_clone (acl, GFP_NOFS);
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;
1390 + /* If we need an ACL.. */
1391 + if (need_acl > 0) {
1392 + err = reiserfs_set_acl (inode, ACL_TYPE_ACCESS, acl_copy);
1394 + goto cleanup_copy;
1398 + posix_acl_release (acl_copy);
1400 + posix_acl_release (acl);
1403 + /* no ACL, apply umask */
1404 + inode->i_mode &= ~current->fs->umask;
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 */
1414 +reiserfs_cache_default_acl (struct inode *inode)
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);
1431 +__reiserfs_permission (struct inode *inode, int mask, int need_lock)
1433 + int mode = inode->i_mode;
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)))
1440 + /* Nobody gets write access to an immutable file */
1441 + if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
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))
1449 + if (current->fsuid == inode->i_uid) {
1451 + } else if (reiserfs_posixacl(inode->i_sb) &&
1452 + get_inode_sd_version (inode) != STAT_DATA_V1) {
1453 + struct posix_acl *acl;
1455 + /* ACL can't contain additional permissions if
1456 + the ACL_MASK entry is 0 */
1457 + if (!(mode & S_IRWXG))
1458 + goto check_groups;
1461 + reiserfs_read_lock_xattrs (inode->i_sb);
1462 + acl = reiserfs_get_acl (inode, ACL_TYPE_ACCESS);
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);
1472 + int err = posix_acl_permission (inode, acl, mask);
1473 + posix_acl_release (acl);
1474 + if (err == -EACCES) {
1475 + goto check_capabilities;
1479 + goto check_groups;
1484 + if (in_group_p(inode->i_gid))
1487 + if ((mode & mask & S_IRWXO) == mask)
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))
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))))
1503 +reiserfs_permission (struct inode *inode, int mask)
1505 + return __reiserfs_permission (inode, mask, 1);
1509 +reiserfs_permission_locked (struct inode *inode, int mask)
1511 + return __reiserfs_permission (inode, mask, 0);
1515 +reiserfs_acl_chmod (struct inode *inode)
1517 + struct posix_acl *acl, *clone;
1520 + if (S_ISLNK(inode->i_mode))
1521 + return -EOPNOTSUPP;
1523 + if (get_inode_sd_version (inode) == STAT_DATA_V1 ||
1524 + !reiserfs_posixacl(inode->i_sb))
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);
1535 + return PTR_ERR(acl);
1536 + clone = posix_acl_clone(acl, GFP_NOFS);
1537 + posix_acl_release(acl);
1540 + error = posix_acl_chmod_masq(clone, inode->i_mode);
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);
1546 + posix_acl_release(clone);
1551 +posix_acl_access_get(struct inode *inode, const char *name,
1552 + void *buffer, size_t size)
1554 + if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
1556 + return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
1560 +posix_acl_access_set(struct inode *inode, const char *name,
1561 + const void *value, size_t size, int flags)
1563 + if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
1565 + return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
1569 +posix_acl_access_del (struct inode *inode, const char *name)
1571 + struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_access;
1572 + if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
1574 + if (!IS_ERR (*acl) && *acl) {
1575 + posix_acl_release (*acl);
1576 + *acl = ERR_PTR (-ENODATA);
1583 +posix_acl_access_list (struct inode *inode, const char *name, int namelen, char *out)
1585 + int len = namelen;
1586 + if (!reiserfs_posixacl (inode->i_sb))
1589 + memcpy (out, name, len);
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,
1603 +posix_acl_default_get (struct inode *inode, const char *name,
1604 + void *buffer, size_t size)
1606 + if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
1608 + return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
1612 +posix_acl_default_set(struct inode *inode, const char *name,
1613 + const void *value, size_t size, int flags)
1615 + if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
1617 + return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
1621 +posix_acl_default_del (struct inode *inode, const char *name)
1623 + struct posix_acl **acl = &inode->u.reiserfs_i.i_acl_default;
1624 + if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
1626 + if (!IS_ERR (*acl) && *acl) {
1627 + posix_acl_release (*acl);
1628 + *acl = ERR_PTR (-ENODATA);
1635 +posix_acl_default_list (struct inode *inode, const char *name, int namelen, char *out)
1637 + int len = namelen;
1638 + if (!reiserfs_posixacl (inode->i_sb))
1641 + memcpy (out, name, len);
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,
1655 +reiserfs_xattr_posix_acl_init (void)
1658 + err = reiserfs_xattr_register_handler (&posix_acl_access_handler);
1660 + err = reiserfs_xattr_register_handler (&posix_acl_default_handler);
1665 +reiserfs_xattr_posix_acl_exit (void)
1668 + err = reiserfs_xattr_unregister_handler (&posix_acl_access_handler);
1670 + err = reiserfs_xattr_unregister_handler (&posix_acl_default_handler);
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
1678 + * linux/fs/reiserfs/xattr.c
1680 + * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com>
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.
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
1699 + * The file contents are the text of the EA. The size is known based on the
1700 + * stat data describing the file.
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.
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>
1723 +#define FL_READONLY 128
1724 +#define FL_DIR_SEM_HELD 256
1725 +#define PRIVROOT_NAME ".reiserfs_priv"
1726 +#define XAROOT_NAME "xattrs"
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);
1735 +static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix);
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
1740 +static struct dentry *
1741 +reiserfs_get_priv_root (struct super_block *s)
1743 + struct dentry *dentry = NULL;
1744 + struct qstr privroot;
1746 + struct reiserfs_dir_entry de;
1747 + INITIALIZE_PATH (path);
1749 + privroot.name = PRIVROOT_NAME;
1750 + privroot.len = strlen (privroot.name);
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));
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);
1767 + d_instantiate (dentry, inode);
1768 + inode->u.reiserfs_i.i_flags |= i_priv_object;
1776 +static struct dentry *
1777 +reiserfs_create_priv_root (struct super_block *sb)
1780 + struct inode *inode = sb->s_root->d_inode;
1781 + struct dentry *privroot;
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);
1789 + return ERR_PTR (-ENOMEM);
1791 + down (&inode->i_sem);
1792 + ret = inode->i_op->mkdir (inode, privroot, 0700);
1793 + up (&inode->i_sem);
1797 + return ERR_PTR (ret);
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);
1810 +static struct dentry *
1811 +create_xa_root (struct super_block *sb)
1813 + struct dentry *privroot = dget (sb->u.reiserfs_sb.priv_root);
1814 + struct dentry *xaroot;
1816 + /* This needs to be created at mount-time */
1818 + return ERR_PTR(-EOPNOTSUPP);
1820 + xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
1821 + if (IS_ERR (xaroot)) {
1823 + } else if (!xaroot->d_inode) {
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);
1832 + return ERR_PTR (err);
1834 + sb->u.reiserfs_sb.xattr_root = dget (xaroot);
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)
1849 + struct dentry *privroot = dget (s->u.reiserfs_sb.priv_root);
1850 + struct dentry *xaroot = NULL;
1852 + if (IS_ERR (privroot) || !privroot)
1855 + xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
1856 + if (IS_ERR (xaroot)) {
1858 + } else if (!xaroot->d_inode) {
1864 + s->u.reiserfs_sb.xattr_root = dget (xaroot);
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.
1876 +static inline struct dentry *
1877 +get_xa_root (struct super_block *s)
1879 + struct dentry *dentry = s->u.reiserfs_sb.xattr_root;
1882 + dentry = __get_xa_root (s);
1888 +/* Same as above, but only returns a valid dentry or NULL */
1890 +reiserfs_get_xa_root (struct super_block *sb)
1892 + struct dentry *dentry;
1894 + dentry = get_xa_root (sb);
1895 + if (IS_ERR (dentry)) {
1897 + } else if (dentry && !dentry->d_inode) {
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)
1911 + struct dentry *xaroot, *xadir;
1914 + xaroot = get_xa_root (inode->i_sb);
1915 + if (IS_ERR (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))
1924 + return ERR_PTR (-ENODATA);
1927 + /* ok, we have xaroot open */
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)) {
1938 + if (!xadir->d_inode) {
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);
1948 + return ERR_PTR (err);
1951 + if (!xadir->d_inode) {
1954 + return ERR_PTR (-ENODATA);
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)
1968 + struct dentry *xadir, *xafile;
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) {
1976 + return ERR_PTR (-ENODATA);
1979 + xafile = lookup_one_len (name, xadir, strlen (name));
1980 + if (IS_ERR (xafile)) {
1982 + return ERR_PTR (PTR_ERR (xafile));
1985 + if (xafile->d_inode) { /* file exists */
1986 + if (flags & XATTR_CREATE) {
1991 + } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
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,
2008 + xafile = ERR_PTR (err);
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)
2017 + struct dentry *xafile;
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) {
2025 + return ERR_PTR (-ENODATA);
2028 + fp = dentry_open (xafile, NULL, O_RDWR);
2029 + /* dentry_open dputs the dentry if it fails */
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
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.
2045 + * we're called with i_sem held, so there are no worries about the directory
2046 + * changing underneath us.
2048 +static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir)
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;
2055 + struct item_head * ih, tmp_ih;
2059 + char small_buf[32] ; /* avoid kmalloc if we can */
2060 + struct reiserfs_de_head *deh;
2065 + struct reiserfs_dir_entry de;
2068 + /* form key for search the next directory entry using f_pos field of
2070 + next_pos = max_reiserfs_offset(inode);
2074 + if (next_pos <= DOT_DOT_OFFSET)
2076 + make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
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
2082 + pathrelse(&path_to_entry);
2086 + if (search_res == NAME_NOT_FOUND)
2087 + de.de_entry_num--;
2089 + set_de_name_and_namelen(&de);
2090 + entry_num = de.de_entry_num;
2091 + deh = &(de.de_deh[entry_num]);
2096 + if (!is_direntry_le_ih(ih)) {
2097 +reiserfs_warning("not direntry %h\n", ih);
2100 + copy_item_head(&tmp_ih, ih);
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",
2107 + if (deh_offset(deh) <= DOT_DOT_OFFSET) {
2111 + /* look for the previous entry in the directory */
2112 + next_pos = deh_offset (deh) - 1;
2114 + if (!de_visible (deh))
2115 + /* it is hidden entry */
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);
2123 + if (!d_name[d_reclen - 1])
2124 + d_reclen = strlen (d_name);
2126 + if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
2127 + /* too big to send back to VFS */
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))
2137 + if (d_reclen <= 32) {
2138 + local_buf = small_buf ;
2140 + local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
2142 + pathrelse (&path_to_entry);
2145 + if (item_moved (&tmp_ih, &path_to_entry)) {
2146 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
2148 + /* sigh, must retry. Do this same offset again */
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);
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
2164 + pathrelse (&path_to_entry);
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) ;
2173 + if (local_buf != small_buf) {
2174 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
2179 + pathrelse (&path_to_entry);
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
2190 +int xattr_readdir(struct file *file, filldir_t filler, void *buf)
2192 + struct inode *inode = file->f_dentry->d_inode;
2193 + int res = -ENOTDIR;
2194 + if (!file->f_op || !file->f_op->readdir)
2196 + down(&inode->i_sem);
2197 + down(&inode->i_zombie);
2199 + if (!IS_DEADDIR(inode)) {
2201 + res = __xattr_readdir(file, buf, filler);
2204 + up(&inode->i_zombie);
2205 + up(&inode->i_sem);
2211 +/* Internal operations on file data */
2213 +reiserfs_put_page(struct page *page)
2216 + page_cache_release(page);
2219 +static struct page *
2220 +reiserfs_get_page(struct inode *dir, unsigned long n)
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);
2232 + if (!Page_Uptodate(page))
2235 + if (!PageChecked(page))
2236 + ext2_check_page(page);
2238 + if (PageError(page))
2244 + reiserfs_put_page(page);
2245 + return ERR_PTR(-EIO);
2248 +static inline __u32
2249 +xattr_hash (const char *msg, int len)
2251 + return csum_partial (msg, len, 0);
2256 +/* Cache handling */
2257 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
2258 +static struct mb_cache *reiserfs_xattr_cache;
2261 +xa_cache_free_entry (struct mb_cache_entry *ce)
2263 + struct inode *inode;
2267 + inode = (struct inode *)ce->e_block;
2268 + if (inode) /* inode may not be set if this is called in an error case */
2272 +static struct mb_cache_op reiserfs_xa_cache_ops = {
2273 + xa_cache_free_entry
2277 +reiserfs_xattr_cache_init (void)
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),
2284 + if (!reiserfs_xattr_cache)
2291 +reiserfs_xattr_cache_exit (void)
2293 + if (reiserfs_xattr_cache)
2294 + mb_cache_destroy (reiserfs_xattr_cache);
2298 +reiserfs_xattr_cache_clear (kdev_t dev)
2300 + if (reiserfs_xattr_cache)
2301 + mb_cache_shrink (reiserfs_xattr_cache, dev);
2304 +static struct inode *
2305 +xa_cache_lookup (struct inode *inode, __u32 hash)
2307 + struct mb_cache_entry *ce;
2308 + struct inode *xattr_inode;
2310 + if (!reiserfs_xattr_cache)
2313 + ce = mb_cache_entry_find_first (reiserfs_xattr_cache, 0,
2314 + inode->i_dev, hash);
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);
2321 + if (xattr_inode->i_uid == inode->i_uid &&
2322 + xattr_inode->i_gid == inode->i_gid) {
2325 + ce = mb_cache_entry_find_next (ce, 0, inode->i_dev, hash);
2331 + xattr_inode = (struct inode *)ce->e_block;
2332 + mb_cache_entry_release (ce);
2335 + return igrab (xattr_inode);
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. */
2344 +xa_cache_insert (struct inode *xattr_inode, __u32 hash)
2346 + struct mb_cache_entry *ce;
2348 + struct inode *inode = igrab (xattr_inode);
2349 + if (!reiserfs_xattr_cache)
2355 + ce = mb_cache_entry_alloc (reiserfs_xattr_cache);
2360 + error = mb_cache_entry_insert (ce, xattr_inode->i_dev,
2361 + (unsigned long)xattr_inode, &hash);
2363 + mb_cache_entry_free (ce);
2364 + if (error == -EBUSY)
2365 + error = 0; /* if it's already there, it's ok */
2367 + mb_cache_entry_release (ce);
2373 +xa_cache_remove (struct inode *xattr_inode)
2375 + struct mb_cache_entry *ce;
2376 + if (!reiserfs_xattr_cache)
2379 + ce = mb_cache_entry_get (reiserfs_xattr_cache, xattr_inode->i_dev,
2380 + (unsigned long) xattr_inode);
2382 + mb_cache_entry_free (ce);
2384 + /* we would do an iput() here, but cache_ops->free takes care of that */
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) {}
2393 +/* Generic extended attribute operations that can be used by xa plugins */
2396 + * inode->i_sem: down
2399 +reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer,
2400 + size_t buffer_size, int flags)
2404 + struct page *page;
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;
2412 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
2413 + struct dentry *xafile;
2414 + struct inode *link = NULL;
2417 + if (get_inode_sd_version (inode) == STAT_DATA_V1)
2418 + return -EOPNOTSUPP;
2420 + /* Empty xattrs are ok, they're just empty files, no hash */
2421 + if (buffer && buffer_size)
2422 + xahash = xattr_hash (buffer, buffer_size);
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);
2428 + if (IS_ERR (xafile) && PTR_ERR (xafile) != -ENODATA) {
2431 + return PTR_ERR (xafile);
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 */
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);
2450 + err = reiserfs_xattr_link_to_inode (link, inode, name);
2457 + fp = open_xa_file (inode, name, flags);
2458 + if (IS_ERR (fp)) {
2459 + err = PTR_ERR (fp);
2463 + xinode = fp->f_dentry->d_inode;
2465 + /* we need to copy it off.. */
2466 + if (xinode->i_nlink > 1) {
2468 + err = reiserfs_xattr_del (inode, name);
2471 + /* We just killed the old one, we're not replacing anymore */
2472 + if (flags & XATTR_REPLACE)
2473 + flags &= ~XATTR_REPLACE;
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);
2485 + mapping = xinode->i_mapping;
2486 + while (buffer_pos < buffer_size || buffer_pos == 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;
2493 + chunk = buffer_size - buffer_pos;
2495 + page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
2496 + if (IS_ERR (page)) {
2497 + err = PTR_ERR (page);
2502 + data = page_address (page);
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);
2514 + err = mapping->a_ops->prepare_write (fp, page, page_offset,
2515 + page_offset + chunk + skip);
2518 + memcpy (data + skip, buffer + buffer_pos, chunk);
2519 + err = mapping->a_ops->commit_write (fp, page, page_offset,
2520 + page_offset + chunk + skip);
2522 + UnlockPage (page);
2523 + reiserfs_put_page (page);
2524 + buffer_pos += chunk;
2525 + file_pos += chunk;
2527 + if (err || buffer_size == 0 || !buffer)
2532 + up (&xinode->i_sem);
2533 + xa_cache_insert (xinode, xahash);
2541 + * inode->i_sem: down
2544 +reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer,
2545 + size_t buffer_size)
2550 + size_t file_pos = 0;
2551 + size_t buffer_pos = 0;
2552 + struct page *page;
2553 + struct inode *xinode;
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;
2561 + fp = open_xa_file (inode, name, FL_READONLY);
2562 + if (IS_ERR (fp)) {
2563 + err = PTR_ERR (fp);
2567 + xinode = fp->f_dentry->d_inode;
2568 + isize = xinode->i_size;
2570 + /* Just return the size needed */
2571 + if (buffer == NULL) {
2572 + err = isize - sizeof (struct reiserfs_xattr_header);
2576 + if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) {
2581 + while (file_pos < isize) {
2584 + size_t page_offset;
2586 + if (isize - file_pos > PAGE_CACHE_SIZE)
2587 + chunk = PAGE_CACHE_SIZE;
2589 + chunk = isize - file_pos;
2591 + page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
2592 + if (IS_ERR (page)) {
2593 + err = PTR_ERR (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);
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);
2611 + hash = le32_to_cpu (rxh->h_hash);
2613 + memcpy (buffer + buffer_pos, data + skip, chunk);
2614 + UnlockPage (page);
2615 + reiserfs_put_page (page);
2616 + file_pos += chunk;
2617 + buffer_pos += chunk;
2620 + err = isize - sizeof (struct reiserfs_xattr_header);
2622 + if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash)
2625 + /* Insert this inode into the xattr cache so we can attempt to do
2626 + * decent sharing.. */
2628 + xa_cache_insert (xinode, hash);
2638 +__reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen)
2640 + struct dentry *file;
2641 + struct inode *dir = xadir->d_inode;
2644 + file = lookup_one_len (name, xadir, namelen);
2645 + if (IS_ERR (file)) {
2646 + err = PTR_ERR (file);
2648 + } else if (!file->d_inode) {
2653 + /* Skip directories.. */
2654 + if (S_ISDIR (file->d_inode->i_mode))
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);
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));
2667 + err = dir->i_op->unlink (dir, file);
2680 +reiserfs_xattr_del (struct inode *inode, const char *name)
2682 + struct dentry *dir;
2685 + dir = open_xa_dir (inode, FL_READONLY);
2686 + if (IS_ERR (dir)) {
2687 + err = PTR_ERR (dir);
2691 + err = __reiserfs_xattr_del (dir, name, strlen (name));
2698 +#if 0 /* def CONFIG_REISERFS_FS_XATTR_SHARING */
2700 +reiserfs_xattr_link_to_inode (struct inode *xattr_inode,
2701 + struct inode *dst_inode, const char *dst_name)
2703 + struct dentry *dst_dentry, *xadir;
2706 + xadir = open_xa_dir (dst_inode, 0);
2707 + if (IS_ERR (xadir))
2708 + return PTR_ERR (xadir);
2710 + dst_dentry = get_xa_file_dentry (dst_inode, dst_name, FL_READONLY);
2711 + if (IS_ERR (dst_dentry)) {
2713 + } else if (dst_dentry->d_inode) {
2718 + err = __reiserfs_link (xattr_inode, xadir->d_inode, dst_dentry);
2721 + dput (dst_dentry);
2727 +reiserfs_xattr_link (struct inode *src_inode, const char *src_name,
2728 + struct inode *dst_inode, const char *dst_name)
2730 + struct dentry *src_dentry;
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);
2741 + err = reiserfs_xattr_link_to_inode (src_dentry->d_inode,
2742 + dst_inode, dst_name);
2743 + dput (src_dentry);
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. */
2753 +reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen,
2754 + loff_t offset, ino_t ino, unsigned int d_type)
2756 + struct dentry *xadir = (struct dentry *)buf;
2758 + return __reiserfs_xattr_del (xadir, name, namelen);
2763 +reiserfs_delete_xattrs (struct inode *inode)
2766 + struct dentry *dir, *root;
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))
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);
2782 + } else if (!dir->d_inode) {
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 */
2795 + err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir);
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);
2809 + reiserfs_warning (inode->i_sb, "Couldn't remove all entries in directory\n");
2820 +struct reiserfs_chown_buf {
2821 + struct inode *inode;
2822 + struct dentry *xadir;
2823 + struct iattr *attrs;
2826 +/* XXX: If there is a better way to do this, I'd love to hear about it */
2828 +reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen,
2829 + loff_t offset, ino_t ino, unsigned int d_type)
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;
2836 + xafile = lookup_one_len (name, xadir, namelen);
2837 + if (IS_ERR (xafile))
2838 + return PTR_ERR (xafile);
2839 + else if (!xafile->d_inode) {
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;
2855 + nameptr = reiserfs_kmalloc (namelen+1, GFP_NOFS, inode->i_sb);
2857 + nameptr = namebuf;
2859 + memcpy (nameptr, name, namelen);
2860 + nameptr[namelen] = 0;
2861 + size = reiserfs_xattr_get (inode, nameptr, NULL, 0);
2863 + if (nameptr != namebuf)
2864 + reiserfs_kfree (nameptr, namelen, inode->i_sb);
2869 + value = reiserfs_kmalloc (size, GFP_NOFS, inode->i_sb);
2871 + if (nameptr != namebuf)
2872 + reiserfs_kfree (nameptr, namelen, inode->i_sb);
2877 + ret = reiserfs_xattr_get (inode, nameptr, value, size);
2879 + if (nameptr != namebuf)
2880 + reiserfs_kfree (nameptr, namelen, inode->i_sb);
2881 + reiserfs_kfree (value, size, inode->i_sb);
2886 + ret = reiserfs_xattr_del (inode, nameptr);
2890 + if (nameptr != namebuf)
2891 + reiserfs_kfree (nameptr, namelen, inode->i_sb);
2892 + reiserfs_kfree (value, size, inode->i_sb);
2896 + ret = reiserfs_xattr_set (inode, nameptr, value, size, FL_DIR_SEM_HELD);
2897 + reiserfs_kfree (value, size, inode->i_sb);
2899 + if (nameptr != namebuf)
2900 + reiserfs_kfree (nameptr, namelen, inode->i_sb);
2905 + xafile = lookup_one_len (nameptr, xadir, namelen);
2906 + if (IS_ERR (xafile))
2907 + return PTR_ERR (xafile);
2908 + else if (!xafile->d_inode) {
2915 + if (!S_ISDIR (xafile->d_inode->i_mode))
2916 + err = notify_change (xafile, attrs);
2923 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
2926 + struct dentry *dir;
2928 + struct reiserfs_chown_buf buf;
2929 + unsigned int ia_valid = attrs->ia_valid;
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))
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);
2945 + } else if (!dir->d_inode) {
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 */
2959 + attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
2961 + buf.attrs = attrs;
2962 + buf.inode = inode;
2964 + err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf);
2970 + err = notify_change (dir, attrs);
2977 + attrs->ia_valid = ia_valid;
2982 +/* Actual operations that are exported to VFS-land */
2985 + * Inode operation getxattr()
2986 + * dentry->d_inode->i_sem down
2987 + * BKL held [before 2.5.x]
2990 +reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer,
2993 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
2996 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
2997 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
2998 + return -EOPNOTSUPP;
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);
3010 + * Inode operation setxattr()
3012 + * dentry->d_inode->i_sem down
3013 + * BKL held [before 2.5.x]
3016 +reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value,
3017 + size_t size, int flags)
3019 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
3022 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
3023 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
3024 + return -EOPNOTSUPP;
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);
3031 + dentry->d_inode->i_ctime = CURRENT_TIME;
3032 + mark_inode_dirty (dentry->d_inode);
3038 + * Inode operation removexattr()
3040 + * dentry->d_inode->i_sem down
3041 + * BKL held [before 2.5.x]
3044 +reiserfs_removexattr (struct dentry *dentry, const char *name)
3047 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
3049 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
3050 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
3051 + return -EOPNOTSUPP;
3053 + down (&dentry->d_inode->i_zombie);
3054 + reiserfs_read_lock_xattrs (dentry->d_sb);
3056 + /* Deletion pre-operation */
3058 + err = xah->del (dentry->d_inode, name);
3060 + reiserfs_read_unlock_xattrs (dentry->d_sb);
3061 + up (&dentry->d_inode->i_zombie);
3066 + err = reiserfs_xattr_del (dentry->d_inode, name);
3067 + reiserfs_read_unlock_xattrs (dentry->d_sb);
3068 + up (&dentry->d_inode->i_zombie);
3070 + dentry->d_inode->i_ctime = CURRENT_TIME;
3071 + mark_inode_dirty (dentry->d_inode);
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 {
3085 + struct inode *r_inode;
3089 +reiserfs_listxattr_filler (void *buf, const char *name, int namelen,
3090 + loff_t offset, ino_t ino, unsigned int d_type)
3092 + struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
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 */
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);
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);
3108 + b->r_pos += len + 1;
3116 +__reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
3119 + struct dentry *dir;
3121 + struct reiserfs_listxattr_buf buf;
3123 + if (!dentry->d_inode)
3126 + if (!reiserfs_xattrs(dentry->d_sb) ||
3127 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
3128 + return -EOPNOTSUPP;
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 */
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 */
3147 + buf.r_buf = buffer;
3148 + buf.r_size = buffer ? size : 0;
3150 + buf.r_inode = dentry->d_inode;
3152 + err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf);
3156 + if (buf.r_pos > buf.r_size && buffer != NULL)
3169 + * Inode operation listxattr()
3171 + * dentry->d_inode->i_sem down
3172 + * BKL held [before 2.5.x]
3175 +reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
3179 + down(&dentry->d_inode->i_sem);
3180 + error = __reiserfs_listxattr(dentry, buffer, size);
3181 + up(&dentry->d_inode->i_sem);
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;
3190 +static struct reiserfs_xattr_handler *
3191 +find_xattr_handler_prefix (const char *prefix)
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)
3198 + read_unlock (&handler_lock);
3203 +reiserfs_xattr_register_handler (struct reiserfs_xattr_handler *handler)
3206 + struct reiserfs_xattr_handler **xah;
3211 + if (handler->next)
3214 + write_lock (&handler_lock);
3216 + for (xah = &xattr_handlers; *xah; xah=&(*xah)->next) {
3217 + if (strcmp ((*xah)->prefix, handler->prefix) == 0)
3227 + printk ("ReiserFS: Registered xattr handler for %s\n", handler->prefix);
3230 + write_unlock (&handler_lock);
3235 +reiserfs_xattr_unregister_handler (struct reiserfs_xattr_handler *handler)
3237 + struct reiserfs_xattr_handler **xah;
3238 + write_lock (&handler_lock);
3240 + xah = &xattr_handlers;
3242 + if (handler == *xah) {
3243 + *xah = handler->next;
3244 + handler->next = NULL;
3245 + write_unlock (&handler_lock);
3247 + printk ("ReiserFS: Unregistered xattr handler for %s\n",
3252 + xah = &(*xah)->next;
3254 + write_unlock (&handler_lock);
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 */
3263 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
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));
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));
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));
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));
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;
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;
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));
3324 + } /* otherwise, already mounted, and remounting */
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. */
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));
3338 + s->s_flags = (s->s_flags & ~MS_POSIXACL) |
3339 + (reiserfs_posixacl (s) ? MS_POSIXACL : 0);
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
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>
3354 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
3355 +# include <linux/reiserfs_acl.h>
3358 +#define XATTR_TRUSTED_PREFIX "trusted."
3361 +trusted_get (struct inode *inode, const char *name, void *buffer, size_t size)
3363 + if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
3366 + if (!reiserfs_xattrs_trusted (inode->i_sb))
3367 + return -EOPNOTSUPP;
3369 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3372 + return reiserfs_xattr_get (inode, name, buffer, size);
3376 +trusted_set (struct inode *inode, const char *name, const void *buffer,
3377 + size_t size, int flags)
3379 + if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
3382 + if (!reiserfs_xattrs_trusted (inode->i_sb))
3383 + return -EOPNOTSUPP;
3385 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3388 + return reiserfs_xattr_set (inode, name, buffer, size, flags);
3392 +trusted_del (struct inode *inode, const char *name)
3394 + if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
3397 + if (!reiserfs_xattrs_trusted (inode->i_sb))
3398 + return -EOPNOTSUPP;
3400 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3407 +trusted_list (struct inode *inode, const char *name, int namelen, char *out)
3409 + int len = namelen;
3411 + if (!reiserfs_xattrs_trusted (inode->i_sb))
3414 + if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
3418 + memcpy (out, name, len);
3424 +struct reiserfs_xattr_handler trusted_handler = {
3425 + prefix: XATTR_TRUSTED_PREFIX,
3429 + list: trusted_list,
3433 +reiserfs_xattr_trusted_init (void)
3435 + return reiserfs_xattr_register_handler (&trusted_handler);
3439 +reiserfs_xattr_trusted_exit (void)
3441 + return reiserfs_xattr_unregister_handler (&trusted_handler);
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
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>
3455 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
3456 +# include <linux/reiserfs_acl.h>
3459 +#define XATTR_USER_PREFIX "user."
3462 +user_get (struct inode *inode, const char *name, void *buffer, size_t size)
3467 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
3470 + if (!reiserfs_xattrs_user (inode->i_sb))
3471 + return -EOPNOTSUPP;
3473 + error = reiserfs_permission_locked (inode, MAY_READ);
3477 + return reiserfs_xattr_get (inode, name, buffer, size);
3481 +user_set (struct inode *inode, const char *name, const void *buffer,
3482 + size_t size, int flags)
3487 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
3490 + if (!reiserfs_xattrs_user (inode->i_sb))
3491 + return -EOPNOTSUPP;
3493 + if (!S_ISREG (inode->i_mode) &&
3494 + (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
3497 + error = reiserfs_permission_locked (inode, MAY_WRITE);
3501 + return reiserfs_xattr_set (inode, name, buffer, size, flags);
3505 +user_del (struct inode *inode, const char *name)
3509 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
3512 + if (!reiserfs_xattrs_user (inode->i_sb))
3513 + return -EOPNOTSUPP;
3515 + if (!S_ISREG (inode->i_mode) &&
3516 + (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
3519 + error = reiserfs_permission_locked (inode, MAY_WRITE);
3527 +user_list (struct inode *inode, const char *name, int namelen, char *out)
3529 + int len = namelen;
3530 + if (!reiserfs_xattrs_user (inode->i_sb))
3534 + memcpy (out, name, len);
3540 +struct reiserfs_xattr_handler user_handler = {
3541 + prefix: XATTR_USER_PREFIX,
3549 +reiserfs_xattr_user_init (void)
3551 + return reiserfs_xattr_register_handler (&user_handler);
3555 +reiserfs_xattr_user_exit (void)
3557 + return reiserfs_xattr_unregister_handler (&user_handler);
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!");
3567 +#ifdef CONFIG_X86_CMPXCHG8
3569 + panic("Kernel compiled for Pentium+, requires CMPXCHG8B feature!");
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
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
3589 #define __xg(x) ((struct __xchg_dummy *)(x))
3592 +#ifdef CONFIG_X86_CMPXCHG8
3593 +#define __ARCH_HAS_GET_SET_64BIT 1
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
3598 "lock cmpxchg8b (%0)\n\t"
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)) )
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.
3616 +static inline unsigned long long get_64bit(unsigned long long * ptr)
3618 + unsigned long low, high;
3620 + __asm__ __volatile__ (
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"
3628 + : "=&b" (low), "=&c" (high)
3630 + : "ax","dx","memory");
3632 + return low | ((unsigned long long) high << 32);
3634 +#endif /* CONFIG_X86_CMPXCHG */
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;
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)
3650 +#define i_size_ordered_init(inode) do { } while (0)
3654 struct list_head i_hash;
3655 struct list_head i_list;
3656 @@ -527,8 +534,65 @@
3657 struct jffs2_inode_info jffs2_i;
3660 +#ifdef __NEED_I_SIZE_ORDERED
3661 + volatile int i_size_version1;
3662 + volatile int i_size_version2;
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.
3676 +static inline loff_t i_size_read(struct inode * inode)
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);
3685 + /* Retry if i_size was possibly modified while sampling. */
3687 + v1 = inode->i_size_version1;
3689 + i_size = inode->i_size;
3691 + v2 = inode->i_size_version2;
3692 + } while (v1 != v2);
3696 +#elif BITS_PER_LONG==64 || !defined(CONFIG_SMP)
3697 + return inode->i_size;
3701 +static inline void i_size_write(struct inode * inode, loff_t i_size)
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);
3707 + inode->i_size_version2++;
3709 + inode->i_size = i_size;
3711 + inode->i_size_version1++;
3712 + wmb(); /* make it visible ASAP */
3714 +#elif BITS_PER_LONG==64 || !defined(CONFIG_SMP)
3715 + inode->i_size = i_size;
3719 static inline void inode_add_bytes(struct inode *inode, loff_t bytes)
3721 inode->i_blocks += bytes >> 9;
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
3742 +#include <linux/init.h>
3743 +#include <linux/posix_acl.h>
3744 +#include <linux/xattr_acl.h>
3746 +#define REISERFS_ACL_VERSION 0x0001
3752 +} reiserfs_acl_entry;
3757 +} reiserfs_acl_entry_short;
3761 +} reiserfs_acl_header;
3763 +static inline size_t reiserfs_acl_size(int count)
3766 + return sizeof(reiserfs_acl_header) +
3767 + count * sizeof(reiserfs_acl_entry_short);
3769 + return sizeof(reiserfs_acl_header) +
3770 + 4 * sizeof(reiserfs_acl_entry_short) +
3771 + (count - 4) * sizeof(reiserfs_acl_entry);
3775 +static inline int reiserfs_acl_count(size_t size)
3778 + size -= sizeof(reiserfs_acl_header);
3779 + s = size - 4 * sizeof(reiserfs_acl_entry_short);
3781 + if (size % sizeof(reiserfs_acl_entry_short))
3783 + return size / sizeof(reiserfs_acl_entry_short);
3785 + if (s % sizeof(reiserfs_acl_entry))
3787 + return s / sizeof(reiserfs_acl_entry) + 4;
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);
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
3810 +reiserfs_xattr_posix_acl_init (void)
3816 +reiserfs_xattr_posix_acl_exit (void)
3822 +reiserfs_acl_chmod (struct inode *inode)
3828 +reiserfs_inherit_default_acl (const struct inode *dir, struct dentry *dentry, struct inode *inode)
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)
3841 - reiserfs_update_sd_size(th, inode, inode->i_size) ;
3842 + reiserfs_update_sd_size(th, inode, i_size_read(inode)) ;
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);
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,
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);
3861 #if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO )
3862 @@ -2081,6 +2087,7 @@
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;
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
3875 +#define REISERFS_XATTR_DIR_SEM(s) ((s)->u.reiserfs_sb.xattr_dir_sem)
3877 #endif /* _LINUX_REISER_FS_H */
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
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;
3893 unsigned long i_tail_trans_id;
3894 struct reiserfs_journal_list *i_tail_jl;
3896 + struct posix_acl *i_acl_access;
3897 + struct posix_acl *i_acl_default;
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
3907 #include <linux/tqueue.h>
3908 +#include <linux/rwsem.h>
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;
3921 /* Definitions of reiserfs on-disk properties: */
3922 @@ -486,6 +490,11 @@
3923 REISERFS_DATA_WRITEBACK,
3927 + REISERFS_XATTRS_USER,
3928 + REISERFS_POSIXACL,
3929 + REISERFS_NO_XATTRS_USER,
3930 + REISERFS_NO_POSIXACL,
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)
3945 +# define reiserfs_xattrs_trusted(s) (0)
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
3955 + File: linux/reiserfs_xattr.h
3958 +#include <linux/config.h>
3959 +#include <linux/init.h>
3960 +#include <linux/xattr.h>
3962 +/* Magic value in header */
3963 +#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
3965 +struct reiserfs_xattr_header {
3966 + __u32 h_magic; /* magic number for identification */
3967 + __u32 h_hash; /* hash of the value */
3972 +struct reiserfs_xattr_handler {
3974 + int (*get)(struct inode *inode, const char *name, void *buffer,
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;
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);
3997 +reiserfs_write_lock_xattrs(struct super_block *sb)
3999 + down_write (&REISERFS_XATTR_DIR_SEM(sb));
4002 +reiserfs_write_unlock_xattrs(struct super_block *sb)
4004 + up_write (&REISERFS_XATTR_DIR_SEM(sb));
4007 +reiserfs_read_lock_xattrs(struct super_block *sb)
4009 + down_read (&REISERFS_XATTR_DIR_SEM(sb));
4012 +reiserfs_read_unlock_xattrs(struct super_block *sb)
4014 + up_read (&REISERFS_XATTR_DIR_SEM(sb));
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)
4027 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
4029 + s->s_flags = (s->s_flags & ~MS_POSIXACL); /* to be sure */
4034 +reiserfs_delete_xattrs (struct inode *inode)
4040 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
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 *,
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);
4059 +reiserfs_xattr_cache_init (void)
4065 +reiserfs_xattr_cache_exit (void)
4071 +reiserfs_xattr_cache_clear (kdev_t dev)
4075 +#ifdef CONFIG_REISERFS_FS_XATTR_USER
4076 +extern int reiserfs_xattr_user_init (void) __init;
4077 +extern int reiserfs_xattr_user_exit (void);
4080 +reiserfs_xattr_user_init (void)
4086 +reiserfs_xattr_user_exit (void)
4091 +#ifdef CONFIG_REISERFS_FS_XATTR_TRUSTED
4092 +extern int reiserfs_xattr_trusted_init (void) __init;
4093 +extern int reiserfs_xattr_trusted_exit (void);
4096 +reiserfs_xattr_trusted_init (void)
4102 +reiserfs_xattr_trusted_exit (void)
4108 +#endif /* __KERNEL__ */