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