1 diff -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
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
13 diff -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
20 +obj-$(CONFIG_REISERFS_FS_XATTR) += xattr.o
21 +obj-$(CONFIG_REISERFS_FS_XATTR_USER) += xattr_user.o
25 # gcc -O2 (the kernel default) is overaggressive on ppc32 when many inline
26 diff -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 */
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))
42 d_off = deh_offset (deh);
44 d_ino = deh_objectid (deh);
45 diff -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
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>
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,
67 diff -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
71 #include <linux/sched.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 */
83 + reiserfs_delete_xattrs (inode);
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;
97 @@ -2689,6 +2693,70 @@ static int reiserfs_direct_io(int rw, st
98 reiserfs_get_block_direct_io) ;
101 +int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
103 + struct inode *inode = dentry->d_inode ;
105 + unsigned int ia_valid = attr->ia_valid ;
107 + if (ia_valid & ATTR_SIZE) {
108 + /* version 2 items will be caught by the s_maxbytes check
109 + ** done for us in vmtruncate
111 + if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
112 + attr->ia_size > MAX_NON_LFS)
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.
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) ;
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 */
145 + error = inode_change_ok(inode, attr) ;
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);
156 + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
160 + error = inode_setattr(inode, attr) ;
165 struct address_space_operations reiserfs_address_space_operations = {
166 writepage: reiserfs_writepage,
167 readpage: reiserfs_readpage,
168 diff -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
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>
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);
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);
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;
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) ;
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;
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,
222 + * symlink operations.. same as page_symlink_inode_operations, with xattr
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,
234 diff -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
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
248 struct reiserfs_transaction_handle th ;
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);
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);
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},
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},
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;
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
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
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 */
301 @@ -811,6 +830,7 @@ static int reiserfs_remount (struct supe
303 if (!( *mount_flags & MS_RDONLY ) ) {
304 finish_unfinished( s );
305 + reiserfs_xattr_init (s, *mount_flags);
306 handle_data_mode(s, mount_options);
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);
316 if (reiserfs_parse_options (s, (char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
318 @@ -1378,11 +1400,23 @@ static struct super_block * reiserfs_rea
320 journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
321 journal_end(&th, s, 1) ;
324 + if (reiserfs_xattr_init (s, s->s_flags)) {
330 /* look for files which were to be removed in previous session */
331 finish_unfinished (s);
335 + if (reiserfs_xattr_init (s, s->s_flags)) {
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();
348 + goto failed_journal_cache_init;
350 + ret = reiserfs_xattr_user_init ();
352 + goto failed_xattr_user_init;
354 return register_filesystem(&reiserfs_fs_type);
356 +failed_xattr_user_init:
357 +failed_journal_cache_init:
358 + reiserfs_proc_unregister_global( "version" );
359 + reiserfs_proc_info_global_done();
364 MODULE_DESCRIPTION("ReiserFS journaled filesystem");
365 @@ -1457,6 +1503,7 @@ MODULE_LICENSE("GPL");
367 static void __exit exit_reiserfs_fs(void)
369 + reiserfs_xattr_user_exit ();
370 reiserfs_proc_unregister_global( "version" );
371 reiserfs_proc_info_global_done();
372 unregister_filesystem(&reiserfs_fs_type);
373 diff -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
378 + * linux/fs/reiserfs/xattr.c
380 + * Copyright (c) 2002 by Jeff Mahoney, <jeffm@suse.com>
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.
393 + * So, for objectid 12648430, we could have:
394 + * /.reiserfs_priv/xattrs/C0FFEE.0/user.Content-Type
397 + * The file contents are the text of the EA. The size is known based on the
398 + * stat data describing the file.
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>
417 +#define FL_READONLY 128
418 +#define FL_DIR_SEM_HELD 256
419 +#define PRIVROOT_NAME ".reiserfs_priv"
420 +#define XAROOT_NAME "xattrs"
422 +static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix);
424 +static struct dentry *
425 +create_xa_root (struct super_block *sb)
427 + struct dentry *privroot = dget (sb->u.reiserfs_sb.priv_root);
428 + struct dentry *xaroot;
430 + /* This needs to be created at mount-time */
432 + return ERR_PTR(-EOPNOTSUPP);
434 + xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
435 + if (IS_ERR (xaroot)) {
437 + } else if (!xaroot->d_inode) {
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);
446 + return ERR_PTR (err);
448 + sb->u.reiserfs_sb.xattr_root = dget (xaroot);
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)
463 + struct dentry *privroot = dget (s->u.reiserfs_sb.priv_root);
464 + struct dentry *xaroot = NULL;
466 + if (IS_ERR (privroot) || !privroot)
469 + xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
470 + if (IS_ERR (xaroot)) {
472 + } else if (!xaroot->d_inode) {
478 + s->u.reiserfs_sb.xattr_root = dget (xaroot);
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.
490 +static inline struct dentry *
491 +get_xa_root (struct super_block *s)
493 + struct dentry *dentry = s->u.reiserfs_sb.xattr_root;
496 + dentry = __get_xa_root (s);
502 +/* Same as above, but only returns a valid dentry or NULL */
504 +reiserfs_get_xa_root (struct super_block *sb)
506 + struct dentry *dentry;
508 + dentry = get_xa_root (sb);
509 + if (IS_ERR (dentry)) {
511 + } else if (dentry && !dentry->d_inode) {
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)
525 + struct dentry *xaroot, *xadir;
528 + xaroot = get_xa_root (inode->i_sb);
529 + if (IS_ERR (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))
538 + return ERR_PTR (-ENODATA);
541 + /* ok, we have xaroot open */
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)) {
552 + if (!xadir->d_inode) {
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);
562 + return ERR_PTR (err);
565 + if (!xadir->d_inode) {
568 + return ERR_PTR (-ENODATA);
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)
582 + struct dentry *xadir, *xafile;
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) {
590 + return ERR_PTR (-ENODATA);
593 + xafile = lookup_one_len (name, xadir, strlen (name));
594 + if (IS_ERR (xafile)) {
596 + return ERR_PTR (PTR_ERR (xafile));
599 + if (xafile->d_inode) { /* file exists */
600 + if (flags & XATTR_CREATE) {
605 + } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
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,
622 + xafile = ERR_PTR (err);
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)
631 + struct dentry *xafile;
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) {
639 + return ERR_PTR (-ENODATA);
642 + fp = dentry_open (xafile, NULL, O_RDWR);
643 + /* dentry_open dputs the dentry if it fails */
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
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.
659 + * we're called with i_sem held, so there are no worries about the directory
660 + * changing underneath us.
662 +static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir)
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;
669 + struct item_head * ih, tmp_ih;
673 + char small_buf[32] ; /* avoid kmalloc if we can */
674 + struct reiserfs_de_head *deh;
679 + struct reiserfs_dir_entry de;
682 + /* form key for search the next directory entry using f_pos field of
684 + next_pos = max_reiserfs_offset(inode);
688 + if (next_pos <= DOT_DOT_OFFSET)
690 + make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
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
696 + pathrelse(&path_to_entry);
700 + if (search_res == NAME_NOT_FOUND)
703 + set_de_name_and_namelen(&de);
704 + entry_num = de.de_entry_num;
705 + deh = &(de.de_deh[entry_num]);
710 + if (!is_direntry_le_ih(ih)) {
711 + reiserfs_warning(inode->i_sb, "not direntry %h\n", ih);
714 + copy_item_head(&tmp_ih, ih);
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",
721 + if (deh_offset(deh) <= DOT_DOT_OFFSET) {
725 + /* look for the previous entry in the directory */
726 + next_pos = deh_offset (deh) - 1;
728 + if (!de_visible (deh))
729 + /* it is hidden entry */
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);
737 + if (!d_name[d_reclen - 1])
738 + d_reclen = strlen (d_name);
740 + if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
741 + /* too big to send back to VFS */
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))
751 + if (d_reclen <= 32) {
752 + local_buf = small_buf ;
754 + local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
756 + pathrelse (&path_to_entry);
759 + if (item_moved (&tmp_ih, &path_to_entry)) {
760 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
762 + /* sigh, must retry. Do this same offset again */
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);
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
778 + pathrelse (&path_to_entry);
780 + if (filldir (dirent, local_buf, d_reclen, d_off, d_ino,
782 + if (local_buf != small_buf) {
783 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
787 + if (local_buf != small_buf) {
788 + reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
793 + pathrelse (&path_to_entry);
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
804 +int xattr_readdir(struct file *file, filldir_t filler, void *buf)
806 + struct inode *inode = file->f_dentry->d_inode;
807 + int res = -ENOTDIR;
808 + if (!file->f_op || !file->f_op->readdir)
810 + down(&inode->i_sem);
811 + down(&inode->i_zombie);
813 + if (!IS_DEADDIR(inode)) {
815 + res = __xattr_readdir(file, buf, filler);
818 + up(&inode->i_zombie);
825 +/* Internal operations on file data */
827 +reiserfs_put_page(struct page *page)
830 + page_cache_release(page);
833 +static struct page *
834 +reiserfs_get_page(struct inode *dir, unsigned long n)
836 + struct address_space *mapping = dir->i_mapping;
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);
846 + if (!Page_Uptodate(page))
849 + if (PageError(page))
855 + reiserfs_put_page(page);
856 + return ERR_PTR(-EIO);
860 +xattr_hash (const char *msg, int len)
862 + return csum_partial (msg, len, 0);
865 +/* Generic extended attribute operations that can be used by xa plugins */
868 + * inode->i_sem: down
871 +reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer,
872 + size_t buffer_size, int flags)
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;
885 + if (get_inode_sd_version (inode) == STAT_DATA_V1)
886 + return -EOPNOTSUPP;
888 + /* Empty xattrs are ok, they're just empty files, no hash */
889 + if (buffer && buffer_size)
890 + xahash = xattr_hash (buffer, buffer_size);
893 + fp = open_xa_file (inode, name, flags);
895 + err = PTR_ERR (fp);
899 + xinode = fp->f_dentry->d_inode;
901 + /* we need to copy it off.. */
902 + if (xinode->i_nlink > 1) {
904 + err = reiserfs_xattr_del (inode, name);
907 + /* We just killed the old one, we're not replacing anymore */
908 + if (flags & XATTR_REPLACE)
909 + flags &= ~XATTR_REPLACE;
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);
921 + mapping = xinode->i_mapping;
922 + while (buffer_pos < buffer_size || buffer_pos == 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;
929 + chunk = buffer_size - buffer_pos;
931 + page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
932 + if (IS_ERR (page)) {
933 + err = PTR_ERR (page);
938 + data = page_address (page);
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);
950 + err = mapping->a_ops->prepare_write (fp, page, page_offset,
951 + page_offset + chunk + skip);
954 + memcpy (data + skip, buffer + buffer_pos, chunk);
955 + err = mapping->a_ops->commit_write (fp, page, page_offset,
956 + page_offset + chunk + skip);
959 + reiserfs_put_page (page);
960 + buffer_pos += chunk;
963 + if (err || buffer_size == 0 || !buffer)
968 + up (&xinode->i_sem);
976 + * inode->i_sem: down
979 +reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer,
980 + size_t buffer_size)
985 + size_t file_pos = 0;
986 + size_t buffer_pos = 0;
988 + struct inode *xinode;
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;
996 + fp = open_xa_file (inode, name, FL_READONLY);
998 + err = PTR_ERR (fp);
1002 + xinode = fp->f_dentry->d_inode;
1003 + isize = xinode->i_size;
1005 + /* Just return the size needed */
1006 + if (buffer == NULL) {
1007 + err = isize - sizeof (struct reiserfs_xattr_header);
1011 + if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) {
1016 + while (file_pos < isize) {
1020 + if (isize - file_pos > PAGE_CACHE_SIZE)
1021 + chunk = PAGE_CACHE_SIZE;
1023 + chunk = isize - file_pos;
1025 + page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
1026 + if (IS_ERR (page)) {
1027 + err = PTR_ERR (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);
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);
1045 + hash = le32_to_cpu (rxh->h_hash);
1047 + memcpy (buffer + buffer_pos, data + skip, chunk);
1048 + UnlockPage (page);
1049 + reiserfs_put_page (page);
1050 + file_pos += chunk;
1051 + buffer_pos += chunk;
1054 + err = isize - sizeof (struct reiserfs_xattr_header);
1056 + if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash)
1067 +__reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen)
1069 + struct dentry *file;
1070 + struct inode *dir = xadir->d_inode;
1073 + file = lookup_one_len (name, xadir, namelen);
1074 + if (IS_ERR (file)) {
1075 + err = PTR_ERR (file);
1077 + } else if (!file->d_inode) {
1082 + /* Skip directories.. */
1083 + if (S_ISDIR (file->d_inode->i_mode))
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));
1092 + err = dir->i_op->unlink (dir, file);
1105 +reiserfs_xattr_del (struct inode *inode, const char *name)
1107 + struct dentry *dir;
1110 + dir = open_xa_dir (inode, FL_READONLY);
1111 + if (IS_ERR (dir)) {
1112 + err = PTR_ERR (dir);
1116 + err = __reiserfs_xattr_del (dir, name, strlen (name));
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. */
1128 +reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen,
1129 + loff_t offset, ino_t ino, unsigned int d_type)
1131 + struct dentry *xadir = (struct dentry *)buf;
1133 + return __reiserfs_xattr_del (xadir, name, namelen);
1138 +reiserfs_delete_xattrs (struct inode *inode)
1141 + struct dentry *dir, *root;
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))
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);
1157 + } else if (!dir->d_inode) {
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 */
1170 + err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir);
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);
1184 + reiserfs_warning (inode->i_sb, "Couldn't remove all entries in directory\n");
1195 +struct reiserfs_chown_buf {
1196 + struct inode *inode;
1197 + struct dentry *xadir;
1198 + struct iattr *attrs;
1201 +/* XXX: If there is a better way to do this, I'd love to hear about it */
1203 +reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen,
1204 + loff_t offset, ino_t ino, unsigned int d_type)
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;
1211 + xafile = lookup_one_len (name, xadir, namelen);
1212 + if (IS_ERR (xafile))
1213 + return PTR_ERR (xafile);
1214 + else if (!xafile->d_inode) {
1219 + if (!S_ISDIR (xafile->d_inode->i_mode))
1220 + err = notify_change (xafile, attrs);
1227 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
1230 + struct dentry *dir;
1232 + struct reiserfs_chown_buf buf;
1233 + unsigned int ia_valid = attrs->ia_valid;
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))
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);
1249 + } else if (!dir->d_inode) {
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 */
1263 + attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
1265 + buf.attrs = attrs;
1266 + buf.inode = inode;
1268 + err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf);
1274 + err = notify_change (dir, attrs);
1281 + attrs->ia_valid = ia_valid;
1286 +/* Actual operations that are exported to VFS-land */
1289 + * Inode operation getxattr()
1290 + * dentry->d_inode->i_sem down
1291 + * BKL held [before 2.5.x]
1294 +reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer,
1297 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1300 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1301 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1302 + return -EOPNOTSUPP;
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);
1312 + * Inode operation setxattr()
1314 + * dentry->d_inode->i_sem down
1315 + * BKL held [before 2.5.x]
1318 +reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value,
1319 + size_t size, int flags)
1321 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1324 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1325 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1326 + return -EOPNOTSUPP;
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);
1336 + * Inode operation removexattr()
1338 + * dentry->d_inode->i_sem down
1339 + * BKL held [before 2.5.x]
1342 +reiserfs_removexattr (struct dentry *dentry, const char *name)
1345 + struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
1347 + if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
1348 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1349 + return -EOPNOTSUPP;
1351 + down (&dentry->d_inode->i_zombie);
1352 + reiserfs_read_lock_xattrs (dentry->d_sb);
1354 + /* Deletion pre-operation */
1356 + err = xah->del (dentry->d_inode, name);
1358 + reiserfs_read_unlock_xattrs (dentry->d_sb);
1359 + up (&dentry->d_inode->i_zombie);
1364 + err = reiserfs_xattr_del (dentry->d_inode, name);
1365 + reiserfs_read_unlock_xattrs (dentry->d_sb);
1366 + up (&dentry->d_inode->i_zombie);
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 {
1380 + struct inode *r_inode;
1384 +reiserfs_listxattr_filler (void *buf, const char *name, int namelen,
1385 + loff_t offset, ino_t ino, unsigned int d_type)
1387 + struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
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 */
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);
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);
1403 + b->r_pos += len + 1;
1410 + * Inode operation listxattr()
1412 + * dentry->d_inode->i_sem down
1413 + * BKL held [before 2.5.x]
1416 +reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
1419 + struct dentry *dir;
1421 + struct reiserfs_listxattr_buf buf;
1423 + if (!dentry->d_inode)
1426 + if (!reiserfs_xattrs(dentry->d_sb) ||
1427 + get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
1428 + return -EOPNOTSUPP;
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 */
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 */
1447 + buf.r_buf = buffer;
1448 + buf.r_size = buffer ? size : 0;
1450 + buf.r_inode = dentry->d_inode;
1452 + err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf);
1456 + if (buf.r_pos > buf.r_size && buffer != NULL)
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;
1472 +static struct reiserfs_xattr_handler *
1473 +find_xattr_handler_prefix (const char *prefix)
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)
1480 + read_unlock (&handler_lock);
1485 +reiserfs_xattr_register_handler (struct reiserfs_xattr_handler *handler)
1488 + struct reiserfs_xattr_handler **xah;
1493 + if (handler->next)
1496 + write_lock (&handler_lock);
1498 + for (xah = &xattr_handlers; *xah; xah=&(*xah)->next) {
1499 + if (strcmp ((*xah)->prefix, handler->prefix) == 0)
1509 + printk ("ReiserFS: Registered xattr handler for %s\n", handler->prefix);
1512 + write_unlock (&handler_lock);
1517 +reiserfs_xattr_unregister_handler (struct reiserfs_xattr_handler *handler)
1519 + struct reiserfs_xattr_handler **xah;
1520 + write_lock (&handler_lock);
1522 + xah = &xattr_handlers;
1524 + if (handler == *xah) {
1525 + *xah = handler->next;
1526 + handler->next = NULL;
1527 + write_unlock (&handler_lock);
1529 + printk ("ReiserFS: Unregistered xattr handler for %s\n",
1534 + xah = &(*xah)->next;
1536 + write_unlock (&handler_lock);
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 */
1545 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
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));
1555 + clear_bit (REISERFS_XATTRS, &(s->u.reiserfs_sb.s_mount_opt));
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;
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);
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) {
1589 + err = PTR_ERR (dentry);
1591 + if (!err && 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;
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));
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. */
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));
1623 diff -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
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>
1635 +#define XATTR_USER_PREFIX "user."
1638 +user_get (struct inode *inode, const char *name, void *buffer, size_t size)
1643 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
1646 + if (!reiserfs_xattrs_user (inode->i_sb))
1647 + return -EOPNOTSUPP;
1649 + error = permission (inode, MAY_READ);
1653 + return reiserfs_xattr_get (inode, name, buffer, size);
1657 +user_set (struct inode *inode, const char *name, const void *buffer,
1658 + size_t size, int flags)
1663 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
1666 + if (!reiserfs_xattrs_user (inode->i_sb))
1667 + return -EOPNOTSUPP;
1669 + if (!S_ISREG (inode->i_mode) &&
1670 + (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
1673 + error = permission (inode, MAY_WRITE);
1677 + return reiserfs_xattr_set (inode, name, buffer, size, flags);
1681 +user_del (struct inode *inode, const char *name)
1685 + if (strlen(name) < sizeof(XATTR_USER_PREFIX))
1688 + if (!reiserfs_xattrs_user (inode->i_sb))
1689 + return -EOPNOTSUPP;
1691 + if (!S_ISREG (inode->i_mode) &&
1692 + (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
1695 + error = permission (inode, MAY_WRITE);
1703 +user_list (struct inode *inode, const char *name, int namelen, char *out)
1705 + int len = namelen;
1706 + if (!reiserfs_xattrs_user (inode->i_sb))
1710 + memcpy (out, name, len);
1716 +struct reiserfs_xattr_handler user_handler = {
1717 + prefix: XATTR_USER_PREFIX,
1725 +reiserfs_xattr_user_init (void)
1727 + return reiserfs_xattr_register_handler (&user_handler);
1731 +reiserfs_xattr_user_exit (void)
1733 + return reiserfs_xattr_unregister_handler (&user_handler);
1735 diff -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
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);
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
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;
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
1759 +#define REISERFS_XATTR_DIR_SEM(s) ((s)->u.reiserfs_sb.xattr_dir_sem)
1761 #endif /* _LINUX_REISER_FS_H */
1764 diff -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;
1775 diff -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
1781 #include <linux/tqueue.h>
1782 +#include <linux/rwsem.h>
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;
1795 /* Definitions of reiserfs on-disk properties: */
1796 @@ -486,6 +490,8 @@ enum {
1797 REISERFS_DATA_WRITEBACK,
1801 + REISERFS_XATTRS_USER,
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)
1814 void reiserfs_file_buffer (struct buffer_head * bh, int list);
1815 diff -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
1820 + File: linux/reiserfs_xattr.h
1823 +#include <linux/config.h>
1824 +#include <linux/init.h>
1825 +#include <linux/xattr.h>
1827 +/* Magic value in header */
1828 +#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
1830 +struct reiserfs_xattr_header {
1831 + __u32 h_magic; /* magic number for identification */
1832 + __u32 h_hash; /* hash of the value */
1837 +struct reiserfs_xattr_handler {
1839 + int (*get)(struct inode *inode, const char *name, void *buffer,
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;
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);
1862 +reiserfs_write_lock_xattrs(struct super_block *sb)
1864 + down_write (&REISERFS_XATTR_DIR_SEM(sb));
1867 +reiserfs_write_unlock_xattrs(struct super_block *sb)
1869 + up_write (&REISERFS_XATTR_DIR_SEM(sb));
1872 +reiserfs_read_lock_xattrs(struct super_block *sb)
1874 + down_read (&REISERFS_XATTR_DIR_SEM(sb));
1877 +reiserfs_read_unlock_xattrs(struct super_block *sb)
1879 + up_read (&REISERFS_XATTR_DIR_SEM(sb));
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)
1892 +reiserfs_xattr_init (struct super_block *s, int mount_flags)
1898 +reiserfs_delete_xattrs (struct inode *inode)
1904 +reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
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 *,
1916 +#ifdef CONFIG_REISERFS_FS_XATTR_USER
1917 +extern int reiserfs_xattr_user_init (void) __init;
1918 +extern int reiserfs_xattr_user_exit (void);
1921 +reiserfs_xattr_user_init (void)
1927 +reiserfs_xattr_user_exit (void)
1932 +#endif /* __KERNEL__ */