aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2009-03-30 14:02:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 15:16:38 -0400
commit48b32a3553a54740d236b79a90f20147a25875e3 (patch)
treefaf6807facb5825608469a9e33c9127f90b974df /fs/reiserfs
parent8ecbe550a142fe604874afa477ea68986f89b86c (diff)
reiserfs: use generic xattr handlers
Christoph Hellwig had asked me quite some time ago to port the reiserfs xattrs to the generic xattr interface. This patch replaces the reiserfs-specific xattr handling code with the generic struct xattr_handler. However, since reiserfs doesn't split the prefix and name when accessing xattrs, it can't leverage generic_{set,get,list,remove}xattr without needlessly reconstructing the name on the back end. Update 7/26/07: Added missing dput() to deletion path. Update 8/30/07: Added missing mark_inode_dirty when i_mode is used to represent an ACL and no previous ACL existed. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/reiserfs')
-rw-r--r--fs/reiserfs/super.c7
-rw-r--r--fs/reiserfs/xattr.c467
-rw-r--r--fs/reiserfs/xattr_acl.c79
-rw-r--r--fs/reiserfs/xattr_security.c26
-rw-r--r--fs/reiserfs/xattr_trusted.c45
-rw-r--r--fs/reiserfs/xattr_user.c31
6 files changed, 249 insertions, 406 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 6d10f81b4fc1..4a1e16362ebd 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2263,9 +2263,6 @@ static int __init init_reiserfs_fs(void)
2263 return ret; 2263 return ret;
2264 } 2264 }
2265 2265
2266 if ((ret = reiserfs_xattr_register_handlers()))
2267 goto failed_reiserfs_xattr_register_handlers;
2268
2269 reiserfs_proc_info_global_init(); 2266 reiserfs_proc_info_global_init();
2270 reiserfs_proc_register_global("version", 2267 reiserfs_proc_register_global("version",
2271 reiserfs_global_version_in_proc); 2268 reiserfs_global_version_in_proc);
@@ -2276,9 +2273,6 @@ static int __init init_reiserfs_fs(void)
2276 return 0; 2273 return 0;
2277 } 2274 }
2278 2275
2279 reiserfs_xattr_unregister_handlers();
2280
2281 failed_reiserfs_xattr_register_handlers:
2282 reiserfs_proc_unregister_global("version"); 2276 reiserfs_proc_unregister_global("version");
2283 reiserfs_proc_info_global_done(); 2277 reiserfs_proc_info_global_done();
2284 destroy_inodecache(); 2278 destroy_inodecache();
@@ -2288,7 +2282,6 @@ static int __init init_reiserfs_fs(void)
2288 2282
2289static void __exit exit_reiserfs_fs(void) 2283static void __exit exit_reiserfs_fs(void)
2290{ 2284{
2291 reiserfs_xattr_unregister_handlers();
2292 reiserfs_proc_unregister_global("version"); 2285 reiserfs_proc_unregister_global("version");
2293 reiserfs_proc_info_global_done(); 2286 reiserfs_proc_info_global_done();
2294 unregister_filesystem(&reiserfs_fs_type); 2287 unregister_filesystem(&reiserfs_fs_type);
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 8d7e5d9ae17c..d3ce27436605 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -53,7 +53,6 @@
53#define PRIVROOT_NAME ".reiserfs_priv" 53#define PRIVROOT_NAME ".reiserfs_priv"
54#define XAROOT_NAME "xattrs" 54#define XAROOT_NAME "xattrs"
55 55
56static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *);
57 56
58/* Helpers for inode ops. We do this so that we don't have all the VFS 57/* Helpers for inode ops. We do this so that we don't have all the VFS
59 * overhead and also for proper i_mutex annotation. 58 * overhead and also for proper i_mutex annotation.
@@ -110,7 +109,6 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)
110 return error; 109 return error;
111} 110}
112 111
113
114#define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) 112#define xattr_may_create(flags) (!flags || flags & XATTR_CREATE)
115 113
116/* Returns and possibly creates the xattr dir. */ 114/* Returns and possibly creates the xattr dir. */
@@ -339,14 +337,17 @@ int xattr_readdir(struct inode *inode, filldir_t filler, void *buf)
339 return res; 337 return res;
340} 338}
341 339
342/* expects xadir->d_inode->i_mutex to be locked */ 340/* The following are side effects of other operations that aren't explicitly
341 * modifying extended attributes. This includes operations such as permissions
342 * or ownership changes, object deletions, etc. */
343
343static int 344static int
344__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) 345reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
346 loff_t offset, u64 ino, unsigned int d_type)
345{ 347{
348 struct dentry *xadir = (struct dentry *)buf;
346 struct dentry *dentry; 349 struct dentry *dentry;
347 struct inode *dir = xadir->d_inode;
348 int err = 0; 350 int err = 0;
349 struct reiserfs_xattr_handler *xah;
350 351
351 dentry = lookup_one_len(name, xadir, namelen); 352 dentry = lookup_one_len(name, xadir, namelen);
352 if (IS_ERR(dentry)) { 353 if (IS_ERR(dentry)) {
@@ -361,28 +362,7 @@ __reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
361 if (S_ISDIR(dentry->d_inode->i_mode)) 362 if (S_ISDIR(dentry->d_inode->i_mode))
362 goto out_file; 363 goto out_file;
363 364
364 if (!IS_PRIVATE(dentry->d_inode)) { 365 err = xattr_unlink(xadir->d_inode, dentry);
365 reiserfs_error(dir->i_sb, "jdm-20003",
366 "OID %08x [%.*s/%.*s] doesn't have "
367 "priv flag set [parent is %sset].",
368 le32_to_cpu(INODE_PKEY(dentry->d_inode)->
369 k_objectid), xadir->d_name.len,
370 xadir->d_name.name, namelen, name,
371 IS_PRIVATE(xadir->d_inode) ? "" :
372 "not ");
373 dput(dentry);
374 return -EIO;
375 }
376
377 /* Deletion pre-operation */
378 xah = find_xattr_handler_prefix(name);
379 if (xah && xah->del) {
380 err = xah->del(dentry->d_inode, name);
381 if (err)
382 goto out;
383 }
384
385 err = xattr_unlink(dir, dentry);
386 366
387out_file: 367out_file:
388 dput(dentry); 368 dput(dentry);
@@ -391,20 +371,6 @@ out:
391 return err; 371 return err;
392} 372}
393 373
394/* The following are side effects of other operations that aren't explicitly
395 * modifying extended attributes. This includes operations such as permissions
396 * or ownership changes, object deletions, etc. */
397
398static int
399reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
400 loff_t offset, u64 ino, unsigned int d_type)
401{
402 struct dentry *xadir = (struct dentry *)buf;
403
404 return __reiserfs_xattr_del(xadir, name, namelen);
405
406}
407
408/* This is called w/ inode->i_mutex downed */ 374/* This is called w/ inode->i_mutex downed */
409int reiserfs_delete_xattrs(struct inode *inode) 375int reiserfs_delete_xattrs(struct inode *inode)
410{ 376{
@@ -541,14 +507,11 @@ out:
541} 507}
542 508
543#ifdef CONFIG_REISERFS_FS_XATTR 509#ifdef CONFIG_REISERFS_FS_XATTR
544static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
545 *prefix);
546
547/* Returns a dentry corresponding to a specific extended attribute file 510/* Returns a dentry corresponding to a specific extended attribute file
548 * for the inode. If flags allow, the file is created. Otherwise, a 511 * for the inode. If flags allow, the file is created. Otherwise, a
549 * valid or negative dentry, or an error is returned. */ 512 * valid or negative dentry, or an error is returned. */
550static struct dentry *get_xa_file_dentry(const struct inode *inode, 513static struct dentry *xattr_lookup(struct inode *inode, const char *name,
551 const char *name, int flags) 514 int flags)
552{ 515{
553 struct dentry *xadir, *xafile; 516 struct dentry *xadir, *xafile;
554 int err = 0; 517 int err = 0;
@@ -623,6 +586,45 @@ int reiserfs_commit_write(struct file *f, struct page *page,
623int reiserfs_prepare_write(struct file *f, struct page *page, 586int reiserfs_prepare_write(struct file *f, struct page *page,
624 unsigned from, unsigned to); 587 unsigned from, unsigned to);
625 588
589static void update_ctime(struct inode *inode)
590{
591 struct timespec now = current_fs_time(inode->i_sb);
592 if (hlist_unhashed(&inode->i_hash) || !inode->i_nlink ||
593 timespec_equal(&inode->i_ctime, &now))
594 return;
595
596 inode->i_ctime = CURRENT_TIME_SEC;
597 mark_inode_dirty(inode);
598}
599
600static int lookup_and_delete_xattr(struct inode *inode, const char *name)
601{
602 int err = 0;
603 struct dentry *dentry, *xadir;
604
605 xadir = open_xa_dir(inode, XATTR_REPLACE);
606 if (IS_ERR(xadir))
607 return PTR_ERR(xadir);
608
609 dentry = lookup_one_len(name, xadir, strlen(name));
610 if (IS_ERR(dentry)) {
611 err = PTR_ERR(dentry);
612 goto out_dput;
613 }
614
615 if (dentry->d_inode) {
616 mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR);
617 err = xattr_unlink(xadir->d_inode, dentry);
618 mutex_unlock(&xadir->d_inode->i_mutex);
619 update_ctime(inode);
620 }
621
622 dput(dentry);
623out_dput:
624 dput(xadir);
625 return err;
626}
627
626 628
627/* Generic extended attribute operations that can be used by xa plugins */ 629/* Generic extended attribute operations that can be used by xa plugins */
628 630
@@ -630,8 +632,8 @@ int reiserfs_prepare_write(struct file *f, struct page *page,
630 * inode->i_mutex: down 632 * inode->i_mutex: down
631 */ 633 */
632int 634int
633reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, 635__reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
634 size_t buffer_size, int flags) 636 size_t buffer_size, int flags)
635{ 637{
636 int err = 0; 638 int err = 0;
637 struct dentry *dentry; 639 struct dentry *dentry;
@@ -639,37 +641,22 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
639 char *data; 641 char *data;
640 size_t file_pos = 0; 642 size_t file_pos = 0;
641 size_t buffer_pos = 0; 643 size_t buffer_pos = 0;
642 struct iattr newattrs; 644 size_t new_size;
643 __u32 xahash = 0; 645 __u32 xahash = 0;
644 646
645 if (get_inode_sd_version(inode) == STAT_DATA_V1) 647 if (get_inode_sd_version(inode) == STAT_DATA_V1)
646 return -EOPNOTSUPP; 648 return -EOPNOTSUPP;
647 649
648 if (!buffer) 650 if (!buffer)
649 return reiserfs_xattr_del(inode, name); 651 return lookup_and_delete_xattr(inode, name);
650 652
651 dentry = get_xa_file_dentry(inode, name, flags); 653 dentry = xattr_lookup(inode, name, flags);
652 if (IS_ERR(dentry)) { 654 if (IS_ERR(dentry))
653 err = PTR_ERR(dentry); 655 return PTR_ERR(dentry);
654 goto out;
655 }
656 656
657 down_write(&REISERFS_I(inode)->i_xattr_sem); 657 down_write(&REISERFS_I(inode)->i_xattr_sem);
658 658
659 xahash = xattr_hash(buffer, buffer_size); 659 xahash = xattr_hash(buffer, buffer_size);
660
661 /* Resize it so we're ok to write there */
662 newattrs.ia_size = buffer_size;
663 newattrs.ia_ctime = current_fs_time(inode->i_sb);
664 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
665 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR);
666 down_write(&dentry->d_inode->i_alloc_sem);
667 err = reiserfs_setattr(dentry, &newattrs);
668 up_write(&dentry->d_inode->i_alloc_sem);
669 mutex_unlock(&dentry->d_inode->i_mutex);
670 if (err)
671 goto out_filp;
672
673 while (buffer_pos < buffer_size || buffer_pos == 0) { 660 while (buffer_pos < buffer_size || buffer_pos == 0) {
674 size_t chunk; 661 size_t chunk;
675 size_t skip = 0; 662 size_t skip = 0;
@@ -682,7 +669,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
682 page = reiserfs_get_page(dentry->d_inode, file_pos); 669 page = reiserfs_get_page(dentry->d_inode, file_pos);
683 if (IS_ERR(page)) { 670 if (IS_ERR(page)) {
684 err = PTR_ERR(page); 671 err = PTR_ERR(page);
685 goto out_filp; 672 goto out_unlock;
686 } 673 }
687 674
688 lock_page(page); 675 lock_page(page);
@@ -716,20 +703,33 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
716 break; 703 break;
717 } 704 }
718 705
719 /* We can't mark the inode dirty if it's not hashed. This is the case 706 new_size = buffer_size + sizeof(struct reiserfs_xattr_header);
720 * when we're inheriting the default ACL. If we dirty it, the inode 707 if (!err && new_size < i_size_read(dentry->d_inode)) {
721 * gets marked dirty, but won't (ever) make it onto the dirty list until 708 struct iattr newattrs = {
722 * it's synced explicitly to clear I_DIRTY. This is bad. */ 709 .ia_ctime = current_fs_time(inode->i_sb),
723 if (!hlist_unhashed(&inode->i_hash)) { 710 .ia_size = buffer_size,
724 inode->i_ctime = CURRENT_TIME_SEC; 711 .ia_valid = ATTR_SIZE | ATTR_CTIME,
725 mark_inode_dirty(inode); 712 };
726 } 713 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR);
727 714 down_write(&dentry->d_inode->i_alloc_sem);
728 out_filp: 715 err = reiserfs_setattr(dentry, &newattrs);
716 up_write(&dentry->d_inode->i_alloc_sem);
717 mutex_unlock(&dentry->d_inode->i_mutex);
718 } else
719 update_ctime(inode);
720out_unlock:
729 up_write(&REISERFS_I(inode)->i_xattr_sem); 721 up_write(&REISERFS_I(inode)->i_xattr_sem);
730 dput(dentry); 722 dput(dentry);
723 return err;
724}
731 725
732 out: 726int
727reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
728 size_t buffer_size, int flags)
729{
730 int err = __reiserfs_xattr_set(inode, name, buffer, buffer_size, flags);
731 if (err == -ENODATA)
732 err = 0;
733 return err; 733 return err;
734} 734}
735 735
@@ -737,7 +737,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
737 * inode->i_mutex: down 737 * inode->i_mutex: down
738 */ 738 */
739int 739int
740reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, 740reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer,
741 size_t buffer_size) 741 size_t buffer_size)
742{ 742{
743 ssize_t err = 0; 743 ssize_t err = 0;
@@ -756,7 +756,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
756 if (get_inode_sd_version(inode) == STAT_DATA_V1) 756 if (get_inode_sd_version(inode) == STAT_DATA_V1)
757 return -EOPNOTSUPP; 757 return -EOPNOTSUPP;
758 758
759 dentry = get_xa_file_dentry(inode, name, XATTR_REPLACE); 759 dentry = xattr_lookup(inode, name, XATTR_REPLACE);
760 if (IS_ERR(dentry)) { 760 if (IS_ERR(dentry)) {
761 err = PTR_ERR(dentry); 761 err = PTR_ERR(dentry);
762 goto out; 762 goto out;
@@ -837,32 +837,53 @@ out:
837 return err; 837 return err;
838} 838}
839 839
840int reiserfs_xattr_del(struct inode *inode, const char *name) 840/* Actual operations that are exported to VFS-land */
841{ 841struct xattr_handler *reiserfs_xattr_handlers[] = {
842 struct dentry *dir; 842 &reiserfs_xattr_user_handler,
843 int err; 843 &reiserfs_xattr_trusted_handler,
844#ifdef CONFIG_REISERFS_FS_SECURITY
845 &reiserfs_xattr_security_handler,
846#endif
847#ifdef CONFIG_REISERFS_FS_POSIX_ACL
848 &reiserfs_posix_acl_access_handler,
849 &reiserfs_posix_acl_default_handler,
850#endif
851 NULL
852};
844 853
845 dir = open_xa_dir(inode, XATTR_REPLACE); 854/*
846 if (IS_ERR(dir)) { 855 * In order to implement different sets of xattr operations for each xattr
847 err = PTR_ERR(dir); 856 * prefix with the generic xattr API, a filesystem should create a
848 goto out; 857 * null-terminated array of struct xattr_handler (one for each prefix) and
849 } 858 * hang a pointer to it off of the s_xattr field of the superblock.
859 *
860 * The generic_fooxattr() functions will use this list to dispatch xattr
861 * operations to the correct xattr_handler.
862 */
863#define for_each_xattr_handler(handlers, handler) \
864 for ((handler) = *(handlers)++; \
865 (handler) != NULL; \
866 (handler) = *(handlers)++)
850 867
851 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); 868/* This is the implementation for the xattr plugin infrastructure */
852 err = __reiserfs_xattr_del(dir, name, strlen(name)); 869static inline struct xattr_handler *
853 mutex_unlock(&dir->d_inode->i_mutex); 870find_xattr_handler_prefix(struct xattr_handler **handlers,
854 dput(dir); 871 const char *name)
872{
873 struct xattr_handler *xah;
855 874
856 if (!err) { 875 if (!handlers)
857 inode->i_ctime = CURRENT_TIME_SEC; 876 return NULL;
858 mark_inode_dirty(inode); 877
878 for_each_xattr_handler(handlers, xah) {
879 if (strncmp(xah->prefix, name, strlen(xah->prefix)) == 0)
880 break;
859 } 881 }
860 882
861 out: 883 return xah;
862 return err;
863} 884}
864 885
865/* Actual operations that are exported to VFS-land */ 886
866/* 887/*
867 * Inode operation getxattr() 888 * Inode operation getxattr()
868 */ 889 */
@@ -870,15 +891,15 @@ ssize_t
870reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, 891reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
871 size_t size) 892 size_t size)
872{ 893{
873 struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); 894 struct inode *inode = dentry->d_inode;
874 int err; 895 struct xattr_handler *handler;
875 896
876 if (!xah || !reiserfs_xattrs(dentry->d_sb) || 897 handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name);
877 get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) 898
899 if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1)
878 return -EOPNOTSUPP; 900 return -EOPNOTSUPP;
879 901
880 err = xah->get(dentry->d_inode, name, buffer, size); 902 return handler->get(inode, name, buffer, size);
881 return err;
882} 903}
883 904
884/* 905/*
@@ -890,15 +911,15 @@ int
890reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, 911reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
891 size_t size, int flags) 912 size_t size, int flags)
892{ 913{
893 struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); 914 struct inode *inode = dentry->d_inode;
894 int err; 915 struct xattr_handler *handler;
895 916
896 if (!xah || !reiserfs_xattrs(dentry->d_sb) || 917 handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name);
897 get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) 918
919 if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1)
898 return -EOPNOTSUPP; 920 return -EOPNOTSUPP;
899 921
900 err = xah->set(dentry->d_inode, name, value, size, flags); 922 return handler->set(inode, name, value, size, flags);
901 return err;
902} 923}
903 924
904/* 925/*
@@ -908,71 +929,65 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
908 */ 929 */
909int reiserfs_removexattr(struct dentry *dentry, const char *name) 930int reiserfs_removexattr(struct dentry *dentry, const char *name)
910{ 931{
911 int err; 932 struct inode *inode = dentry->d_inode;
912 struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); 933 struct xattr_handler *handler;
934 handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name);
913 935
914 if (!xah || !reiserfs_xattrs(dentry->d_sb) || 936 if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1)
915 get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
916 return -EOPNOTSUPP; 937 return -EOPNOTSUPP;
917 938
918 err = reiserfs_xattr_del(dentry->d_inode, name); 939 return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
919
920 dentry->d_inode->i_ctime = CURRENT_TIME_SEC;
921 mark_inode_dirty(dentry->d_inode);
922
923 return err;
924} 940}
925 941
926/* This is what filldir will use: 942struct listxattr_buf {
927 * r_pos will always contain the amount of space required for the entire 943 size_t size;
928 * list. If r_pos becomes larger than r_size, we need more space and we 944 size_t pos;
929 * return an error indicating this. If r_pos is less than r_size, then we've 945 char *buf;
930 * filled the buffer successfully and we return success */ 946 struct inode *inode;
931struct reiserfs_listxattr_buf {
932 int r_pos;
933 int r_size;
934 char *r_buf;
935 struct inode *r_inode;
936}; 947};
937 948
938static int 949static int listxattr_filler(void *buf, const char *name, int namelen,
939reiserfs_listxattr_filler(void *buf, const char *name, int namelen, 950 loff_t offset, u64 ino, unsigned int d_type)
940 loff_t offset, u64 ino, unsigned int d_type)
941{ 951{
942 struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; 952 struct listxattr_buf *b = (struct listxattr_buf *)buf;
943 int len = 0; 953 size_t size;
944 if (name[0] != '.' 954 if (name[0] != '.' ||
945 || (namelen != 1 && (name[1] != '.' || namelen != 2))) { 955 (namelen != 1 && (name[1] != '.' || namelen != 2))) {
946 struct reiserfs_xattr_handler *xah = 956 struct xattr_handler *handler;
947 find_xattr_handler_prefix(name); 957 handler = find_xattr_handler_prefix(b->inode->i_sb->s_xattr,
948 if (!xah) 958 name);
949 return 0; /* Unsupported xattr name, skip it */ 959 if (!handler) /* Unsupported xattr name */
950 960 return 0;
951 /* We call ->list() twice because the operation isn't required to just 961 if (b->buf) {
952 * return the name back - we want to make sure we have enough space */ 962 size = handler->list(b->inode, b->buf + b->pos,
953 len += xah->list(b->r_inode, name, namelen, NULL); 963 b->size, name, namelen);
954 964 if (size > b->size)
955 if (len) { 965 return -ERANGE;
956 if (b->r_pos + len + 1 <= b->r_size) { 966 } else {
957 char *p = b->r_buf + b->r_pos; 967 size = handler->list(b->inode, NULL, 0, name, namelen);
958 p += xah->list(b->r_inode, name, namelen, p);
959 *p++ = '\0';
960 }
961 b->r_pos += len + 1;
962 } 968 }
963 }
964 969
970 b->pos += size;
971 }
965 return 0; 972 return 0;
966} 973}
967 974
968/* 975/*
969 * Inode operation listxattr() 976 * Inode operation listxattr()
977 *
978 * We totally ignore the generic listxattr here because it would be stupid
979 * not to. Since the xattrs are organized in a directory, we can just
980 * readdir to find them.
970 */ 981 */
971ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) 982ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
972{ 983{
973 struct dentry *dir; 984 struct dentry *dir;
974 int err = 0; 985 int err = 0;
975 struct reiserfs_listxattr_buf buf; 986 struct listxattr_buf buf = {
987 .inode = dentry->d_inode,
988 .buf = buffer,
989 .size = buffer ? size : 0,
990 };
976 991
977 if (!dentry->d_inode) 992 if (!dentry->d_inode)
978 return -EINVAL; 993 return -EINVAL;
@@ -985,120 +1000,22 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
985 if (IS_ERR(dir)) { 1000 if (IS_ERR(dir)) {
986 err = PTR_ERR(dir); 1001 err = PTR_ERR(dir);
987 if (err == -ENODATA) 1002 if (err == -ENODATA)
988 err = 0; /* Not an error if there aren't any xattrs */ 1003 err = 0; /* Not an error if there aren't any xattrs */
989 goto out; 1004 goto out;
990 } 1005 }
991 1006
992 buf.r_buf = buffer;
993 buf.r_size = buffer ? size : 0;
994 buf.r_pos = 0;
995 buf.r_inode = dentry->d_inode;
996
997 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); 1007 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR);
998 err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); 1008 err = xattr_readdir(dir->d_inode, listxattr_filler, &buf);
999 mutex_unlock(&dir->d_inode->i_mutex); 1009 mutex_unlock(&dir->d_inode->i_mutex);
1000 1010
1001 if (!err) { 1011 if (!err)
1002 if (buf.r_pos > buf.r_size && buffer != NULL) 1012 err = buf.pos;
1003 err = -ERANGE;
1004 else
1005 err = buf.r_pos;
1006 }
1007 1013
1008 dput(dir); 1014 dput(dir);
1009out: 1015out:
1010 return err; 1016 return err;
1011} 1017}
1012 1018
1013/* This is the implementation for the xattr plugin infrastructure */
1014static LIST_HEAD(xattr_handlers);
1015static DEFINE_RWLOCK(handler_lock);
1016
1017static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
1018 *prefix)
1019{
1020 struct reiserfs_xattr_handler *xah = NULL;
1021 struct list_head *p;
1022
1023 read_lock(&handler_lock);
1024 list_for_each(p, &xattr_handlers) {
1025 xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
1026 if (strncmp(xah->prefix, prefix, strlen(xah->prefix)) == 0)
1027 break;
1028 xah = NULL;
1029 }
1030
1031 read_unlock(&handler_lock);
1032 return xah;
1033}
1034
1035static void __unregister_handlers(void)
1036{
1037 struct reiserfs_xattr_handler *xah;
1038 struct list_head *p, *tmp;
1039
1040 list_for_each_safe(p, tmp, &xattr_handlers) {
1041 xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
1042 if (xah->exit)
1043 xah->exit();
1044
1045 list_del_init(p);
1046 }
1047 INIT_LIST_HEAD(&xattr_handlers);
1048}
1049
1050int __init reiserfs_xattr_register_handlers(void)
1051{
1052 int err = 0;
1053 struct reiserfs_xattr_handler *xah;
1054 struct list_head *p;
1055
1056 write_lock(&handler_lock);
1057
1058 /* If we're already initialized, nothing to do */
1059 if (!list_empty(&xattr_handlers)) {
1060 write_unlock(&handler_lock);
1061 return 0;
1062 }
1063
1064 /* Add the handlers */
1065 list_add_tail(&user_handler.handlers, &xattr_handlers);
1066 list_add_tail(&trusted_handler.handlers, &xattr_handlers);
1067#ifdef CONFIG_REISERFS_FS_SECURITY
1068 list_add_tail(&security_handler.handlers, &xattr_handlers);
1069#endif
1070#ifdef CONFIG_REISERFS_FS_POSIX_ACL
1071 list_add_tail(&posix_acl_access_handler.handlers, &xattr_handlers);
1072 list_add_tail(&posix_acl_default_handler.handlers, &xattr_handlers);
1073#endif
1074
1075 /* Run initializers, if available */
1076 list_for_each(p, &xattr_handlers) {
1077 xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
1078 if (xah->init) {
1079 err = xah->init();
1080 if (err) {
1081 list_del_init(p);
1082 break;
1083 }
1084 }
1085 }
1086
1087 /* Clean up other handlers, if any failed */
1088 if (err)
1089 __unregister_handlers();
1090
1091 write_unlock(&handler_lock);
1092 return err;
1093}
1094
1095void reiserfs_xattr_unregister_handlers(void)
1096{
1097 write_lock(&handler_lock);
1098 __unregister_handlers();
1099 write_unlock(&handler_lock);
1100}
1101
1102static int reiserfs_check_acl(struct inode *inode, int mask) 1019static int reiserfs_check_acl(struct inode *inode, int mask)
1103{ 1020{
1104 struct posix_acl *acl; 1021 struct posix_acl *acl;
@@ -1157,20 +1074,16 @@ static int xattr_mount_check(struct super_block *s)
1157{ 1074{
1158 /* We need generation numbers to ensure that the oid mapping is correct 1075 /* We need generation numbers to ensure that the oid mapping is correct
1159 * v3.5 filesystems don't have them. */ 1076 * v3.5 filesystems don't have them. */
1160 if (!old_format_only(s)) { 1077 if (old_format_only(s)) {
1161 set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); 1078 if (reiserfs_xattrs_optional(s)) {
1162 } else if (reiserfs_xattrs_optional(s)) { 1079 /* Old format filesystem, but optional xattrs have
1163 /* Old format filesystem, but optional xattrs have been enabled 1080 * been enabled. Error out. */
1164 * at mount time. Error out. */ 1081 reiserfs_warning(s, "jdm-2005",
1165 reiserfs_warning(s, "jdm-20005", 1082 "xattrs/ACLs not supported "
1166 "xattrs/ACLs not supported on pre v3.6 " 1083 "on pre-v3.6 format filesystems. "
1167 "format filesystem. Failing mount."); 1084 "Failing mount.");
1168 return -EOPNOTSUPP; 1085 return -EOPNOTSUPP;
1169 } else { 1086 }
1170 /* Old format filesystem, but no optional xattrs have
1171 * been enabled. This means we silently disable xattrs
1172 * on the filesystem. */
1173 clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
1174 } 1087 }
1175 1088
1176 return 0; 1089 return 0;
@@ -1251,9 +1164,11 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
1251 } 1164 }
1252 1165
1253#ifdef CONFIG_REISERFS_FS_XATTR 1166#ifdef CONFIG_REISERFS_FS_XATTR
1167 if (!err)
1168 s->s_xattr = reiserfs_xattr_handlers;
1169
1254error: 1170error:
1255 if (err) { 1171 if (err) {
1256 clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
1257 clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); 1172 clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
1258 clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); 1173 clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
1259 } 1174 }
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index d3ce6ee9b262..bfecf7553002 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -271,7 +271,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
271 char *name; 271 char *name;
272 void *value = NULL; 272 void *value = NULL;
273 struct posix_acl **p_acl; 273 struct posix_acl **p_acl;
274 size_t size; 274 size_t size = 0;
275 int error; 275 int error;
276 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 276 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
277 277
@@ -308,16 +308,21 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
308 value = posix_acl_to_disk(acl, &size); 308 value = posix_acl_to_disk(acl, &size);
309 if (IS_ERR(value)) 309 if (IS_ERR(value))
310 return (int)PTR_ERR(value); 310 return (int)PTR_ERR(value);
311 error = reiserfs_xattr_set(inode, name, value, size, 0); 311 }
312 } else { 312
313 error = reiserfs_xattr_del(inode, name); 313 error = __reiserfs_xattr_set(inode, name, value, size, 0);
314 if (error == -ENODATA) { 314
315 /* This may seem odd here, but it means that the ACL was set 315 /*
316 * with a value representable with mode bits. If there was 316 * Ensure that the inode gets dirtied if we're only using
317 * an ACL before, reiserfs_xattr_del already dirtied the inode. 317 * the mode bits and an old ACL didn't exist. We don't need
318 */ 318 * to check if the inode is hashed here since we won't get
319 * called by reiserfs_inherit_default_acl().
320 */
321 if (error == -ENODATA) {
322 error = 0;
323 if (type == ACL_TYPE_ACCESS) {
324 inode->i_ctime = CURRENT_TIME_SEC;
319 mark_inode_dirty(inode); 325 mark_inode_dirty(inode);
320 error = 0;
321 } 326 }
322 } 327 }
323 328
@@ -474,33 +479,22 @@ posix_acl_access_set(struct inode *inode, const char *name,
474 return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); 479 return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
475} 480}
476 481
477static int posix_acl_access_del(struct inode *inode, const char *name) 482static size_t posix_acl_access_list(struct inode *inode, char *list,
478{ 483 size_t list_size, const char *name,
479 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 484 size_t name_len)
480 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1)
481 return -EINVAL;
482 iset_acl(inode, &reiserfs_i->i_acl_access, ERR_PTR(-ENODATA));
483 return 0;
484}
485
486static int
487posix_acl_access_list(struct inode *inode, const char *name, int namelen,
488 char *out)
489{ 485{
490 int len = namelen; 486 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
491 if (!reiserfs_posixacl(inode->i_sb)) 487 if (!reiserfs_posixacl(inode->i_sb))
492 return 0; 488 return 0;
493 if (out) 489 if (list && size <= list_size)
494 memcpy(out, name, len); 490 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
495 491 return size;
496 return len;
497} 492}
498 493
499struct reiserfs_xattr_handler posix_acl_access_handler = { 494struct xattr_handler reiserfs_posix_acl_access_handler = {
500 .prefix = POSIX_ACL_XATTR_ACCESS, 495 .prefix = POSIX_ACL_XATTR_ACCESS,
501 .get = posix_acl_access_get, 496 .get = posix_acl_access_get,
502 .set = posix_acl_access_set, 497 .set = posix_acl_access_set,
503 .del = posix_acl_access_del,
504 .list = posix_acl_access_list, 498 .list = posix_acl_access_list,
505}; 499};
506 500
@@ -522,32 +516,21 @@ posix_acl_default_set(struct inode *inode, const char *name,
522 return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); 516 return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
523} 517}
524 518
525static int posix_acl_default_del(struct inode *inode, const char *name) 519static size_t posix_acl_default_list(struct inode *inode, char *list,
520 size_t list_size, const char *name,
521 size_t name_len)
526{ 522{
527 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 523 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
528 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1)
529 return -EINVAL;
530 iset_acl(inode, &reiserfs_i->i_acl_default, ERR_PTR(-ENODATA));
531 return 0;
532}
533
534static int
535posix_acl_default_list(struct inode *inode, const char *name, int namelen,
536 char *out)
537{
538 int len = namelen;
539 if (!reiserfs_posixacl(inode->i_sb)) 524 if (!reiserfs_posixacl(inode->i_sb))
540 return 0; 525 return 0;
541 if (out) 526 if (list && size <= list_size)
542 memcpy(out, name, len); 527 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
543 528 return size;
544 return len;
545} 529}
546 530
547struct reiserfs_xattr_handler posix_acl_default_handler = { 531struct xattr_handler reiserfs_posix_acl_default_handler = {
548 .prefix = POSIX_ACL_XATTR_DEFAULT, 532 .prefix = POSIX_ACL_XATTR_DEFAULT,
549 .get = posix_acl_default_get, 533 .get = posix_acl_default_get,
550 .set = posix_acl_default_set, 534 .set = posix_acl_default_set,
551 .del = posix_acl_default_del,
552 .list = posix_acl_default_list, 535 .list = posix_acl_default_list,
553}; 536};
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index 1958b361c35d..2aacf1fe69fd 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -31,35 +31,25 @@ security_set(struct inode *inode, const char *name, const void *buffer,
31 return reiserfs_xattr_set(inode, name, buffer, size, flags); 31 return reiserfs_xattr_set(inode, name, buffer, size, flags);
32} 32}
33 33
34static int security_del(struct inode *inode, const char *name) 34static size_t security_list(struct inode *inode, char *list, size_t list_len,
35 const char *name, size_t namelen)
35{ 36{
36 if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) 37 const size_t len = namelen + 1;
37 return -EINVAL;
38
39 if (IS_PRIVATE(inode))
40 return -EPERM;
41
42 return 0;
43}
44
45static int
46security_list(struct inode *inode, const char *name, int namelen, char *out)
47{
48 int len = namelen;
49 38
50 if (IS_PRIVATE(inode)) 39 if (IS_PRIVATE(inode))
51 return 0; 40 return 0;
52 41
53 if (out) 42 if (list && len <= list_len) {
54 memcpy(out, name, len); 43 memcpy(list, name, namelen);
44 list[namelen] = '\0';
45 }
55 46
56 return len; 47 return len;
57} 48}
58 49
59struct reiserfs_xattr_handler security_handler = { 50struct xattr_handler reiserfs_xattr_security_handler = {
60 .prefix = XATTR_SECURITY_PREFIX, 51 .prefix = XATTR_SECURITY_PREFIX,
61 .get = security_get, 52 .get = security_get,
62 .set = security_set, 53 .set = security_set,
63 .del = security_del,
64 .list = security_list, 54 .list = security_list,
65}; 55};
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
index 076ad388d489..a865042f75e2 100644
--- a/fs/reiserfs/xattr_trusted.c
+++ b/fs/reiserfs/xattr_trusted.c
@@ -13,10 +13,7 @@ trusted_get(struct inode *inode, const char *name, void *buffer, size_t size)
13 if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) 13 if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
14 return -EINVAL; 14 return -EINVAL;
15 15
16 if (!reiserfs_xattrs(inode->i_sb)) 16 if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
17 return -EOPNOTSUPP;
18
19 if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)))
20 return -EPERM; 17 return -EPERM;
21 18
22 return reiserfs_xattr_get(inode, name, buffer, size); 19 return reiserfs_xattr_get(inode, name, buffer, size);
@@ -29,50 +26,30 @@ trusted_set(struct inode *inode, const char *name, const void *buffer,
29 if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) 26 if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
30 return -EINVAL; 27 return -EINVAL;
31 28
32 if (!reiserfs_xattrs(inode->i_sb)) 29 if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
33 return -EOPNOTSUPP;
34
35 if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)))
36 return -EPERM; 30 return -EPERM;
37 31
38 return reiserfs_xattr_set(inode, name, buffer, size, flags); 32 return reiserfs_xattr_set(inode, name, buffer, size, flags);
39} 33}
40 34
41static int trusted_del(struct inode *inode, const char *name) 35static size_t trusted_list(struct inode *inode, char *list, size_t list_size,
36 const char *name, size_t name_len)
42{ 37{
43 if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) 38 const size_t len = name_len + 1;
44 return -EINVAL;
45 39
46 if (!reiserfs_xattrs(inode->i_sb)) 40 if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
47 return -EOPNOTSUPP;
48
49 if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)))
50 return -EPERM;
51
52 return 0;
53}
54
55static int
56trusted_list(struct inode *inode, const char *name, int namelen, char *out)
57{
58 int len = namelen;
59
60 if (!reiserfs_xattrs(inode->i_sb))
61 return 0; 41 return 0;
62 42
63 if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) 43 if (list && len <= list_size) {
64 return 0; 44 memcpy(list, name, name_len);
65 45 list[name_len] = '\0';
66 if (out) 46 }
67 memcpy(out, name, len);
68
69 return len; 47 return len;
70} 48}
71 49
72struct reiserfs_xattr_handler trusted_handler = { 50struct xattr_handler reiserfs_xattr_trusted_handler = {
73 .prefix = XATTR_TRUSTED_PREFIX, 51 .prefix = XATTR_TRUSTED_PREFIX,
74 .get = trusted_get, 52 .get = trusted_get,
75 .set = trusted_set, 53 .set = trusted_set,
76 .del = trusted_del,
77 .list = trusted_list, 54 .list = trusted_list,
78}; 55};
diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c
index 1384efcb938e..e3238dc4f3db 100644
--- a/fs/reiserfs/xattr_user.c
+++ b/fs/reiserfs/xattr_user.c
@@ -6,10 +6,6 @@
6#include <linux/reiserfs_xattr.h> 6#include <linux/reiserfs_xattr.h>
7#include <asm/uaccess.h> 7#include <asm/uaccess.h>
8 8
9#ifdef CONFIG_REISERFS_FS_POSIX_ACL
10# include <linux/reiserfs_acl.h>
11#endif
12
13static int 9static int
14user_get(struct inode *inode, const char *name, void *buffer, size_t size) 10user_get(struct inode *inode, const char *name, void *buffer, size_t size)
15{ 11{
@@ -25,7 +21,6 @@ static int
25user_set(struct inode *inode, const char *name, const void *buffer, 21user_set(struct inode *inode, const char *name, const void *buffer,
26 size_t size, int flags) 22 size_t size, int flags)
27{ 23{
28
29 if (strlen(name) < sizeof(XATTR_USER_PREFIX)) 24 if (strlen(name) < sizeof(XATTR_USER_PREFIX))
30 return -EINVAL; 25 return -EINVAL;
31 26
@@ -34,33 +29,23 @@ user_set(struct inode *inode, const char *name, const void *buffer,
34 return reiserfs_xattr_set(inode, name, buffer, size, flags); 29 return reiserfs_xattr_set(inode, name, buffer, size, flags);
35} 30}
36 31
37static int user_del(struct inode *inode, const char *name) 32static size_t user_list(struct inode *inode, char *list, size_t list_size,
33 const char *name, size_t name_len)
38{ 34{
39 if (strlen(name) < sizeof(XATTR_USER_PREFIX)) 35 const size_t len = name_len + 1;
40 return -EINVAL;
41
42 if (!reiserfs_xattrs_user(inode->i_sb))
43 return -EOPNOTSUPP;
44 return 0;
45}
46 36
47static int
48user_list(struct inode *inode, const char *name, int namelen, char *out)
49{
50 int len = namelen;
51 if (!reiserfs_xattrs_user(inode->i_sb)) 37 if (!reiserfs_xattrs_user(inode->i_sb))
52 return 0; 38 return 0;
53 39 if (list && len <= list_size) {
54 if (out) 40 memcpy(list, name, name_len);
55 memcpy(out, name, len); 41 list[name_len] = '\0';
56 42 }
57 return len; 43 return len;
58} 44}
59 45
60struct reiserfs_xattr_handler user_handler = { 46struct xattr_handler reiserfs_xattr_user_handler = {
61 .prefix = XATTR_USER_PREFIX, 47 .prefix = XATTR_USER_PREFIX,
62 .get = user_get, 48 .get = user_get,
63 .set = user_set, 49 .set = user_set,
64 .del = user_del,
65 .list = user_list, 50 .list = user_list,
66}; 51};