]> git.pld-linux.org Git - packages/kernel.git/blame - 01-reiserfs-xattrs-2.4.23+datalogging+quota-03
- xen update to 3.0.4
[packages/kernel.git] / 01-reiserfs-xattrs-2.4.23+datalogging+quota-03
CommitLineData
f701fa52
AM
1diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/Config.in linux-2.4.23.xattr/fs/Config.in
2--- linux-2.4.23.datalogging+quota/fs/Config.in 2003-12-11 12:53:34.170047728 -0500
3+++ linux-2.4.23.xattr/fs/Config.in 2003-12-11 12:55:03.321494648 -0500
4@@ -13,6 +13,8 @@ tristate 'Kernel automounter version 4 s
5 tristate 'Reiserfs support' CONFIG_REISERFS_FS
6 dep_mbool ' Enable reiserfs debug mode' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS
7 dep_mbool ' Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS
8+dep_mbool ' ReiserFS extended attributes' CONFIG_REISERFS_FS_XATTR $CONFIG_REISERFS_FS
9+dep_mbool ' ReiserFS extended user attributes' CONFIG_REISERFS_FS_XATTR_USER $CONFIG_REISERFS_FS_XATTR
10
11 dep_tristate 'ADFS file system support (EXPERIMENTAL)' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
12 dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
13diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/Makefile linux-2.4.23.xattr/fs/reiserfs/Makefile
14--- linux-2.4.23.datalogging+quota/fs/reiserfs/Makefile 2003-12-11 12:54:15.917701120 -0500
15+++ linux-2.4.23.xattr/fs/reiserfs/Makefile 2003-12-11 12:55:03.322494496 -0500
16@@ -12,6 +12,9 @@ O_TARGET := reiserfs.o
17 obj-y := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o super.o prints.o objectid.o \
18 lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o item_ops.o ioctl.o procfs.o
19
20+obj-$(CONFIG_REISERFS_FS_XATTR) += xattr.o
21+obj-$(CONFIG_REISERFS_FS_XATTR_USER) += xattr_user.o
22+
23 obj-m := $(O_TARGET)
24
25 # gcc -O2 (the kernel default) is overaggressive on ppc32 when many inline
26diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/dir.c linux-2.4.23.xattr/fs/reiserfs/dir.c
27--- linux-2.4.23.datalogging+quota/fs/reiserfs/dir.c 2003-12-11 12:53:11.351516672 -0500
28+++ linux-2.4.23.xattr/fs/reiserfs/dir.c 2003-12-11 12:55:03.322494496 -0500
29@@ -110,6 +110,15 @@ static int reiserfs_readdir (struct file
30 /* too big to send back to VFS */
31 continue ;
32 }
33+
34+ /* Ignore the .reiserfs_priv entry */
35+ if (reiserfs_xattrs (inode->i_sb) &&
36+ !old_format_only(inode->i_sb) &&
37+ inode->i_sb->u.reiserfs_sb.priv_root &&
38+ inode->i_sb->u.reiserfs_sb.priv_root->d_inode &&
39+ deh_objectid (deh) == le32_to_cpu (INODE_PKEY(inode->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid))
40+ continue;
41+
42 d_off = deh_offset (deh);
43 filp->f_pos = d_off ;
44 d_ino = deh_objectid (deh);
45diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/file.c linux-2.4.23.xattr/fs/reiserfs/file.c
46--- linux-2.4.23.datalogging+quota/fs/reiserfs/file.c 2003-12-11 12:54:29.707604736 -0500
47+++ linux-2.4.23.xattr/fs/reiserfs/file.c 2003-12-11 12:55:03.323494344 -0500
48@@ -5,6 +5,7 @@
49
50 #include <linux/sched.h>
51 #include <linux/reiserfs_fs.h>
52+#include <linux/reiserfs_xattr.h>
53 #include <linux/smp_lock.h>
54 #include <linux/quotaops.h>
55
56@@ -173,6 +174,10 @@ struct file_operations reiserfs_file_ope
57 struct inode_operations reiserfs_file_inode_operations = {
58 truncate: reiserfs_vfs_truncate_file,
59 setattr: reiserfs_setattr,
60+ setxattr: reiserfs_setxattr,
61+ getxattr: reiserfs_getxattr,
62+ listxattr: reiserfs_listxattr,
63+ removexattr: reiserfs_removexattr,
64 };
65
66
67diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/inode.c linux-2.4.23.xattr/fs/reiserfs/inode.c
68--- linux-2.4.23.datalogging+quota/fs/reiserfs/inode.c 2003-12-11 12:54:29.711604128 -0500
69+++ linux-2.4.23.xattr/fs/reiserfs/inode.c 2003-12-11 12:58:42.434184456 -0500
70@@ -6,6 +6,8 @@
71 #include <linux/sched.h>
72 #include <linux/fs.h>
73 #include <linux/reiserfs_fs.h>
74+#include <linux/reiserfs_xattr.h>
75+#include <linux/quotaops.h>
76 #include <linux/locks.h>
77 #include <linux/smp_lock.h>
78 #include <linux/quotaops.h>
79@@ -42,6 +44,8 @@ void reiserfs_delete_inode (struct inode
80 if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
81 down (&inode->i_sem);
82
83+ reiserfs_delete_xattrs (inode);
84+
85 journal_begin(&th, inode->i_sb, jbegin_count) ;
86 reiserfs_update_inode_transaction(inode) ;
87 windex = push_journal_writer("delete_inode") ;
88@@ -1169,7 +1173,7 @@ static void init_inode (struct inode * i
89 inode->i_op = &reiserfs_dir_inode_operations;
90 inode->i_fop = &reiserfs_dir_operations;
91 } else if (S_ISLNK (inode->i_mode)) {
92- inode->i_op = &page_symlink_inode_operations;
93+ inode->i_op = &reiserfs_symlink_inode_operations;
94 inode->i_mapping->a_ops = &reiserfs_address_space_operations;
95 } else {
96 inode->i_blocks = 0;
97@@ -2689,6 +2693,70 @@ static int reiserfs_direct_io(int rw, st
98 reiserfs_get_block_direct_io) ;
99 }
100
101+int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
102+{
103+ struct inode *inode = dentry->d_inode ;
104+ int error ;
105+ unsigned int ia_valid = attr->ia_valid ;
106+
107+ if (ia_valid & ATTR_SIZE) {
108+ /* version 2 items will be caught by the s_maxbytes check
109+ ** done for us in vmtruncate
110+ */
111+ if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
112+ attr->ia_size > MAX_NON_LFS)
113+ return -EFBIG ;
114+
115+ /* During a truncate, we have to make sure the new i_size is in
116+ ** the transaction before we start dropping updates to data logged
117+ ** or ordered write data pages.
118+ */
119+ if (attr->ia_size < inode->i_size && reiserfs_file_data_log(inode)) {
120+ struct reiserfs_transaction_handle th ;
121+ journal_begin(&th, inode->i_sb, 1) ;
122+ reiserfs_update_sd_size(&th, inode, attr->ia_size) ;
123+ journal_end(&th, inode->i_sb, 1) ;
124+ /* fill in hole pointers in the expanding truncate case. */
125+ } else if (attr->ia_size > inode->i_size) {
126+ error = generic_cont_expand(inode, attr->ia_size) ;
127+ if (inode->u.reiserfs_i.i_prealloc_count > 0) {
128+ struct reiserfs_transaction_handle th ;
129+ /* we're changing at most 2 bitmaps, inode + super */
130+ journal_begin(&th, inode->i_sb, 4) ;
131+ reiserfs_discard_prealloc (&th, inode);
132+ journal_end(&th, inode->i_sb, 4) ;
133+ }
134+ if (error)
135+ return error ;
136+ }
137+ }
138+
139+ if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
140+ ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
141+ (get_inode_sd_version (inode) == STAT_DATA_V1))
142+ /* stat data of format v3.5 has 16 bit uid and gid */
143+ return -EINVAL;
144+
145+ error = inode_change_ok(inode, attr) ;
146+ if (!error) {
147+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
148+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
149+ if (!(attr->ia_valid & ATTR_SIZE))
150+ down (&inode->i_sem);
151+ error = reiserfs_chown_xattrs (inode, attr);
152+ if (!(attr->ia_valid & ATTR_SIZE))
153+ up (&inode->i_sem);
154+
155+ if (!error)
156+ error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
157+ }
158+
159+ if (!error)
160+ error = inode_setattr(inode, attr) ;
161+ }
162+ return error ;
163+}
164+
165 struct address_space_operations reiserfs_address_space_operations = {
166 writepage: reiserfs_writepage,
167 readpage: reiserfs_readpage,
168diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/namei.c linux-2.4.23.xattr/fs/reiserfs/namei.c
169--- linux-2.4.23.datalogging+quota/fs/reiserfs/namei.c 2003-12-11 12:54:29.705605040 -0500
170+++ linux-2.4.23.xattr/fs/reiserfs/namei.c 2003-12-11 12:55:03.327493736 -0500
171@@ -6,6 +6,7 @@
172 #include <linux/sched.h>
173 #include <linux/bitops.h>
174 #include <linux/reiserfs_fs.h>
175+#include <linux/reiserfs_xattr.h>
176 #include <linux/smp_lock.h>
177 #include <linux/quotaops.h>
178
179@@ -324,10 +325,21 @@ static struct dentry * reiserfs_lookup (
180 retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
181 pathrelse (&path_to_entry);
182 if (retval == NAME_FOUND) {
183+ /* Hide the .reiserfs_priv dir */
184+ if (reiserfs_xattrs (dir->i_sb) &&
185+ !old_format_only(dir->i_sb) &&
186+ dir->i_sb->u.reiserfs_sb.priv_root &&
187+ dir->i_sb->u.reiserfs_sb.priv_root->d_inode &&
188+ de.de_objectid == le32_to_cpu (INODE_PKEY(dir->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid)) {
189+ return ERR_PTR (-EACCES);
190+ }
191 inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
192 if (!inode || IS_ERR(inode)) {
193 return ERR_PTR(-EACCES);
194 }
195+ /* Propogate the priv_object flag so we know we're in the priv tree */
196+ if (is_reiserfs_priv_object (dir))
197+ inode->u.reiserfs_i.i_flags |= i_priv_object;
198 }
199 if ( retval == IO_ERROR ) {
200 return ERR_PTR(-EIO);
201@@ -908,7 +920,7 @@ static int reiserfs_symlink (struct inod
202 reiserfs_update_inode_transaction(inode) ;
203 reiserfs_update_inode_transaction(parent_dir) ;
204
205- inode->i_op = &page_symlink_inode_operations;
206+ inode->i_op = &reiserfs_symlink_inode_operations;
207 inode->i_mapping->a_ops = &reiserfs_address_space_operations;
208
209 // must be sure this inode is written with this transaction
210@@ -1280,5 +1292,23 @@ struct inode_operations reiserfs_dir_ino
211 rmdir: reiserfs_rmdir,
212 mknod: reiserfs_mknod,
213 rename: reiserfs_rename,
214+ setattr: reiserfs_setattr,
215+ setxattr: reiserfs_setxattr,
216+ getxattr: reiserfs_getxattr,
217+ listxattr: reiserfs_listxattr,
218+ removexattr: reiserfs_removexattr,
219 };
220
221+/*
222+ * symlink operations.. same as page_symlink_inode_operations, with xattr
223+ * stuff added
224+ */
225+struct inode_operations reiserfs_symlink_inode_operations = {
226+ readlink: page_readlink,
227+ follow_link: page_follow_link,
228+ setattr: reiserfs_setattr,
229+ setxattr: reiserfs_setxattr,
230+ getxattr: reiserfs_getxattr,
231+ listxattr: reiserfs_listxattr,
232+ removexattr: reiserfs_removexattr,
233+};
234diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/super.c linux-2.4.23.xattr/fs/reiserfs/super.c
235--- linux-2.4.23.datalogging+quota/fs/reiserfs/super.c 2003-12-11 12:54:29.706604888 -0500
236+++ linux-2.4.23.xattr/fs/reiserfs/super.c 2003-12-11 12:59:19.183597696 -0500
237@@ -9,6 +9,7 @@
238 #include <linux/vmalloc.h>
239 #include <asm/uaccess.h>
240 #include <linux/reiserfs_fs.h>
241+#include <linux/reiserfs_xattr.h>
242 #include <linux/smp_lock.h>
243 #include <linux/locks.h>
244 #include <linux/init.h>
245@@ -354,7 +355,17 @@ static void reiserfs_put_super (struct s
246 {
247 int i;
248 struct reiserfs_transaction_handle th ;
249+
250+ if (s->u.reiserfs_sb.xattr_root) {
251+ d_invalidate (s->u.reiserfs_sb.xattr_root);
252+ dput (s->u.reiserfs_sb.xattr_root);
253+ }
254
255+ if (s->u.reiserfs_sb.priv_root) {
256+ d_invalidate (s->u.reiserfs_sb.priv_root);
257+ dput (s->u.reiserfs_sb.priv_root);
258+ }
259+
260 /* change file system state to current state if it was mounted with read-write permissions */
261 if (!(s->s_flags & MS_RDONLY)) {
262 journal_begin(&th, s, 10) ;
263@@ -639,7 +650,12 @@ static int reiserfs_parse_options (struc
264 {"noattrs", 0, 0, 0, 1<<REISERFS_ATTRS},
265 {"usrquota", 0, 0, 0, 0},
266 {"grpquota", 0, 0, 0, 0},
267-
268+#ifdef CONFIG_REISERFS_FS_XATTR
269+# ifdef CONFIG_REISERFS_FS_XATTR_USER
270+ {"user_xattr", 0, 0, 1<<REISERFS_XATTRS_USER, 0},
271+ {"nouser_xattr", 0, 0, 0, 1<<REISERFS_XATTRS_USER},
272+# endif
273+#endif
274 {NULL, 0, 0, 0, 0}
275 };
276
277@@ -757,6 +773,7 @@ static int reiserfs_remount (struct supe
278 safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
279 safe_mask |= 1 << REISERFS_TEST4;
280 safe_mask |= 1 << REISERFS_ATTRS;
281+ safe_mask |= 1 << REISERFS_XATTRS_USER;
282
283 /* Update the bitmask, taking care to keep
284 * the bits we're not allowed to change here */
285@@ -771,6 +788,7 @@ static int reiserfs_remount (struct supe
286 }
287
288 if (*mount_flags & MS_RDONLY) {
289+ reiserfs_xattr_init (s, *mount_flags);
290 /* remount read-only */
291 if (s->s_flags & MS_RDONLY)
292 /* it is read-only already */
293@@ -789,6 +807,7 @@ static int reiserfs_remount (struct supe
294 } else {
295 /* remount read-write */
296 if (!(s->s_flags & MS_RDONLY)) {
297+ reiserfs_xattr_init (s, *mount_flags);
298 handle_data_mode(s, mount_options);
299 return 0; /* We are read-write already */
300 }
301@@ -811,6 +830,7 @@ static int reiserfs_remount (struct supe
302
303 if (!( *mount_flags & MS_RDONLY ) ) {
304 finish_unfinished( s );
305+ reiserfs_xattr_init (s, *mount_flags);
306 handle_data_mode(s, mount_options);
307 }
308 return 0;
309@@ -1236,6 +1256,8 @@ static struct super_block * reiserfs_rea
310 s->u.reiserfs_sb.s_alloc_options.preallocmin = 4;
311 /* Preallocate by 8 blocks (9-1) at once */
312 s->u.reiserfs_sb.s_alloc_options.preallocsize = 9;
313+ /* Initialize the rwsem for xattr dir */
314+ init_rwsem(&s->u.reiserfs_sb.xattr_dir_sem);
315
316 if (reiserfs_parse_options (s, (char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
317 return NULL;
318@@ -1378,11 +1400,23 @@ static struct super_block * reiserfs_rea
319
320 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
321 journal_end(&th, s, 1) ;
322-
323+
324+ if (reiserfs_xattr_init (s, s->s_flags)) {
325+ dput (s->s_root);
326+ s->s_root = NULL;
327+ goto error;
328+ }
329+
330 /* look for files which were to be removed in previous session */
331 finish_unfinished (s);
332
333 s->s_dirt = 0;
334+ } else {
335+ if (reiserfs_xattr_init (s, s->s_flags)) {
336+ dput (s->s_root);
337+ s->s_root = NULL;
338+ goto error;
339+ }
340 }
341
342 // mark hash in super block: it could be unset. overwrite should be ok
343@@ -1447,8 +1481,20 @@ static int __init init_reiserfs_fs (void
344 reiserfs_global_version_in_proc );
345 ret = reiserfs_journal_cache_init();
346 if (ret)
347- return ret;
348+ goto failed_journal_cache_init;
349+
350+ ret = reiserfs_xattr_user_init ();
351+ if (ret)
352+ goto failed_xattr_user_init;
353+
354 return register_filesystem(&reiserfs_fs_type);
355+
356+failed_xattr_user_init:
357+failed_journal_cache_init:
358+ reiserfs_proc_unregister_global( "version" );
359+ reiserfs_proc_info_global_done();
360+ return ret;
361+
362 }
363
364 MODULE_DESCRIPTION("ReiserFS journaled filesystem");
365@@ -1457,6 +1503,7 @@ MODULE_LICENSE("GPL");
366
367 static void __exit exit_reiserfs_fs(void)
368 {
369+ reiserfs_xattr_user_exit ();
370 reiserfs_proc_unregister_global( "version" );
371 reiserfs_proc_info_global_done();
372 unregister_filesystem(&reiserfs_fs_type);
373diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/xattr.c linux-2.4.23.xattr/fs/reiserfs/xattr.c
374--- linux-2.4.23.datalogging+quota/fs/reiserfs/xattr.c 1969-12-31 19:00:00.000000000 -0500
375+++ linux-2.4.23.xattr/fs/reiserfs/xattr.c 2003-12-11 12:55:03.332492976 -0500
376@@ -0,0 +1,1246 @@
377+/*
378+ * linux/fs/reiserfs/xattr.c
379+ *
380+ * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com>
381+ *
382+ */
383+
384+/*
385+ * In order to implement EAs in a clean, backwards compatible manner,
386+ * they are implemented as files in a "private" directory.
387+ * Each EA is in it's own file, with the directory layout like so (/ is assumed
388+ * to be relative to fs root). Inside the /.reiserfs_priv/xattrs directory,
389+ * directories named using the capital-hex form of the objectid and
390+ * generation number are used. Inside each directory are individual files
391+ * named with the name of the extended attribute.
392+ *
393+ * So, for objectid 12648430, we could have:
394+ * /.reiserfs_priv/xattrs/C0FFEE.0/user.Content-Type
395+ * .. or similar.
396+ *
397+ * The file contents are the text of the EA. The size is known based on the
398+ * stat data describing the file.
399+ *
400+ */
401+
402+#include <linux/reiserfs_fs.h>
403+#include <linux/dcache.h>
404+#include <linux/errno.h>
405+#include <linux/fs.h>
406+#include <linux/file.h>
407+#include <linux/pagemap.h>
408+#include <linux/xattr.h>
409+#include <linux/reiserfs_xattr.h>
410+#include <linux/mbcache.h>
411+#include <asm/uaccess.h>
412+#include <asm/checksum.h>
413+#include <linux/smp_lock.h>
414+#include <linux/stat.h>
415+#include <asm/semaphore.h>
416+
417+#define FL_READONLY 128
418+#define FL_DIR_SEM_HELD 256
419+#define PRIVROOT_NAME ".reiserfs_priv"
420+#define XAROOT_NAME "xattrs"
421+
422+static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix);
423+
424+static struct dentry *
425+create_xa_root (struct super_block *sb)
426+{
427+ struct dentry *privroot = dget (sb->u.reiserfs_sb.priv_root);
428+ struct dentry *xaroot;
429+
430+ /* This needs to be created at mount-time */
431+ if (!privroot)
432+ return ERR_PTR(-EOPNOTSUPP);
433+
434+ xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
435+ if (IS_ERR (xaroot)) {
436+ goto out;
437+ } else if (!xaroot->d_inode) {
438+ int err;
439+ down (&privroot->d_inode->i_sem);
440+ err = privroot->d_inode->i_op->mkdir (privroot->d_inode, xaroot, 0700);
441+ up (&privroot->d_inode->i_sem);
442+
443+ if (err) {
444+ dput (xaroot);
445+ dput (privroot);
446+ return ERR_PTR (err);
447+ }
448+ sb->u.reiserfs_sb.xattr_root = dget (xaroot);
449+ }
450+
451+out:
452+ dput (privroot);
453+ return xaroot;
454+}
455+
456+/* This will return a dentry, or error, refering to the xa root directory.
457+ * If the xa root doesn't exist yet, the dentry will be returned without
458+ * an associated inode. This dentry can be used with ->mkdir to create
459+ * the xa directory. */
460+static struct dentry *
461+__get_xa_root (struct super_block *s)
462+{
463+ struct dentry *privroot = dget (s->u.reiserfs_sb.priv_root);
464+ struct dentry *xaroot = NULL;
465+
466+ if (IS_ERR (privroot) || !privroot)
467+ return privroot;
468+
469+ xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
470+ if (IS_ERR (xaroot)) {
471+ goto out;
472+ } else if (!xaroot->d_inode) {
473+ dput (xaroot);
474+ xaroot = NULL;
475+ goto out;
476+ }
477+
478+ s->u.reiserfs_sb.xattr_root = dget (xaroot);
479+
480+out:
481+ dput (privroot);
482+ return xaroot;
483+}
484+
485+/* Returns the dentry (or NULL) referring to the root of the extended
486+ * attribute directory tree. If it has already been retreived, it is used.
487+ * Otherwise, we attempt to retreive it from disk. It may also return
488+ * a pointer-encoded error.
489+ */
490+static inline struct dentry *
491+get_xa_root (struct super_block *s)
492+{
493+ struct dentry *dentry = s->u.reiserfs_sb.xattr_root;
494+
495+ if (!dentry)
496+ dentry = __get_xa_root (s);
497+ else
498+ dget (dentry);
499+ return dentry;
500+}
501+
502+/* Same as above, but only returns a valid dentry or NULL */
503+struct dentry *
504+reiserfs_get_xa_root (struct super_block *sb)
505+{
506+ struct dentry *dentry;
507+
508+ dentry = get_xa_root (sb);
509+ if (IS_ERR (dentry)) {
510+ dentry = NULL;
511+ } else if (dentry && !dentry->d_inode) {
512+ dput (dentry);
513+ dentry = NULL;
514+ }
515+
516+ return dentry;
517+}
518+
519+/* Opens the directory corresponding to the inode's extended attribute store.
520+ * If flags allow, the tree to the directory may be created. If creation is
521+ * prohibited, -ENODATA is returned. */
522+static struct dentry *
523+open_xa_dir (const struct inode *inode, int flags)
524+{
525+ struct dentry *xaroot, *xadir;
526+ char namebuf[17];
527+
528+ xaroot = get_xa_root (inode->i_sb);
529+ if (IS_ERR (xaroot)) {
530+ return xaroot;
531+ } else if (!xaroot) {
532+ if (flags == 0 || flags & XATTR_CREATE) {
533+ xaroot = create_xa_root (inode->i_sb);
534+ if (IS_ERR (xaroot))
535+ return xaroot;
536+ }
537+ if (!xaroot)
538+ return ERR_PTR (-ENODATA);
539+ }
540+
541+ /* ok, we have xaroot open */
542+
543+ snprintf (namebuf, sizeof (namebuf), "%X.%X",
544+ le32_to_cpu (INODE_PKEY (inode)->k_objectid),
545+ inode->i_generation);
546+ xadir = lookup_one_len (namebuf, xaroot, strlen (namebuf));
547+ if (IS_ERR (xadir)) {
548+ dput (xaroot);
549+ return xadir;
550+ }
551+
552+ if (!xadir->d_inode) {
553+ int err;
554+ if (flags == 0 || flags & XATTR_CREATE) {
555+ /* Although there is nothing else trying to create this directory,
556+ * another directory with the same hash may be created, so we need
557+ * to protect against that */
558+ err = xaroot->d_inode->i_op->mkdir (xaroot->d_inode, xadir, 0700);
559+ if (err) {
560+ dput (xaroot);
561+ dput (xadir);
562+ return ERR_PTR (err);
563+ }
564+ }
565+ if (!xadir->d_inode) {
566+ dput (xaroot);
567+ dput (xadir);
568+ return ERR_PTR (-ENODATA);
569+ }
570+ }
571+
572+ dput (xaroot);
573+ return xadir;
574+}
575+
576+/* Returns a dentry corresponding to a specific extended attribute file
577+ * for the inode. If flags allow, the file is created. Otherwise, a
578+ * valid or negative dentry, or an error is returned. */
579+static struct dentry *
580+get_xa_file_dentry (const struct inode *inode, const char *name, int flags)
581+{
582+ struct dentry *xadir, *xafile;
583+ int err = 0;
584+
585+ xadir = open_xa_dir (inode, flags);
586+ if (IS_ERR (xadir)) {
587+ return ERR_PTR (PTR_ERR (xadir));
588+ } else if (xadir && !xadir->d_inode) {
589+ dput (xadir);
590+ return ERR_PTR (-ENODATA);
591+ }
592+
593+ xafile = lookup_one_len (name, xadir, strlen (name));
594+ if (IS_ERR (xafile)) {
595+ dput (xadir);
596+ return ERR_PTR (PTR_ERR (xafile));
597+ }
598+
599+ if (xafile->d_inode) { /* file exists */
600+ if (flags & XATTR_CREATE) {
601+ err = -EEXIST;
602+ dput (xafile);
603+ goto out;
604+ }
605+ } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
606+ goto out;
607+ } else {
608+ /* inode->i_sem is down, so nothing else can try to create
609+ * the same xattr */
610+ err = xadir->d_inode->i_op->create (xadir->d_inode, xafile,
611+ 0700|S_IFREG);
612+
613+ if (err) {
614+ dput (xafile);
615+ goto out;
616+ }
617+ }
618+
619+out:
620+ dput (xadir);
621+ if (err)
622+ xafile = ERR_PTR (err);
623+ return xafile;
624+}
625+
626+
627+/* Opens a file pointer to the attribute associated with inode */
628+static struct file *
629+open_xa_file (const struct inode *inode, const char *name, int flags)
630+{
631+ struct dentry *xafile;
632+ struct file *fp;
633+
634+ xafile = get_xa_file_dentry (inode, name, flags);
635+ if (IS_ERR (xafile))
636+ return ERR_PTR (PTR_ERR (xafile));
637+ else if (!xafile->d_inode) {
638+ dput (xafile);
639+ return ERR_PTR (-ENODATA);
640+ }
641+
642+ fp = dentry_open (xafile, NULL, O_RDWR);
643+ /* dentry_open dputs the dentry if it fails */
644+
645+ return fp;
646+}
647+
648+
649+/*
650+ * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but
651+ * we need to drop the path before calling the filldir struct. That
652+ * would be a big performance hit to the non-xattr case, so I've copied
653+ * the whole thing for now. --clm
654+ *
655+ * the big difference is that I go backwards through the directory,
656+ * and don't mess with f->f_pos, but the idea is the same. Do some
657+ * action on each and every entry in the directory.
658+ *
659+ * we're called with i_sem held, so there are no worries about the directory
660+ * changing underneath us.
661+ */
662+static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir)
663+{
664+ struct inode *inode = filp->f_dentry->d_inode;
665+ struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */
666+ INITIALIZE_PATH (path_to_entry);
667+ struct buffer_head * bh;
668+ int entry_num;
669+ struct item_head * ih, tmp_ih;
670+ int search_res;
671+ char * local_buf;
672+ loff_t next_pos;
673+ char small_buf[32] ; /* avoid kmalloc if we can */
674+ struct reiserfs_de_head *deh;
675+ int d_reclen;
676+ char * d_name;
677+ off_t d_off;
678+ ino_t d_ino;
679+ struct reiserfs_dir_entry de;
680+
681+
682+ /* form key for search the next directory entry using f_pos field of
683+ file structure */
684+ next_pos = max_reiserfs_offset(inode);
685+
686+ while (1) {
687+research:
688+ if (next_pos <= DOT_DOT_OFFSET)
689+ break;
690+ make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
691+
692+ search_res = search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, &de);
693+ if (search_res == IO_ERROR) {
694+ // FIXME: we could just skip part of directory which could
695+ // not be read
696+ pathrelse(&path_to_entry);
697+ return -EIO;
698+ }
699+
700+ if (search_res == NAME_NOT_FOUND)
701+ de.de_entry_num--;
702+
703+ set_de_name_and_namelen(&de);
704+ entry_num = de.de_entry_num;
705+ deh = &(de.de_deh[entry_num]);
706+
707+ bh = de.de_bh;
708+ ih = de.de_ih;
709+
710+ if (!is_direntry_le_ih(ih)) {
711+ reiserfs_warning(inode->i_sb, "not direntry %h\n", ih);
712+ break;
713+ }
714+ copy_item_head(&tmp_ih, ih);
715+
716+ /* we must have found item, that is item of this directory, */
717+ RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key),
718+ "vs-9000: found item %h does not match to dir we readdir %K",
719+ ih, &pos_key);
720+
721+ if (deh_offset(deh) <= DOT_DOT_OFFSET) {
722+ break;
723+ }
724+
725+ /* look for the previous entry in the directory */
726+ next_pos = deh_offset (deh) - 1;
727+
728+ if (!de_visible (deh))
729+ /* it is hidden entry */
730+ continue;
731+
732+ d_reclen = entry_length(bh, ih, entry_num);
733+ d_name = B_I_DEH_ENTRY_FILE_NAME (bh, ih, deh);
734+ d_off = deh_offset (deh);
735+ d_ino = deh_objectid (deh);
736+
737+ if (!d_name[d_reclen - 1])
738+ d_reclen = strlen (d_name);
739+
740+ if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
741+ /* too big to send back to VFS */
742+ continue ;
743+ }
744+
745+ /* Ignore the .reiserfs_priv entry */
746+ if (reiserfs_xattrs (inode->i_sb) &&
747+ !old_format_only(inode->i_sb) &&
748+ deh_objectid (deh) == le32_to_cpu (INODE_PKEY(inode->i_sb->u.reiserfs_sb.priv_root->d_inode)->k_objectid))
749+ continue;
750+
751+ if (d_reclen <= 32) {
752+ local_buf = small_buf ;
753+ } else {
754+ local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
755+ if (!local_buf) {
756+ pathrelse (&path_to_entry);
757+ return -ENOMEM ;
758+ }
759+ if (item_moved (&tmp_ih, &path_to_entry)) {
760+ reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
761+
762+ /* sigh, must retry. Do this same offset again */
763+ next_pos = d_off;
764+ goto research;
765+ }
766+ }
767+
768+ // Note, that we copy name to user space via temporary
769+ // buffer (local_buf) because filldir will block if
770+ // user space buffer is swapped out. At that time
771+ // entry can move to somewhere else
772+ memcpy (local_buf, d_name, d_reclen);
773+
774+ /* the filldir function might need to start transactions,
775+ * or do who knows what. Release the path now that we've
776+ * copied all the important stuff out of the deh
777+ */
778+ pathrelse (&path_to_entry);
779+
780+ if (filldir (dirent, local_buf, d_reclen, d_off, d_ino,
781+ DT_UNKNOWN) < 0) {
782+ if (local_buf != small_buf) {
783+ reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
784+ }
785+ goto end;
786+ }
787+ if (local_buf != small_buf) {
788+ reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
789+ }
790+ } /* while */
791+
792+end:
793+ pathrelse (&path_to_entry);
794+ return 0;
795+}
796+
797+/*
798+ * this could be done with dedicated readdir ops for the xattr files,
799+ * but I want to get something working asap
800+ * this is stolen from vfs_readdir
801+ *
802+ */
803+static
804+int xattr_readdir(struct file *file, filldir_t filler, void *buf)
805+{
806+ struct inode *inode = file->f_dentry->d_inode;
807+ int res = -ENOTDIR;
808+ if (!file->f_op || !file->f_op->readdir)
809+ goto out;
810+ down(&inode->i_sem);
811+ down(&inode->i_zombie);
812+ res = -ENOENT;
813+ if (!IS_DEADDIR(inode)) {
814+ lock_kernel();
815+ res = __xattr_readdir(file, buf, filler);
816+ unlock_kernel();
817+ }
818+ up(&inode->i_zombie);
819+ up(&inode->i_sem);
820+out:
821+ return res;
822+}
823+
824+
825+/* Internal operations on file data */
826+static inline void
827+reiserfs_put_page(struct page *page)
828+{
829+ kunmap(page);
830+ page_cache_release(page);
831+}
832+
833+static struct page *
834+reiserfs_get_page(struct inode *dir, unsigned long n)
835+{
836+ struct address_space *mapping = dir->i_mapping;
837+ struct page *page;
838+ /* We can deadlock if we try to free dentries,
839+ and an unlink/rmdir has just occured - GFP_NOFS avoids this */
840+ mapping->gfp_mask = GFP_NOFS;
841+ page = read_cache_page (mapping, n,
842+ (filler_t*)mapping->a_ops->readpage, NULL);
843+ if (!IS_ERR(page)) {
844+ wait_on_page(page);
845+ kmap(page);
846+ if (!Page_Uptodate(page))
847+ goto fail;
848+
849+ if (PageError(page))
850+ goto fail;
851+ }
852+ return page;
853+
854+fail:
855+ reiserfs_put_page(page);
856+ return ERR_PTR(-EIO);
857+}
858+
859+static inline __u32
860+xattr_hash (const char *msg, int len)
861+{
862+ return csum_partial (msg, len, 0);
863+}
864+
865+/* Generic extended attribute operations that can be used by xa plugins */
866+
867+/*
868+ * inode->i_sem: down
869+ */
870+int
871+reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer,
872+ size_t buffer_size, int flags)
873+{
874+ int err = 0;
875+ struct file *fp;
876+ struct page *page;
877+ char *data;
878+ struct address_space *mapping;
879+ size_t file_pos = 0;
880+ size_t buffer_pos = 0;
881+ struct inode *xinode;
882+ struct iattr newattrs;
883+ __u32 xahash = 0;
884+
885+ if (get_inode_sd_version (inode) == STAT_DATA_V1)
886+ return -EOPNOTSUPP;
887+
888+ /* Empty xattrs are ok, they're just empty files, no hash */
889+ if (buffer && buffer_size)
890+ xahash = xattr_hash (buffer, buffer_size);
891+
892+open_file:
893+ fp = open_xa_file (inode, name, flags);
894+ if (IS_ERR (fp)) {
895+ err = PTR_ERR (fp);
896+ goto out;
897+ }
898+
899+ xinode = fp->f_dentry->d_inode;
900+
901+ /* we need to copy it off.. */
902+ if (xinode->i_nlink > 1) {
903+ fput(fp);
904+ err = reiserfs_xattr_del (inode, name);
905+ if (err < 0)
906+ goto out;
907+ /* We just killed the old one, we're not replacing anymore */
908+ if (flags & XATTR_REPLACE)
909+ flags &= ~XATTR_REPLACE;
910+ goto open_file;
911+ }
912+
913+ /* Resize it so we're ok to write there */
914+ newattrs.ia_size = buffer_size;
915+ newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
916+ down (&xinode->i_sem);
917+ err = notify_change(fp->f_dentry, &newattrs);
918+ if (err)
919+ goto out_filp;
920+
921+ mapping = xinode->i_mapping;
922+ while (buffer_pos < buffer_size || buffer_pos == 0) {
923+ size_t chunk;
924+ size_t skip = 0;
925+ size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1));
926+ if (buffer_size - buffer_pos > PAGE_CACHE_SIZE)
927+ chunk = PAGE_CACHE_SIZE;
928+ else
929+ chunk = buffer_size - buffer_pos;
930+
931+ page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
932+ if (IS_ERR (page)) {
933+ err = PTR_ERR (page);
934+ goto out_filp;
935+ }
936+
937+ lock_page (page);
938+ data = page_address (page);
939+
940+ if (file_pos == 0) {
941+ struct reiserfs_xattr_header *rxh;
942+ skip = file_pos = sizeof (struct reiserfs_xattr_header);
943+ if (chunk + skip > PAGE_CACHE_SIZE)
944+ chunk = PAGE_CACHE_SIZE - skip;
945+ rxh = (struct reiserfs_xattr_header *)data;
946+ rxh->h_magic = cpu_to_le32 (REISERFS_XATTR_MAGIC);
947+ rxh->h_hash = cpu_to_le32 (xahash);
948+ }
949+
950+ err = mapping->a_ops->prepare_write (fp, page, page_offset,
951+ page_offset + chunk + skip);
952+ if (!err) {
953+ if (buffer)
954+ memcpy (data + skip, buffer + buffer_pos, chunk);
955+ err = mapping->a_ops->commit_write (fp, page, page_offset,
956+ page_offset + chunk + skip);
957+ }
958+ UnlockPage (page);
959+ reiserfs_put_page (page);
960+ buffer_pos += chunk;
961+ file_pos += chunk;
962+ skip = 0;
963+ if (err || buffer_size == 0 || !buffer)
964+ break;
965+ }
966+
967+out_filp:
968+ up (&xinode->i_sem);
969+ fput(fp);
970+
971+out:
972+ return err;
973+}
974+
975+/*
976+ * inode->i_sem: down
977+ */
978+int
979+reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer,
980+ size_t buffer_size)
981+{
982+ ssize_t err = 0;
983+ struct file *fp;
984+ size_t isize;
985+ size_t file_pos = 0;
986+ size_t buffer_pos = 0;
987+ struct page *page;
988+ struct inode *xinode;
989+ __u32 hash = 0;
990+
991+ /* We can't have xattrs attached to v1 items since they don't have
992+ * generation numbers */
993+ if (get_inode_sd_version (inode) == STAT_DATA_V1)
994+ return -EOPNOTSUPP;
995+
996+ fp = open_xa_file (inode, name, FL_READONLY);
997+ if (IS_ERR (fp)) {
998+ err = PTR_ERR (fp);
999+ goto out;
1000+ }
1001+
1002+ xinode = fp->f_dentry->d_inode;
1003+ isize = xinode->i_size;
1004+
1005+ /* Just return the size needed */
1006+ if (buffer == NULL) {
1007+ err = isize - sizeof (struct reiserfs_xattr_header);
1008+ goto out_dput;
1009+ }
1010+
1011+ if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) {
1012+ err = -ERANGE;
1013+ goto out_dput;
1014+ }
1015+
1016+ while (file_pos < isize) {
1017+ size_t chunk;
1018+ char *data;
1019+ size_t skip = 0;
1020+ if (isize - file_pos > PAGE_CACHE_SIZE)
1021+ chunk = PAGE_CACHE_SIZE;
1022+ else
1023+ chunk = isize - file_pos;
1024+
1025+ page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
1026+ if (IS_ERR (page)) {
1027+ err = PTR_ERR (page);
1028+ goto out_dput;
1029+ }
1030+
1031+ lock_page (page);
1032+ data = page_address (page);
1033+ if (file_pos == 0) {
1034+ struct reiserfs_xattr_header *rxh =
1035+ (struct reiserfs_xattr_header *)data;
1036+ skip = file_pos = sizeof (struct reiserfs_xattr_header);
1037+ chunk -= skip;
1038+ /* Magic doesn't match up.. */
1039+ if (rxh->h_magic != cpu_to_le32 (REISERFS_XATTR_MAGIC)) {
1040+ UnlockPage (page);
1041+ reiserfs_put_page (page);
1042+ err = -EIO;
1043+ goto out_dput;
1044+ }
1045+ hash = le32_to_cpu (rxh->h_hash);
1046+ }
1047+ memcpy (buffer + buffer_pos, data + skip, chunk);
1048+ UnlockPage (page);
1049+ reiserfs_put_page (page);
1050+ file_pos += chunk;
1051+ buffer_pos += chunk;
1052+ skip = 0;
1053+ }
1054+ err = isize - sizeof (struct reiserfs_xattr_header);
1055+
1056+ if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash)
1057+ err = -EIO;
1058+
1059+out_dput:
1060+ fput(fp);
1061+
1062+out:
1063+ return err;
1064+}
1065+
1066+static int
1067+__reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen)
1068+{
1069+ struct dentry *file;
1070+ struct inode *dir = xadir->d_inode;
1071+ int err = 0;
1072+
1073+ file = lookup_one_len (name, xadir, namelen);
1074+ if (IS_ERR (file)) {
1075+ err = PTR_ERR (file);
1076+ goto out;
1077+ } else if (!file->d_inode) {
1078+ err = -ENODATA;
1079+ goto out_file;
1080+ }
1081+
1082+ /* Skip directories.. */
1083+ if (S_ISDIR (file->d_inode->i_mode))
1084+ goto out_file;
1085+
1086+ if (!is_reiserfs_priv_object (file->d_inode)) {
1087+ reiserfs_warning (dir->i_sb, "trying to delete objectid %08x, which isn't an xattr!\n", le32_to_cpu (INODE_PKEY (file->d_inode)->k_objectid));
1088+ dput (file);
1089+ return -EIO;
1090+ }
1091+
1092+ err = dir->i_op->unlink (dir, file);
1093+ if (!err)
1094+ d_delete (file);
1095+
1096+out_file:
1097+ dput (file);
1098+
1099+out:
1100+ return err;
1101+}
1102+
1103+
1104+int
1105+reiserfs_xattr_del (struct inode *inode, const char *name)
1106+{
1107+ struct dentry *dir;
1108+ int err;
1109+
1110+ dir = open_xa_dir (inode, FL_READONLY);
1111+ if (IS_ERR (dir)) {
1112+ err = PTR_ERR (dir);
1113+ goto out;
1114+ }
1115+
1116+ err = __reiserfs_xattr_del (dir, name, strlen (name));
1117+ dput (dir);
1118+
1119+out:
1120+ return err;
1121+}
1122+
1123+/* The following are side effects of other operations that aren't explicitly
1124+ * modifying extended attributes. This includes operations such as permissions
1125+ * or ownership changes, object deletions, etc. */
1126+
1127+static int
1128+reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen,
1129+ loff_t offset, ino_t ino, unsigned int d_type)
1130+{
1131+ struct dentry *xadir = (struct dentry *)buf;
1132+
1133+ return __reiserfs_xattr_del (xadir, name, namelen);
1134+
1135+}
1136+
1137+int
1138+reiserfs_delete_xattrs (struct inode *inode)
1139+{
1140+ struct file *fp;
1141+ struct dentry *dir, *root;
1142+ int err = 0;
1143+
1144+ /* Skip out, an xattr has no xattrs associated with it */
1145+ if (is_reiserfs_priv_object (inode) ||
1146+ get_inode_sd_version (inode) == STAT_DATA_V1 ||
1147+ !reiserfs_xattrs(inode->i_sb))
1148+ {
1149+ return 0;
1150+ }
1151+ reiserfs_read_lock_xattrs (inode->i_sb);
1152+ dir = open_xa_dir (inode, FL_READONLY);
1153+ reiserfs_read_unlock_xattrs (inode->i_sb);
1154+ if (IS_ERR (dir)) {
1155+ err = PTR_ERR (dir);
1156+ goto out;
1157+ } else if (!dir->d_inode) {
1158+ dput (dir);
1159+ return 0;
1160+ }
1161+
1162+ fp = dentry_open (dir, NULL, O_RDWR);
1163+ if (IS_ERR (fp)) {
1164+ err = PTR_ERR (fp);
1165+ /* dentry_open dputs the dentry if it fails */
1166+ goto out;
1167+ }
1168+
1169+ lock_kernel ();
1170+ err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir);
1171+ if (err) {
1172+ unlock_kernel ();
1173+ goto out_dir;
1174+ }
1175+
1176+ /* Leftovers besides . and .. -- that's not good. */
1177+ if (dir->d_inode->i_nlink <= 2) {
1178+ root = get_xa_root (inode->i_sb);
1179+ reiserfs_write_lock_xattrs (inode->i_sb);
1180+ err = vfs_rmdir (root->d_inode, dir);
1181+ reiserfs_write_unlock_xattrs (inode->i_sb);
1182+ dput (root);
1183+ } else {
1184+ reiserfs_warning (inode->i_sb, "Couldn't remove all entries in directory\n");
1185+ }
1186+ unlock_kernel ();
1187+
1188+out_dir:
1189+ fput(fp);
1190+
1191+out:
1192+ return err;
1193+}
1194+
1195+struct reiserfs_chown_buf {
1196+ struct inode *inode;
1197+ struct dentry *xadir;
1198+ struct iattr *attrs;
1199+};
1200+
1201+/* XXX: If there is a better way to do this, I'd love to hear about it */
1202+static int
1203+reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen,
1204+ loff_t offset, ino_t ino, unsigned int d_type)
1205+{
1206+ struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
1207+ struct dentry *xafile, *xadir = chown_buf->xadir;
1208+ struct iattr *attrs = chown_buf->attrs;
1209+ int err = 0;
1210+
1211+ xafile = lookup_one_len (name, xadir, namelen);
1212+ if (IS_ERR (xafile))
1213+ return PTR_ERR (xafile);
1214+ else if (!xafile->d_inode) {
1215+ dput (xafile);
1216+ return -ENODATA;
1217+ }
1218+
1219+ if (!S_ISDIR (xafile->d_inode->i_mode))
1220+ err = notify_change (xafile, attrs);
1221+ dput (xafile);
1222+
1223+ return err;
1224+}
1225+
1226+int
1227+reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
1228+{
1229+ struct file *fp;
1230+ struct dentry *dir;
1231+ int err = 0;
1232+ struct reiserfs_chown_buf buf;
1233+ unsigned int ia_valid = attrs->ia_valid;
1234+
1235+ /* Skip out, an xattr has no xattrs associated with it */
1236+ if (is_reiserfs_priv_object (inode) ||
1237+ get_inode_sd_version (inode) == STAT_DATA_V1 ||
1238+ !reiserfs_xattrs(inode->i_sb))
1239+ {
1240+ return 0;
1241+ }
1242+ reiserfs_read_lock_xattrs (inode->i_sb);
1243+ dir = open_xa_dir (inode, FL_READONLY);
1244+ reiserfs_read_unlock_xattrs (inode->i_sb);
1245+ if (IS_ERR (dir)) {
1246+ if (PTR_ERR (dir) != -ENODATA)
1247+ err = PTR_ERR (dir);
1248+ goto out;
1249+ } else if (!dir->d_inode) {
1250+ dput (dir);
1251+ goto out;
1252+ }
1253+
1254+ fp = dentry_open (dir, NULL, O_RDWR);
1255+ if (IS_ERR (fp)) {
1256+ err = PTR_ERR (fp);
1257+ /* dentry_open dputs the dentry if it fails */
1258+ goto out;
1259+ }
1260+
1261+ lock_kernel ();
1262+
1263+ attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
1264+ buf.xadir = dir;
1265+ buf.attrs = attrs;
1266+ buf.inode = inode;
1267+
1268+ err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf);
1269+ if (err) {
1270+ unlock_kernel ();
1271+ goto out_dir;
1272+ }
1273+
1274+ err = notify_change (dir, attrs);
1275+ unlock_kernel ();
1276+
1277+out_dir:
1278+ fput(fp);
1279+
1280+out:
1281+ attrs->ia_valid = ia_valid;
1282+ return err;
1283+}
1284+
1285+
1286+/* Actual operations that are exported to VFS-land */
1287+
1288+/*
1289+ * Inode operation getxattr()
1290+ * dentry->d_inode->i_sem down
1291+ * BKL held [before 2.5.x]
1292+ */
1293+ssize_t
1294+reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer,
1295+ size_t size)
1296+{
1297+ struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1298+ int err;
1299+
1300+ if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1301+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1302+ return -EOPNOTSUPP;
1303+
1304+ reiserfs_read_lock_xattrs (dentry->d_sb);
1305+ err = xah->get (dentry->d_inode, name, buffer, size);
1306+ reiserfs_read_unlock_xattrs (dentry->d_sb);
1307+ return err;
1308+}
1309+
1310+
1311+/*
1312+ * Inode operation setxattr()
1313+ *
1314+ * dentry->d_inode->i_sem down
1315+ * BKL held [before 2.5.x]
1316+ */
1317+int
1318+reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value,
1319+ size_t size, int flags)
1320+{
1321+ struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1322+ int err;
1323+
1324+ if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1325+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1326+ return -EOPNOTSUPP;
1327+
1328+
1329+ reiserfs_write_lock_xattrs (dentry->d_sb);
1330+ err = xah->set (dentry->d_inode, name, value, size, flags);
1331+ reiserfs_write_unlock_xattrs (dentry->d_sb);
1332+ return err;
1333+}
1334+
1335+/*
1336+ * Inode operation removexattr()
1337+ *
1338+ * dentry->d_inode->i_sem down
1339+ * BKL held [before 2.5.x]
1340+ */
1341+int
1342+reiserfs_removexattr (struct dentry *dentry, const char *name)
1343+{
1344+ int err;
1345+ struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1346+
1347+ if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1348+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1349+ return -EOPNOTSUPP;
1350+
1351+ down (&dentry->d_inode->i_zombie);
1352+ reiserfs_read_lock_xattrs (dentry->d_sb);
1353+
1354+ /* Deletion pre-operation */
1355+ if (xah->del) {
1356+ err = xah->del (dentry->d_inode, name);
1357+ if (err) {
1358+ reiserfs_read_unlock_xattrs (dentry->d_sb);
1359+ up (&dentry->d_inode->i_zombie);
1360+ return err;
1361+ }
1362+ }
1363+
1364+ err = reiserfs_xattr_del (dentry->d_inode, name);
1365+ reiserfs_read_unlock_xattrs (dentry->d_sb);
1366+ up (&dentry->d_inode->i_zombie);
1367+ return err;
1368+}
1369+
1370+
1371+/* This is what filldir will use:
1372+ * r_pos will always contain the amount of space required for the entire
1373+ * list. If r_pos becomes larger than r_size, we need more space and we
1374+ * return an error indicating this. If r_pos is less than r_size, then we've
1375+ * filled the buffer successfully and we return success */
1376+struct reiserfs_listxattr_buf {
1377+ int r_pos;
1378+ int r_size;
1379+ char *r_buf;
1380+ struct inode *r_inode;
1381+};
1382+
1383+static int
1384+reiserfs_listxattr_filler (void *buf, const char *name, int namelen,
1385+ loff_t offset, ino_t ino, unsigned int d_type)
1386+{
1387+ struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
1388+ int len = 0;
1389+ if (name[0] != '.' || (namelen != 1 && (name[1] != '.' || namelen != 2))) {
1390+ struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1391+ if (!xah) return 0; /* Unsupported xattr name, skip it */
1392+
1393+ /* We call ->list() twice because the operation isn't required to just
1394+ * return the name back - we want to make sure we have enough space */
1395+ len += xah->list (b->r_inode, name, namelen, NULL);
1396+
1397+ if (len) {
1398+ if (b->r_pos + len + 1 <= b->r_size) {
1399+ char *p = b->r_buf + b->r_pos;
1400+ p += xah->list (b->r_inode, name, namelen, p);
1401+ *p++ = '\0';
1402+ }
1403+ b->r_pos += len + 1;
1404+ }
1405+ }
1406+
1407+ return 0;
1408+}
1409+/*
1410+ * Inode operation listxattr()
1411+ *
1412+ * dentry->d_inode->i_sem down
1413+ * BKL held [before 2.5.x]
1414+ */
1415+ssize_t
1416+reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
1417+{
1418+ struct file *fp;
1419+ struct dentry *dir;
1420+ int err = 0;
1421+ struct reiserfs_listxattr_buf buf;
1422+
1423+ if (!dentry->d_inode)
1424+ return -EINVAL;
1425+
1426+ if (!reiserfs_xattrs(dentry->d_sb) ||
1427+ get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1428+ return -EOPNOTSUPP;
1429+
1430+ reiserfs_read_lock_xattrs (dentry->d_sb);
1431+ dir = open_xa_dir (dentry->d_inode, FL_READONLY);
1432+ reiserfs_read_unlock_xattrs (dentry->d_sb);
1433+ if (IS_ERR (dir)) {
1434+ err = PTR_ERR (dir);
1435+ if (err == -ENODATA)
1436+ err = 0; /* Not an error if there aren't any xattrs */
1437+ goto out;
1438+ }
1439+
1440+ fp = dentry_open (dir, NULL, O_RDWR);
1441+ if (IS_ERR (fp)) {
1442+ err = PTR_ERR (fp);
1443+ /* dentry_open dputs the dentry if it fails */
1444+ goto out;
1445+ }
1446+
1447+ buf.r_buf = buffer;
1448+ buf.r_size = buffer ? size : 0;
1449+ buf.r_pos = 0;
1450+ buf.r_inode = dentry->d_inode;
1451+
1452+ err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf);
1453+ if (err)
1454+ goto out_dir;
1455+
1456+ if (buf.r_pos > buf.r_size && buffer != NULL)
1457+ err = -ERANGE;
1458+ else
1459+ err = buf.r_pos;
1460+
1461+out_dir:
1462+ fput(fp);
1463+
1464+out:
1465+ return err;
1466+}
1467+
1468+/* This is the implementation for the xattr plugin infrastructure */
1469+static struct reiserfs_xattr_handler *xattr_handlers;
1470+static rwlock_t handler_lock = RW_LOCK_UNLOCKED;
1471+
1472+static struct reiserfs_xattr_handler *
1473+find_xattr_handler_prefix (const char *prefix)
1474+{
1475+ struct reiserfs_xattr_handler **xah;
1476+ read_lock (&handler_lock);
1477+ for (xah = &xattr_handlers; *xah; xah=&(*xah)->next)
1478+ if (strncmp ((*xah)->prefix, prefix, strlen ((*xah)->prefix)) == 0)
1479+ break;
1480+ read_unlock (&handler_lock);
1481+ return *xah;
1482+}
1483+
1484+int
1485+reiserfs_xattr_register_handler (struct reiserfs_xattr_handler *handler)
1486+{
1487+ int res = 0;
1488+ struct reiserfs_xattr_handler **xah;
1489+
1490+ if (!handler)
1491+ return -EINVAL;
1492+
1493+ if (handler->next)
1494+ return -EBUSY;
1495+
1496+ write_lock (&handler_lock);
1497+
1498+ for (xah = &xattr_handlers; *xah; xah=&(*xah)->next) {
1499+ if (strcmp ((*xah)->prefix, handler->prefix) == 0)
1500+ break;
1501+ }
1502+ if (*xah)
1503+ res = -EBUSY;
1504+ else
1505+ *xah = handler;
1506+
1507+ /*
1508+ if (!res)
1509+ printk ("ReiserFS: Registered xattr handler for %s\n", handler->prefix);
1510+ */
1511+
1512+ write_unlock (&handler_lock);
1513+ return res;
1514+}
1515+
1516+int
1517+reiserfs_xattr_unregister_handler (struct reiserfs_xattr_handler *handler)
1518+{
1519+ struct reiserfs_xattr_handler **xah;
1520+ write_lock (&handler_lock);
1521+
1522+ xah = &xattr_handlers;
1523+ while (*xah) {
1524+ if (handler == *xah) {
1525+ *xah = handler->next;
1526+ handler->next = NULL;
1527+ write_unlock (&handler_lock);
1528+ /*
1529+ printk ("ReiserFS: Unregistered xattr handler for %s\n",
1530+ handler->prefix);
1531+ */
1532+ return 0;
1533+ }
1534+ xah = &(*xah)->next;
1535+ }
1536+ write_unlock (&handler_lock);
1537+ return -EINVAL;
1538+}
1539+
1540+/* We need to take a copy of the mount flags since things like
1541+ * MS_RDONLY don't get set until *after* we're called.
1542+ * mount_flags != mount_options */
1543+
1544+int
1545+reiserfs_xattr_init (struct super_block *s, int mount_flags)
1546+{
1547+ int err = 0;
1548+
1549+ /* If the user has requested an optional xattrs type (e.g. user/acl), then
1550+ * enable xattrs. If we're a v3.5 filesystem, this will get caught and
1551+ * error out. If no optional xattrs are enabled, disable xattrs */
1552+ if (reiserfs_xattrs_optional (s))
1553+ set_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
1554+ else
1555+ clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
1556+
1557+ if (reiserfs_xattrs (s)) {
1558+ /* We need generation numbers to ensure that the oid mapping is correct
1559+ * v3.5 filesystems don't have them. */
1560+ if (old_format_only (s)) {
1561+ reiserfs_warning (s, "reiserfs: xattrs not supported on pre v3.6 "
1562+ "format filesystem. Failing mount.\n");
1563+ err = -EOPNOTSUPP;
1564+ goto error;
1565+ } else if (!s->u.reiserfs_sb.priv_root) {
1566+ struct dentry *dentry;
1567+ dentry = lookup_one_len (PRIVROOT_NAME, s->s_root,
1568+ strlen (PRIVROOT_NAME));
1569+ if (!IS_ERR (dentry)) {
1570+ if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
1571+ struct inode *inode = dentry->d_parent->d_inode;
1572+ down (&inode->i_sem);
1573+ err = inode->i_op->mkdir (inode, dentry, 0700);
1574+ up (&inode->i_sem);
1575+ if (err) {
1576+ dput (dentry);
1577+ dentry = NULL;
1578+ }
1579+
1580+ if (dentry && dentry->d_inode)
1581+ reiserfs_warning (inode->i_sb, "reiserfs: Created %s on %s - reserved for "
1582+ "xattr storage.\n", PRIVROOT_NAME,
1583+ bdevname (inode->i_sb->s_dev));
1584+ } else if (!dentry->d_inode) {
1585+ dput (dentry);
1586+ dentry = NULL;
1587+ }
1588+ } else
1589+ err = PTR_ERR (dentry);
1590+
1591+ if (!err && dentry) {
1592+ d_drop (dentry);
1593+ dentry->d_inode->u.reiserfs_i.i_flags |= i_priv_object;
1594+ s->u.reiserfs_sb.priv_root = dentry;
1595+ } else { /* xattrs are unavailable */
1596+ /* If we're read-only it just means that the dir hasn't been
1597+ * created. Not an error -- just no xattrs on the fs. We'll
1598+ * check again if we go read-write */
1599+ if (!(mount_flags & MS_RDONLY)) {
1600+ reiserfs_warning (s, "reiserfs: xattrs enabled and couldn't "
1601+ "find/create .reiserfs_priv. Failing mount.\n");
1602+ err = -EOPNOTSUPP;
1603+ goto error;
1604+ }
1605+ /* Just to speed things up a bit since it won't find anything and
1606+ * we're read-only */
1607+ clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
1608+ clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
1609+ }
1610+ }
1611+ }
1612+
1613+error:
1614+ /* This is only nonzero if there was an error initializing the xattr
1615+ * directory or if there is a condition where we don't support them. */
1616+
1617+ if (err) {
1618+ clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
1619+ clear_bit (REISERFS_XATTRS_USER, &(s->u.reiserfs_sb.s_mount_opt));
1620+ }
1621+ return err;
1622+}
1623diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/fs/reiserfs/xattr_user.c linux-2.4.23.xattr/fs/reiserfs/xattr_user.c
1624--- linux-2.4.23.datalogging+quota/fs/reiserfs/xattr_user.c 1969-12-31 19:00:00.000000000 -0500
1625+++ linux-2.4.23.xattr/fs/reiserfs/xattr_user.c 2003-12-11 12:55:03.333492824 -0500
1626@@ -0,0 +1,108 @@
1627+#include <linux/reiserfs_fs.h>
1628+#include <linux/errno.h>
1629+#include <linux/fs.h>
1630+#include <linux/pagemap.h>
1631+#include <linux/xattr.h>
1632+#include <linux/reiserfs_xattr.h>
1633+#include <asm/uaccess.h>
1634+
1635+#define XATTR_USER_PREFIX "user."
1636+
1637+static int
1638+user_get (struct inode *inode, const char *name, void *buffer, size_t size)
1639+{
1640+
1641+ int error;
1642+
1643+ if (strlen(name) < sizeof(XATTR_USER_PREFIX))
1644+ return -EINVAL;
1645+
1646+ if (!reiserfs_xattrs_user (inode->i_sb))
1647+ return -EOPNOTSUPP;
1648+
1649+ error = permission (inode, MAY_READ);
1650+ if (error)
1651+ return error;
1652+
1653+ return reiserfs_xattr_get (inode, name, buffer, size);
1654+}
1655+
1656+static int
1657+user_set (struct inode *inode, const char *name, const void *buffer,
1658+ size_t size, int flags)
1659+{
1660+
1661+ int error;
1662+
1663+ if (strlen(name) < sizeof(XATTR_USER_PREFIX))
1664+ return -EINVAL;
1665+
1666+ if (!reiserfs_xattrs_user (inode->i_sb))
1667+ return -EOPNOTSUPP;
1668+
1669+ if (!S_ISREG (inode->i_mode) &&
1670+ (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
1671+ return -EPERM;
1672+
1673+ error = permission (inode, MAY_WRITE);
1674+ if (error)
1675+ return error;
1676+
1677+ return reiserfs_xattr_set (inode, name, buffer, size, flags);
1678+}
1679+
1680+static int
1681+user_del (struct inode *inode, const char *name)
1682+{
1683+ int error;
1684+
1685+ if (strlen(name) < sizeof(XATTR_USER_PREFIX))
1686+ return -EINVAL;
1687+
1688+ if (!reiserfs_xattrs_user (inode->i_sb))
1689+ return -EOPNOTSUPP;
1690+
1691+ if (!S_ISREG (inode->i_mode) &&
1692+ (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
1693+ return -EPERM;
1694+
1695+ error = permission (inode, MAY_WRITE);
1696+ if (error)
1697+ return error;
1698+
1699+ return 0;
1700+}
1701+
1702+static int
1703+user_list (struct inode *inode, const char *name, int namelen, char *out)
1704+{
1705+ int len = namelen;
1706+ if (!reiserfs_xattrs_user (inode->i_sb))
1707+ return 0;
1708+
1709+ if (out)
1710+ memcpy (out, name, len);
1711+
1712+ return len;
1713+}
1714+
1715+
1716+struct reiserfs_xattr_handler user_handler = {
1717+ prefix: XATTR_USER_PREFIX,
1718+ get: user_get,
1719+ set: user_set,
1720+ del: user_del,
1721+ list: user_list,
1722+};
1723+
1724+int __init
1725+reiserfs_xattr_user_init (void)
1726+{
1727+ return reiserfs_xattr_register_handler (&user_handler);
1728+}
1729+
1730+int
1731+reiserfs_xattr_user_exit (void)
1732+{
1733+ return reiserfs_xattr_unregister_handler (&user_handler);
1734+}
1735diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/include/linux/reiserfs_fs.h linux-2.4.23.xattr/include/linux/reiserfs_fs.h
1736--- linux-2.4.23.datalogging+quota/include/linux/reiserfs_fs.h 2003-12-11 12:54:29.715603520 -0500
1737+++ linux-2.4.23.xattr/include/linux/reiserfs_fs.h 2003-12-11 12:55:03.335492520 -0500
1738@@ -2012,6 +2012,7 @@ static inline void reiserfs_update_sd(st
1739
1740 void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
1741 void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
1742+int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
1743
1744 /* namei.c */
1745 inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
1746@@ -2081,6 +2082,7 @@ int reiserfs_journal_in_proc( char *buff
1747
1748 /* dir.c */
1749 extern struct inode_operations reiserfs_dir_inode_operations;
1750+extern struct inode_operations reiserfs_symlink_inode_operations;
1751 extern struct file_operations reiserfs_dir_operations;
1752
1753 /* tail_conversion.c */
1754@@ -2301,6 +2303,9 @@ int reiserfs_unpack (struct inode * inod
1755 #define REISERFS_IOC_GETVERSION EXT2_IOC_GETVERSION
1756 #define REISERFS_IOC_SETVERSION EXT2_IOC_SETVERSION
1757
1758+/* xattr stuff */
1759+#define REISERFS_XATTR_DIR_SEM(s) ((s)->u.reiserfs_sb.xattr_dir_sem)
1760+
1761 #endif /* _LINUX_REISER_FS_H */
1762
1763
1764diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/include/linux/reiserfs_fs_i.h linux-2.4.23.xattr/include/linux/reiserfs_fs_i.h
1765--- linux-2.4.23.datalogging+quota/include/linux/reiserfs_fs_i.h 2003-12-11 12:54:15.944697016 -0500
1766+++ linux-2.4.23.xattr/include/linux/reiserfs_fs_i.h 2003-12-11 12:55:03.335492520 -0500
1767@@ -28,6 +28,7 @@ typedef enum {
1768 i_link_saved_truncate_mask = 0x0020,
1769 /** are we logging data blocks for this file? */
1770 i_data_log = 0x0040,
1771+ i_priv_object = 0x0080,
1772 } reiserfs_inode_flags;
1773
1774
1775diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/include/linux/reiserfs_fs_sb.h linux-2.4.23.xattr/include/linux/reiserfs_fs_sb.h
1776--- linux-2.4.23.datalogging+quota/include/linux/reiserfs_fs_sb.h 2003-12-11 12:54:15.945696864 -0500
1777+++ linux-2.4.23.xattr/include/linux/reiserfs_fs_sb.h 2003-12-11 12:55:03.336492368 -0500
1778@@ -6,6 +6,7 @@
1779
1780 #ifdef __KERNEL__
1781 #include <linux/tqueue.h>
1782+#include <linux/rwsem.h>
1783 #endif
1784
1785 //
1786@@ -442,6 +443,9 @@ struct reiserfs_sb_info
1787 struct proc_dir_entry *procdir;
1788 int reserved_blocks; /* amount of blocks reserved for further allocations */
1789 struct list_head s_reiserfs_supers;
1790+ struct dentry *priv_root; /* root of /.reiserfs_priv */
1791+ struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
1792+ struct rw_semaphore xattr_dir_sem;
1793 };
1794
1795 /* Definitions of reiserfs on-disk properties: */
1796@@ -486,6 +490,8 @@ enum {
1797 REISERFS_DATA_WRITEBACK,
1798 REISERFS_ATTRS,
1799 REISERFS_TEST4,
1800+ REISERFS_XATTRS,
1801+ REISERFS_XATTRS_USER,
1802 };
1803
1804 #define reiserfs_r5_hash(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << FORCE_R5_HASH))
1805@@ -507,6 +513,9 @@ enum {
1806 #define reiserfs_attrs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_ATTRS))
1807 #define old_format_only(s) ((s)->u.reiserfs_sb.s_properties & (1 << REISERFS_3_5))
1808 #define convert_reiserfs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_CONVERT))
1809+#define reiserfs_xattrs(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_XATTRS))
1810+#define reiserfs_xattrs_user(s) ((s)->u.reiserfs_sb.s_mount_opt & (1 << REISERFS_XATTRS_USER))
1811+#define reiserfs_xattrs_optional(s) reiserfs_xattrs_user(s)
1812
1813
1814 void reiserfs_file_buffer (struct buffer_head * bh, int list);
1815diff -ruNp -X ../dontdiff linux-2.4.23.datalogging+quota/include/linux/reiserfs_xattr.h linux-2.4.23.xattr/include/linux/reiserfs_xattr.h
1816--- linux-2.4.23.datalogging+quota/include/linux/reiserfs_xattr.h 1969-12-31 19:00:00.000000000 -0500
1817+++ linux-2.4.23.xattr/include/linux/reiserfs_xattr.h 2003-12-11 12:55:03.337492216 -0500
1818@@ -0,0 +1,114 @@
1819+/*
1820+ File: linux/reiserfs_xattr.h
1821+*/
1822+
1823+#include <linux/config.h>
1824+#include <linux/init.h>
1825+#include <linux/xattr.h>
1826+
1827+/* Magic value in header */
1828+#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
1829+
1830+struct reiserfs_xattr_header {
1831+ __u32 h_magic; /* magic number for identification */
1832+ __u32 h_hash; /* hash of the value */
1833+};
1834+
1835+#ifdef __KERNEL__
1836+
1837+struct reiserfs_xattr_handler {
1838+ char *prefix;
1839+ int (*get)(struct inode *inode, const char *name, void *buffer,
1840+ size_t size);
1841+ int (*set)(struct inode *inode, const char *name, const void *buffer,
1842+ size_t size, int flags);
1843+ int (*del)(struct inode *inode, const char *name);
1844+ int (*list)(struct inode *inode, const char *name, int namelen, char *out);
1845+ struct reiserfs_xattr_handler *next;
1846+};
1847+
1848+
1849+#ifdef CONFIG_REISERFS_FS_XATTR
1850+#define is_reiserfs_priv_object(inode) (((inode)->u.reiserfs_i.i_flags & i_priv_object) == i_priv_object)
1851+ssize_t reiserfs_getxattr (struct dentry *dentry, const char *name,
1852+ void *buffer, size_t size);
1853+int reiserfs_setxattr (struct dentry *dentry, const char *name,
1854+ const void *value, size_t size, int flags);
1855+ssize_t reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size);
1856+int reiserfs_removexattr (struct dentry *dentry, const char *name);
1857+int reiserfs_delete_xattrs (struct inode *inode);
1858+int reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs);
1859+int reiserfs_xattr_init (struct super_block *sb, int mount_flags);
1860+
1861+static inline void
1862+reiserfs_write_lock_xattrs(struct super_block *sb)
1863+{
1864+ down_write (&REISERFS_XATTR_DIR_SEM(sb));
1865+}
1866+static inline void
1867+reiserfs_write_unlock_xattrs(struct super_block *sb)
1868+{
1869+ up_write (&REISERFS_XATTR_DIR_SEM(sb));
1870+}
1871+static inline void
1872+reiserfs_read_lock_xattrs(struct super_block *sb)
1873+{
1874+ down_read (&REISERFS_XATTR_DIR_SEM(sb));
1875+}
1876+static inline void
1877+reiserfs_read_unlock_xattrs(struct super_block *sb)
1878+{
1879+ up_read (&REISERFS_XATTR_DIR_SEM(sb));
1880+}
1881+#else
1882+#define is_reiserfs_priv_object(inode) 0
1883+#define reiserfs_getxattr NULL
1884+#define reiserfs_setxattr NULL
1885+#define reiserfs_listxattr NULL
1886+#define reiserfs_removexattr NULL
1887+#define reiserfs_write_lock_xattrs(sb)
1888+#define reiserfs_write_unlock_xattrs(sb)
1889+#define reiserfs_read_lock_xattrs(sb)
1890+#define reiserfs_read_unlock_xattrs(sb)
1891+static inline int
1892+reiserfs_xattr_init (struct super_block *s, int mount_flags)
1893+{
1894+ return 0;
1895+}
1896+
1897+static inline int
1898+reiserfs_delete_xattrs (struct inode *inode)
1899+{
1900+ return 0;
1901+}
1902+
1903+static inline int
1904+reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
1905+{
1906+ return 0;
1907+}
1908+#endif
1909+
1910+extern int reiserfs_xattr_register_handler(struct reiserfs_xattr_handler *);
1911+extern int reiserfs_xattr_unregister_handler(struct reiserfs_xattr_handler *);
1912+extern int reiserfs_xattr_del (struct inode *, const char *);
1913+extern int reiserfs_xattr_get (const struct inode *, const char *, void *, size_t);
1914+extern int reiserfs_xattr_set (struct inode *, const char *, const void *,
1915+ size_t, int);
1916+#ifdef CONFIG_REISERFS_FS_XATTR_USER
1917+extern int reiserfs_xattr_user_init (void) __init;
1918+extern int reiserfs_xattr_user_exit (void);
1919+#else
1920+static inline int
1921+reiserfs_xattr_user_init (void)
1922+{
1923+ return 0;
1924+}
1925+
1926+static inline int
1927+reiserfs_xattr_user_exit (void)
1928+{
1929+ return 0;
1930+}
1931+#endif
1932+#endif /* __KERNEL__ */
This page took 0.258467 seconds and 4 git commands to generate.