aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2009-03-30 14:02:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 15:16:37 -0400
commita72bdb1cd244725ff47b3a29662e2cb820d8c60f (patch)
tree68f9022b303ca5183bd64eddbff41f0624e84188
parent6dfede696391133eadd7ce90b61c9573ee6e5a90 (diff)
reiserfs: Clean up xattrs when REISERFS_FS_XATTR is unset
The current reiserfs xattr implementation will not clean up old xattr files if files are deleted when REISERFS_FS_XATTR is unset. This results in inaccessible lost files, wasting space. This patch compiles in basic xattr knowledge, such as how to delete them and change ownership for quota tracking. If the file system has never used xattrs, then the operation is quite fast: it returns immediately when it sees there is no .reiserfs_priv directory. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/reiserfs/Makefile4
-rw-r--r--fs/reiserfs/xattr.c689
-rw-r--r--include/linux/reiserfs_fs_sb.h2
-rw-r--r--include/linux/reiserfs_xattr.h29
4 files changed, 367 insertions, 357 deletions
diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile
index 0eb7ac080484..7c5ab6330dd6 100644
--- a/fs/reiserfs/Makefile
+++ b/fs/reiserfs/Makefile
@@ -7,10 +7,10 @@ obj-$(CONFIG_REISERFS_FS) += reiserfs.o
7reiserfs-objs := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o \ 7reiserfs-objs := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o \
8 super.o prints.o objectid.o lbalance.o ibalance.o stree.o \ 8 super.o prints.o objectid.o lbalance.o ibalance.o stree.o \
9 hashes.o tail_conversion.o journal.o resize.o \ 9 hashes.o tail_conversion.o journal.o resize.o \
10 item_ops.o ioctl.o procfs.o 10 item_ops.o ioctl.o procfs.o xattr.o
11 11
12ifeq ($(CONFIG_REISERFS_FS_XATTR),y) 12ifeq ($(CONFIG_REISERFS_FS_XATTR),y)
13reiserfs-objs += xattr.o xattr_user.o xattr_trusted.o 13reiserfs-objs += xattr_user.o xattr_trusted.o
14endif 14endif
15 15
16ifeq ($(CONFIG_REISERFS_FS_SECURITY),y) 16ifeq ($(CONFIG_REISERFS_FS_SECURITY),y)
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index c5fc207e529c..f9bcdd5750f7 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -50,9 +50,6 @@
50#define PRIVROOT_NAME ".reiserfs_priv" 50#define PRIVROOT_NAME ".reiserfs_priv"
51#define XAROOT_NAME "xattrs" 51#define XAROOT_NAME "xattrs"
52 52
53static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
54 *prefix);
55
56/* Returns the dentry referring to the root of the extended attribute 53/* Returns the dentry referring to the root of the extended attribute
57 * directory tree. If it has already been retrieved, it is used. If it 54 * directory tree. If it has already been retrieved, it is used. If it
58 * hasn't been created and the flags indicate creation is allowed, we 55 * hasn't been created and the flags indicate creation is allowed, we
@@ -143,60 +140,6 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
143 return xadir; 140 return xadir;
144} 141}
145 142
146/* Returns a dentry corresponding to a specific extended attribute file
147 * for the inode. If flags allow, the file is created. Otherwise, a
148 * valid or negative dentry, or an error is returned. */
149static struct dentry *get_xa_file_dentry(const struct inode *inode,
150 const char *name, int flags)
151{
152 struct dentry *xadir, *xafile;
153 int err = 0;
154
155 xadir = open_xa_dir(inode, flags);
156 if (IS_ERR(xadir)) {
157 return ERR_CAST(xadir);
158 } else if (!xadir->d_inode) {
159 dput(xadir);
160 return ERR_PTR(-ENODATA);
161 }
162
163 xafile = lookup_one_len(name, xadir, strlen(name));
164 if (IS_ERR(xafile)) {
165 dput(xadir);
166 return ERR_CAST(xafile);
167 }
168
169 if (xafile->d_inode) { /* file exists */
170 if (flags & XATTR_CREATE) {
171 err = -EEXIST;
172 dput(xafile);
173 goto out;
174 }
175 } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
176 goto out;
177 } else {
178 /* inode->i_mutex is down, so nothing else can try to create
179 * the same xattr */
180 err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,
181 0700 | S_IFREG, NULL);
182
183 if (err) {
184 dput(xafile);
185 goto out;
186 }
187 }
188
189 out:
190 dput(xadir);
191 if (err)
192 xafile = ERR_PTR(err);
193 else if (!xafile->d_inode) {
194 dput(xafile);
195 xafile = ERR_PTR(-ENODATA);
196 }
197 return xafile;
198}
199
200/* 143/*
201 * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but 144 * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but
202 * we need to drop the path before calling the filldir struct. That 145 * we need to drop the path before calling the filldir struct. That
@@ -369,6 +312,251 @@ int xattr_readdir(struct inode *inode, filldir_t filler, void *buf)
369 return res; 312 return res;
370} 313}
371 314
315static int
316__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
317{
318 struct dentry *dentry;
319 struct inode *dir = xadir->d_inode;
320 int err = 0;
321
322 dentry = lookup_one_len(name, xadir, namelen);
323 if (IS_ERR(dentry)) {
324 err = PTR_ERR(dentry);
325 goto out;
326 } else if (!dentry->d_inode) {
327 err = -ENODATA;
328 goto out_file;
329 }
330
331 /* Skip directories.. */
332 if (S_ISDIR(dentry->d_inode->i_mode))
333 goto out_file;
334
335 if (!IS_PRIVATE(dentry->d_inode)) {
336 reiserfs_error(dir->i_sb, "jdm-20003",
337 "OID %08x [%.*s/%.*s] doesn't have "
338 "priv flag set [parent is %sset].",
339 le32_to_cpu(INODE_PKEY(dentry->d_inode)->
340 k_objectid), xadir->d_name.len,
341 xadir->d_name.name, namelen, name,
342 IS_PRIVATE(xadir->d_inode) ? "" :
343 "not ");
344 dput(dentry);
345 return -EIO;
346 }
347
348 err = dir->i_op->unlink(dir, dentry);
349 if (!err)
350 d_delete(dentry);
351
352out_file:
353 dput(dentry);
354
355out:
356 return err;
357}
358
359/* The following are side effects of other operations that aren't explicitly
360 * modifying extended attributes. This includes operations such as permissions
361 * or ownership changes, object deletions, etc. */
362
363static int
364reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
365 loff_t offset, u64 ino, unsigned int d_type)
366{
367 struct dentry *xadir = (struct dentry *)buf;
368
369 return __reiserfs_xattr_del(xadir, name, namelen);
370
371}
372
373/* This is called w/ inode->i_mutex downed */
374int reiserfs_delete_xattrs(struct inode *inode)
375{
376 struct dentry *dir, *root;
377 int err = 0;
378
379 /* Skip out, an xattr has no xattrs associated with it */
380 if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1)
381 return 0;
382
383 reiserfs_read_lock_xattrs(inode->i_sb);
384 dir = open_xa_dir(inode, FL_READONLY);
385 reiserfs_read_unlock_xattrs(inode->i_sb);
386 if (IS_ERR(dir)) {
387 err = PTR_ERR(dir);
388 goto out;
389 } else if (!dir->d_inode) {
390 dput(dir);
391 return 0;
392 }
393
394 lock_kernel();
395 err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir);
396 if (err) {
397 unlock_kernel();
398 goto out_dir;
399 }
400
401 /* Leftovers besides . and .. -- that's not good. */
402 if (dir->d_inode->i_nlink <= 2) {
403 root = get_xa_root(inode->i_sb, XATTR_REPLACE);
404 reiserfs_write_lock_xattrs(inode->i_sb);
405 err = vfs_rmdir(root->d_inode, dir);
406 reiserfs_write_unlock_xattrs(inode->i_sb);
407 dput(root);
408 } else {
409 reiserfs_warning(inode->i_sb, "jdm-20006",
410 "Couldn't remove all entries in directory");
411 }
412 unlock_kernel();
413
414out_dir:
415 dput(dir);
416
417out:
418 if (!err)
419 REISERFS_I(inode)->i_flags =
420 REISERFS_I(inode)->i_flags & ~i_has_xattr_dir;
421 return err;
422}
423
424struct reiserfs_chown_buf {
425 struct inode *inode;
426 struct dentry *xadir;
427 struct iattr *attrs;
428};
429
430/* XXX: If there is a better way to do this, I'd love to hear about it */
431static int
432reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
433 loff_t offset, u64 ino, unsigned int d_type)
434{
435 struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
436 struct dentry *xafile, *xadir = chown_buf->xadir;
437 struct iattr *attrs = chown_buf->attrs;
438 int err = 0;
439
440 xafile = lookup_one_len(name, xadir, namelen);
441 if (IS_ERR(xafile))
442 return PTR_ERR(xafile);
443 else if (!xafile->d_inode) {
444 dput(xafile);
445 return -ENODATA;
446 }
447
448 if (!S_ISDIR(xafile->d_inode->i_mode))
449 err = notify_change(xafile, attrs);
450 dput(xafile);
451
452 return err;
453}
454
455int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
456{
457 struct dentry *dir;
458 int err = 0;
459 struct reiserfs_chown_buf buf;
460 unsigned int ia_valid = attrs->ia_valid;
461
462 /* Skip out, an xattr has no xattrs associated with it */
463 if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1)
464 return 0;
465
466 reiserfs_read_lock_xattrs(inode->i_sb);
467 dir = open_xa_dir(inode, FL_READONLY);
468 reiserfs_read_unlock_xattrs(inode->i_sb);
469 if (IS_ERR(dir)) {
470 if (PTR_ERR(dir) != -ENODATA)
471 err = PTR_ERR(dir);
472 goto out;
473 } else if (!dir->d_inode) {
474 dput(dir);
475 goto out;
476 }
477
478 lock_kernel();
479
480 attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
481 buf.xadir = dir;
482 buf.attrs = attrs;
483 buf.inode = inode;
484
485 err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf);
486 if (err) {
487 unlock_kernel();
488 goto out_dir;
489 }
490
491 err = notify_change(dir, attrs);
492 unlock_kernel();
493
494out_dir:
495 dput(dir);
496
497out:
498 attrs->ia_valid = ia_valid;
499 return err;
500}
501
502#ifdef CONFIG_REISERFS_FS_XATTR
503static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
504 *prefix);
505
506/* Returns a dentry corresponding to a specific extended attribute file
507 * for the inode. If flags allow, the file is created. Otherwise, a
508 * valid or negative dentry, or an error is returned. */
509static struct dentry *get_xa_file_dentry(const struct inode *inode,
510 const char *name, int flags)
511{
512 struct dentry *xadir, *xafile;
513 int err = 0;
514
515 xadir = open_xa_dir(inode, flags);
516 if (IS_ERR(xadir)) {
517 return ERR_CAST(xadir);
518 } else if (xadir && !xadir->d_inode) {
519 dput(xadir);
520 return ERR_PTR(-ENODATA);
521 }
522
523 xafile = lookup_one_len(name, xadir, strlen(name));
524 if (IS_ERR(xafile)) {
525 dput(xadir);
526 return ERR_CAST(xafile);
527 }
528
529 if (xafile->d_inode) { /* file exists */
530 if (flags & XATTR_CREATE) {
531 err = -EEXIST;
532 dput(xafile);
533 goto out;
534 }
535 } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
536 goto out;
537 } else {
538 /* inode->i_mutex is down, so nothing else can try to create
539 * the same xattr */
540 err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,
541 0700 | S_IFREG, NULL);
542
543 if (err) {
544 dput(xafile);
545 goto out;
546 }
547 }
548
549out:
550 dput(xadir);
551 if (err)
552 xafile = ERR_PTR(err);
553 else if (!xafile->d_inode) {
554 dput(xafile);
555 xafile = ERR_PTR(-ENODATA);
556 }
557 return xafile;
558}
559
372/* Internal operations on file data */ 560/* Internal operations on file data */
373static inline void reiserfs_put_page(struct page *page) 561static inline void reiserfs_put_page(struct page *page)
374{ 562{
@@ -606,54 +794,10 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
606 err = -EIO; 794 err = -EIO;
607 } 795 }
608 796
609 out_dput: 797out_dput:
610 dput(dentry); 798 dput(dentry);
611 799
612 out: 800out:
613 return err;
614}
615
616static int
617__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
618{
619 struct dentry *dentry;
620 struct inode *dir = xadir->d_inode;
621 int err = 0;
622
623 dentry = lookup_one_len(name, xadir, namelen);
624 if (IS_ERR(dentry)) {
625 err = PTR_ERR(dentry);
626 goto out;
627 } else if (!dentry->d_inode) {
628 err = -ENODATA;
629 goto out_file;
630 }
631
632 /* Skip directories.. */
633 if (S_ISDIR(dentry->d_inode->i_mode))
634 goto out_file;
635
636 if (!IS_PRIVATE(dentry->d_inode)) {
637 reiserfs_error(dir->i_sb, "jdm-20003",
638 "OID %08x [%.*s/%.*s] doesn't have "
639 "priv flag set [parent is %sset].",
640 le32_to_cpu(INODE_PKEY(dentry->d_inode)->
641 k_objectid), xadir->d_name.len,
642 xadir->d_name.name, namelen, name,
643 IS_PRIVATE(xadir->d_inode) ? "" :
644 "not ");
645 dput(dentry);
646 return -EIO;
647 }
648
649 err = dir->i_op->unlink(dir, dentry);
650 if (!err)
651 d_delete(dentry);
652
653 out_file:
654 dput(dentry);
655
656 out:
657 return err; 801 return err;
658} 802}
659 803
@@ -680,151 +824,6 @@ int reiserfs_xattr_del(struct inode *inode, const char *name)
680 return err; 824 return err;
681} 825}
682 826
683/* The following are side effects of other operations that aren't explicitly
684 * modifying extended attributes. This includes operations such as permissions
685 * or ownership changes, object deletions, etc. */
686
687static int
688reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
689 loff_t offset, u64 ino, unsigned int d_type)
690{
691 struct dentry *xadir = (struct dentry *)buf;
692
693 return __reiserfs_xattr_del(xadir, name, namelen);
694
695}
696
697/* This is called w/ inode->i_mutex downed */
698int reiserfs_delete_xattrs(struct inode *inode)
699{
700 struct dentry *dir, *root;
701 int err = 0;
702
703 /* Skip out, an xattr has no xattrs associated with it */
704 if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 ||
705 !reiserfs_xattrs(inode->i_sb)) {
706 return 0;
707 }
708 reiserfs_read_lock_xattrs(inode->i_sb);
709 dir = open_xa_dir(inode, FL_READONLY);
710 reiserfs_read_unlock_xattrs(inode->i_sb);
711 if (IS_ERR(dir)) {
712 err = PTR_ERR(dir);
713 goto out;
714 } else if (!dir->d_inode) {
715 dput(dir);
716 return 0;
717 }
718
719 lock_kernel();
720 err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir);
721 if (err) {
722 unlock_kernel();
723 goto out_dir;
724 }
725
726 /* Leftovers besides . and .. -- that's not good. */
727 if (dir->d_inode->i_nlink <= 2) {
728 root = get_xa_root(inode->i_sb, XATTR_REPLACE);
729 reiserfs_write_lock_xattrs(inode->i_sb);
730 err = vfs_rmdir(root->d_inode, dir);
731 reiserfs_write_unlock_xattrs(inode->i_sb);
732 dput(root);
733 } else {
734 reiserfs_warning(inode->i_sb, "jdm-20006",
735 "Couldn't remove all entries in directory");
736 }
737 unlock_kernel();
738
739 out_dir:
740 dput(dir);
741
742 out:
743 if (!err)
744 REISERFS_I(inode)->i_flags =
745 REISERFS_I(inode)->i_flags & ~i_has_xattr_dir;
746 return err;
747}
748
749struct reiserfs_chown_buf {
750 struct inode *inode;
751 struct dentry *xadir;
752 struct iattr *attrs;
753};
754
755/* XXX: If there is a better way to do this, I'd love to hear about it */
756static int
757reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
758 loff_t offset, u64 ino, unsigned int d_type)
759{
760 struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
761 struct dentry *xafile, *xadir = chown_buf->xadir;
762 struct iattr *attrs = chown_buf->attrs;
763 int err = 0;
764
765 xafile = lookup_one_len(name, xadir, namelen);
766 if (IS_ERR(xafile))
767 return PTR_ERR(xafile);
768 else if (!xafile->d_inode) {
769 dput(xafile);
770 return -ENODATA;
771 }
772
773 if (!S_ISDIR(xafile->d_inode->i_mode))
774 err = notify_change(xafile, attrs);
775 dput(xafile);
776
777 return err;
778}
779
780int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
781{
782 struct dentry *dir;
783 int err = 0;
784 struct reiserfs_chown_buf buf;
785 unsigned int ia_valid = attrs->ia_valid;
786
787 /* Skip out, an xattr has no xattrs associated with it */
788 if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 ||
789 !reiserfs_xattrs(inode->i_sb)) {
790 return 0;
791 }
792 reiserfs_read_lock_xattrs(inode->i_sb);
793 dir = open_xa_dir(inode, FL_READONLY);
794 reiserfs_read_unlock_xattrs(inode->i_sb);
795 if (IS_ERR(dir)) {
796 if (PTR_ERR(dir) != -ENODATA)
797 err = PTR_ERR(dir);
798 goto out;
799 } else if (!dir->d_inode) {
800 dput(dir);
801 goto out;
802 }
803
804 lock_kernel();
805
806 attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
807 buf.xadir = dir;
808 buf.attrs = attrs;
809 buf.inode = inode;
810
811 err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf);
812 if (err) {
813 unlock_kernel();
814 goto out_dir;
815 }
816
817 err = notify_change(dir, attrs);
818 unlock_kernel();
819
820 out_dir:
821 dput(dir);
822
823 out:
824 attrs->ia_valid = ia_valid;
825 return err;
826}
827
828/* Actual operations that are exported to VFS-land */ 827/* Actual operations that are exported to VFS-land */
829 828
830/* 829/*
@@ -1101,6 +1100,94 @@ void reiserfs_xattr_unregister_handlers(void)
1101 write_unlock(&handler_lock); 1100 write_unlock(&handler_lock);
1102} 1101}
1103 1102
1103static int reiserfs_check_acl(struct inode *inode, int mask)
1104{
1105 struct posix_acl *acl;
1106 int error = -EAGAIN; /* do regular unix permission checks by default */
1107
1108 reiserfs_read_lock_xattr_i(inode);
1109 reiserfs_read_lock_xattrs(inode->i_sb);
1110
1111 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
1112
1113 reiserfs_read_unlock_xattrs(inode->i_sb);
1114 reiserfs_read_unlock_xattr_i(inode);
1115
1116 if (acl) {
1117 if (!IS_ERR(acl)) {
1118 error = posix_acl_permission(inode, acl, mask);
1119 posix_acl_release(acl);
1120 } else if (PTR_ERR(acl) != -ENODATA)
1121 error = PTR_ERR(acl);
1122 }
1123
1124 return error;
1125}
1126
1127int reiserfs_permission(struct inode *inode, int mask)
1128{
1129 /*
1130 * We don't do permission checks on the internal objects.
1131 * Permissions are determined by the "owning" object.
1132 */
1133 if (IS_PRIVATE(inode))
1134 return 0;
1135 /*
1136 * Stat data v1 doesn't support ACLs.
1137 */
1138 if (get_inode_sd_version(inode) == STAT_DATA_V1)
1139 return generic_permission(inode, mask, NULL);
1140 else
1141 return generic_permission(inode, mask, reiserfs_check_acl);
1142}
1143
1144static int create_privroot(struct dentry *dentry)
1145{
1146 int err;
1147 struct inode *inode = dentry->d_parent->d_inode;
1148 mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR);
1149 err = inode->i_op->mkdir(inode, dentry, 0700);
1150 mutex_unlock(&inode->i_mutex);
1151 if (err) {
1152 dput(dentry);
1153 dentry = NULL;
1154 }
1155
1156 if (dentry && dentry->d_inode)
1157 reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
1158 "storage.\n", PRIVROOT_NAME);
1159
1160 return err;
1161}
1162
1163static int xattr_mount_check(struct super_block *s)
1164{
1165 /* We need generation numbers to ensure that the oid mapping is correct
1166 * v3.5 filesystems don't have them. */
1167 if (!old_format_only(s)) {
1168 set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
1169 } else if (reiserfs_xattrs_optional(s)) {
1170 /* Old format filesystem, but optional xattrs have been enabled
1171 * at mount time. Error out. */
1172 reiserfs_warning(s, "jdm-20005",
1173 "xattrs/ACLs not supported on pre v3.6 "
1174 "format filesystem. Failing mount.");
1175 return -EOPNOTSUPP;
1176 } else {
1177 /* Old format filesystem, but no optional xattrs have
1178 * been enabled. This means we silently disable xattrs
1179 * on the filesystem. */
1180 clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
1181 }
1182
1183 return 0;
1184}
1185
1186#else
1187int __init reiserfs_xattr_register_handlers(void) { return 0; }
1188void reiserfs_xattr_unregister_handlers(void) {}
1189#endif
1190
1104/* This will catch lookups from the fs root to .reiserfs_priv */ 1191/* This will catch lookups from the fs root to .reiserfs_priv */
1105static int 1192static int
1106xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) 1193xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
@@ -1127,47 +1214,23 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
1127{ 1214{
1128 int err = 0; 1215 int err = 0;
1129 1216
1130 /* We need generation numbers to ensure that the oid mapping is correct 1217#ifdef CONFIG_REISERFS_FS_XATTR
1131 * v3.5 filesystems don't have them. */ 1218 err = xattr_mount_check(s);
1132 if (!old_format_only(s)) { 1219 if (err)
1133 set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
1134 } else if (reiserfs_xattrs_optional(s)) {
1135 /* Old format filesystem, but optional xattrs have been enabled
1136 * at mount time. Error out. */
1137 reiserfs_warning(s, "jdm-20005",
1138 "xattrs/ACLs not supported on pre v3.6 "
1139 "format filesystem. Failing mount.");
1140 err = -EOPNOTSUPP;
1141 goto error; 1220 goto error;
1142 } else { 1221#endif
1143 /* Old format filesystem, but no optional xattrs have been enabled. This
1144 * means we silently disable xattrs on the filesystem. */
1145 clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
1146 }
1147 1222
1148 /* If we don't have the privroot located yet - go find it */ 1223 /* If we don't have the privroot located yet - go find it */
1149 if (reiserfs_xattrs(s) && !REISERFS_SB(s)->priv_root) { 1224 if (!REISERFS_SB(s)->priv_root) {
1150 struct dentry *dentry; 1225 struct dentry *dentry;
1151 dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, 1226 dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
1152 strlen(PRIVROOT_NAME)); 1227 strlen(PRIVROOT_NAME));
1153 if (!IS_ERR(dentry)) { 1228 if (!IS_ERR(dentry)) {
1154 if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { 1229#ifdef CONFIG_REISERFS_FS_XATTR
1155 struct inode *inode = dentry->d_parent->d_inode; 1230 if (!(mount_flags & MS_RDONLY) && !dentry->d_inode)
1156 mutex_lock_nested(&inode->i_mutex, 1231 err = create_privroot(dentry);
1157 I_MUTEX_XATTR); 1232#endif
1158 err = inode->i_op->mkdir(inode, dentry, 0700); 1233 if (!dentry->d_inode) {
1159 mutex_unlock(&inode->i_mutex);
1160 if (err) {
1161 dput(dentry);
1162 dentry = NULL;
1163 }
1164
1165 if (dentry && dentry->d_inode)
1166 reiserfs_info(s, "Created %s - "
1167 "reserved for xattr "
1168 "storage.\n",
1169 PRIVROOT_NAME);
1170 } else if (!dentry->d_inode) {
1171 dput(dentry); 1234 dput(dentry);
1172 dentry = NULL; 1235 dentry = NULL;
1173 } 1236 }
@@ -1178,73 +1241,37 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
1178 s->s_root->d_op = &xattr_lookup_poison_ops; 1241 s->s_root->d_op = &xattr_lookup_poison_ops;
1179 dentry->d_inode->i_flags |= S_PRIVATE; 1242 dentry->d_inode->i_flags |= S_PRIVATE;
1180 REISERFS_SB(s)->priv_root = dentry; 1243 REISERFS_SB(s)->priv_root = dentry;
1181 } else if (!(mount_flags & MS_RDONLY)) { /* xattrs are unavailable */ 1244#ifdef CONFIG_REISERFS_FS_XATTR
1182 /* If we're read-only it just means that the dir hasn't been 1245 /* xattrs are unavailable */
1183 * created. Not an error -- just no xattrs on the fs. We'll 1246 } else if (!(mount_flags & MS_RDONLY)) {
1184 * check again if we go read-write */ 1247 /* If we're read-only it just means that the dir
1248 * hasn't been created. Not an error -- just no
1249 * xattrs on the fs. We'll check again if we
1250 * go read-write */
1185 reiserfs_warning(s, "jdm-20006", 1251 reiserfs_warning(s, "jdm-20006",
1186 "xattrs/ACLs enabled and couldn't " 1252 "xattrs/ACLs enabled and couldn't "
1187 "find/create .reiserfs_priv. " 1253 "find/create .reiserfs_priv. "
1188 "Failing mount."); 1254 "Failing mount.");
1189 err = -EOPNOTSUPP; 1255 err = -EOPNOTSUPP;
1256#endif
1190 } 1257 }
1191 } 1258 }
1192 1259
1193 error: 1260#ifdef CONFIG_REISERFS_FS_XATTR
1194 /* This is only nonzero if there was an error initializing the xattr 1261error:
1195 * directory or if there is a condition where we don't support them. */
1196 if (err) { 1262 if (err) {
1197 clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); 1263 clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
1198 clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); 1264 clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
1199 clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); 1265 clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
1200 } 1266 }
1267#endif
1201 1268
1202 /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */ 1269 /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
1203 s->s_flags = s->s_flags & ~MS_POSIXACL; 1270 s->s_flags = s->s_flags & ~MS_POSIXACL;
1271#ifdef CONFIG_REISERFS_FS_POSIX_ACL
1204 if (reiserfs_posixacl(s)) 1272 if (reiserfs_posixacl(s))
1205 s->s_flags |= MS_POSIXACL; 1273 s->s_flags |= MS_POSIXACL;
1274#endif
1206 1275
1207 return err; 1276 return err;
1208} 1277}
1209
1210static int reiserfs_check_acl(struct inode *inode, int mask)
1211{
1212 struct posix_acl *acl;
1213 int error = -EAGAIN; /* do regular unix permission checks by default */
1214
1215 reiserfs_read_lock_xattr_i(inode);
1216 reiserfs_read_lock_xattrs(inode->i_sb);
1217
1218 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
1219
1220 reiserfs_read_unlock_xattrs(inode->i_sb);
1221 reiserfs_read_unlock_xattr_i(inode);
1222
1223 if (acl) {
1224 if (!IS_ERR(acl)) {
1225 error = posix_acl_permission(inode, acl, mask);
1226 posix_acl_release(acl);
1227 } else if (PTR_ERR(acl) != -ENODATA)
1228 error = PTR_ERR(acl);
1229 }
1230
1231 return error;
1232}
1233
1234int reiserfs_permission(struct inode *inode, int mask)
1235{
1236 /*
1237 * We don't do permission checks on the internal objects.
1238 * Permissions are determined by the "owning" object.
1239 */
1240 if (IS_PRIVATE(inode))
1241 return 0;
1242
1243 /*
1244 * Stat data v1 doesn't support ACLs.
1245 */
1246 if (get_inode_sd_version(inode) == STAT_DATA_V1)
1247 return generic_permission(inode, mask, NULL);
1248 else
1249 return generic_permission(inode, mask, reiserfs_check_acl);
1250}
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 12fc2a0d13be..cbb8868e844e 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -402,8 +402,8 @@ struct reiserfs_sb_info {
402 int reserved_blocks; /* amount of blocks reserved for further allocations */ 402 int reserved_blocks; /* amount of blocks reserved for further allocations */
403 spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */ 403 spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
404 struct dentry *priv_root; /* root of /.reiserfs_priv */ 404 struct dentry *priv_root; /* root of /.reiserfs_priv */
405#ifdef CONFIG_REISERFS_FS_XATTR
406 struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */ 405 struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
406#ifdef CONFIG_REISERFS_FS_XATTR
407 struct rw_semaphore xattr_dir_sem; 407 struct rw_semaphore xattr_dir_sem;
408#endif 408#endif
409 int j_errno; 409 int j_errno;
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index 58f32ba7f5a0..13cdd5e1cb60 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -43,6 +43,12 @@ struct reiserfs_xattr_handler {
43 struct list_head handlers; 43 struct list_head handlers;
44}; 44};
45 45
46int reiserfs_xattr_register_handlers(void) __init;
47void reiserfs_xattr_unregister_handlers(void);
48int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
49int reiserfs_delete_xattrs(struct inode *inode);
50int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
51
46#ifdef CONFIG_REISERFS_FS_XATTR 52#ifdef CONFIG_REISERFS_FS_XATTR
47#define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir) 53#define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)
48ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name, 54ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name,
@@ -51,9 +57,6 @@ int reiserfs_setxattr(struct dentry *dentry, const char *name,
51 const void *value, size_t size, int flags); 57 const void *value, size_t size, int flags);
52ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size); 58ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
53int reiserfs_removexattr(struct dentry *dentry, const char *name); 59int reiserfs_removexattr(struct dentry *dentry, const char *name);
54int reiserfs_delete_xattrs(struct inode *inode);
55int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
56int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
57int reiserfs_permission(struct inode *inode, int mask); 60int reiserfs_permission(struct inode *inode, int mask);
58 61
59int reiserfs_xattr_del(struct inode *, const char *); 62int reiserfs_xattr_del(struct inode *, const char *);
@@ -64,9 +67,6 @@ extern struct reiserfs_xattr_handler user_handler;
64extern struct reiserfs_xattr_handler trusted_handler; 67extern struct reiserfs_xattr_handler trusted_handler;
65extern struct reiserfs_xattr_handler security_handler; 68extern struct reiserfs_xattr_handler security_handler;
66 69
67int reiserfs_xattr_register_handlers(void) __init;
68void reiserfs_xattr_unregister_handlers(void);
69
70static inline void reiserfs_write_lock_xattrs(struct super_block *sb) 70static inline void reiserfs_write_lock_xattrs(struct super_block *sb)
71{ 71{
72 down_write(&REISERFS_XATTR_DIR_SEM(sb)); 72 down_write(&REISERFS_XATTR_DIR_SEM(sb));
@@ -121,23 +121,6 @@ static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
121 121
122#define reiserfs_permission NULL 122#define reiserfs_permission NULL
123 123
124#define reiserfs_xattr_register_handlers() 0
125#define reiserfs_xattr_unregister_handlers()
126
127static inline int reiserfs_delete_xattrs(struct inode *inode)
128{
129 return 0;
130};
131static inline int reiserfs_chown_xattrs(struct inode *inode,
132 struct iattr *attrs)
133{
134 return 0;
135};
136static inline int reiserfs_xattr_init(struct super_block *sb, int mount_flags)
137{
138 sb->s_flags = (sb->s_flags & ~MS_POSIXACL); /* to be sure */
139 return 0;
140};
141static inline void reiserfs_init_xattr_rwsem(struct inode *inode) 124static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
142{ 125{
143} 126}