diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/jfs/acl.c | 105 | ||||
-rw-r--r-- | fs/jfs/file.c | 4 | ||||
-rw-r--r-- | fs/jfs/jfs_acl.h | 7 | ||||
-rw-r--r-- | fs/jfs/jfs_xattr.h | 2 | ||||
-rw-r--r-- | fs/jfs/namei.c | 1 | ||||
-rw-r--r-- | fs/jfs/super.c | 2 | ||||
-rw-r--r-- | fs/jfs/xattr.c | 108 |
7 files changed, 89 insertions, 140 deletions
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 28d529ae9a4a..e973b85d6afd 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
@@ -72,7 +72,7 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type) | |||
72 | return acl; | 72 | return acl; |
73 | } | 73 | } |
74 | 74 | ||
75 | static int jfs_set_acl(tid_t tid, struct inode *inode, int type, | 75 | static int __jfs_set_acl(tid_t tid, struct inode *inode, int type, |
76 | struct posix_acl *acl) | 76 | struct posix_acl *acl) |
77 | { | 77 | { |
78 | char *ea_name; | 78 | char *ea_name; |
@@ -80,21 +80,22 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, | |||
80 | int size = 0; | 80 | int size = 0; |
81 | char *value = NULL; | 81 | char *value = NULL; |
82 | 82 | ||
83 | if (S_ISLNK(inode->i_mode)) | 83 | switch (type) { |
84 | return -EOPNOTSUPP; | 84 | case ACL_TYPE_ACCESS: |
85 | 85 | ea_name = POSIX_ACL_XATTR_ACCESS; | |
86 | switch(type) { | 86 | rc = posix_acl_equiv_mode(acl, &inode->i_mode); |
87 | case ACL_TYPE_ACCESS: | 87 | if (rc < 0) |
88 | ea_name = POSIX_ACL_XATTR_ACCESS; | 88 | return rc; |
89 | break; | 89 | if (rc == 0) |
90 | case ACL_TYPE_DEFAULT: | 90 | acl = NULL; |
91 | ea_name = POSIX_ACL_XATTR_DEFAULT; | 91 | break; |
92 | if (!S_ISDIR(inode->i_mode)) | 92 | case ACL_TYPE_DEFAULT: |
93 | return acl ? -EACCES : 0; | 93 | ea_name = POSIX_ACL_XATTR_DEFAULT; |
94 | break; | 94 | break; |
95 | default: | 95 | default: |
96 | return -EINVAL; | 96 | return -EINVAL; |
97 | } | 97 | } |
98 | |||
98 | if (acl) { | 99 | if (acl) { |
99 | size = posix_acl_xattr_size(acl->a_count); | 100 | size = posix_acl_xattr_size(acl->a_count); |
100 | value = kmalloc(size, GFP_KERNEL); | 101 | value = kmalloc(size, GFP_KERNEL); |
@@ -114,65 +115,43 @@ out: | |||
114 | return rc; | 115 | return rc; |
115 | } | 116 | } |
116 | 117 | ||
118 | int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) | ||
119 | { | ||
120 | int rc; | ||
121 | tid_t tid; | ||
122 | |||
123 | tid = txBegin(inode->i_sb, 0); | ||
124 | mutex_lock(&JFS_IP(inode)->commit_mutex); | ||
125 | rc = __jfs_set_acl(tid, inode, type, acl); | ||
126 | if (!rc) | ||
127 | rc = txCommit(tid, 1, &inode, 0); | ||
128 | txEnd(tid); | ||
129 | mutex_unlock(&JFS_IP(inode)->commit_mutex); | ||
130 | return rc; | ||
131 | } | ||
132 | |||
117 | int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) | 133 | int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) |
118 | { | 134 | { |
119 | struct posix_acl *acl = NULL; | 135 | struct posix_acl *default_acl, *acl; |
120 | int rc = 0; | 136 | int rc = 0; |
121 | 137 | ||
122 | if (S_ISLNK(inode->i_mode)) | 138 | rc = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); |
123 | return 0; | 139 | if (rc) |
140 | return rc; | ||
124 | 141 | ||
125 | acl = jfs_get_acl(dir, ACL_TYPE_DEFAULT); | 142 | if (default_acl) { |
126 | if (IS_ERR(acl)) | 143 | rc = __jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, default_acl); |
127 | return PTR_ERR(acl); | 144 | posix_acl_release(default_acl); |
145 | } | ||
128 | 146 | ||
129 | if (acl) { | 147 | if (acl) { |
130 | if (S_ISDIR(inode->i_mode)) { | 148 | if (!rc) |
131 | rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl); | 149 | rc = __jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl); |
132 | if (rc) | ||
133 | goto cleanup; | ||
134 | } | ||
135 | rc = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); | ||
136 | if (rc < 0) | ||
137 | goto cleanup; /* posix_acl_release(NULL) is no-op */ | ||
138 | if (rc > 0) | ||
139 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl); | ||
140 | cleanup: | ||
141 | posix_acl_release(acl); | 150 | posix_acl_release(acl); |
142 | } else | 151 | } |
143 | inode->i_mode &= ~current_umask(); | ||
144 | 152 | ||
145 | JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | | 153 | JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | |
146 | inode->i_mode; | 154 | inode->i_mode; |
147 | 155 | ||
148 | return rc; | 156 | return rc; |
149 | } | 157 | } |
150 | |||
151 | int jfs_acl_chmod(struct inode *inode) | ||
152 | { | ||
153 | struct posix_acl *acl; | ||
154 | int rc; | ||
155 | tid_t tid; | ||
156 | |||
157 | if (S_ISLNK(inode->i_mode)) | ||
158 | return -EOPNOTSUPP; | ||
159 | |||
160 | acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); | ||
161 | if (IS_ERR(acl) || !acl) | ||
162 | return PTR_ERR(acl); | ||
163 | |||
164 | rc = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); | ||
165 | if (rc) | ||
166 | return rc; | ||
167 | |||
168 | tid = txBegin(inode->i_sb, 0); | ||
169 | mutex_lock(&JFS_IP(inode)->commit_mutex); | ||
170 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl); | ||
171 | if (!rc) | ||
172 | rc = txCommit(tid, 1, &inode, 0); | ||
173 | txEnd(tid); | ||
174 | mutex_unlock(&JFS_IP(inode)->commit_mutex); | ||
175 | |||
176 | posix_acl_release(acl); | ||
177 | return rc; | ||
178 | } | ||
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index dd7442c58358..794da944d5cd 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/posix_acl.h> | ||
22 | #include <linux/quotaops.h> | 23 | #include <linux/quotaops.h> |
23 | #include "jfs_incore.h" | 24 | #include "jfs_incore.h" |
24 | #include "jfs_inode.h" | 25 | #include "jfs_inode.h" |
@@ -131,7 +132,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
131 | mark_inode_dirty(inode); | 132 | mark_inode_dirty(inode); |
132 | 133 | ||
133 | if (iattr->ia_valid & ATTR_MODE) | 134 | if (iattr->ia_valid & ATTR_MODE) |
134 | rc = jfs_acl_chmod(inode); | 135 | rc = posix_acl_chmod(inode, inode->i_mode); |
135 | return rc; | 136 | return rc; |
136 | } | 137 | } |
137 | 138 | ||
@@ -143,6 +144,7 @@ const struct inode_operations jfs_file_inode_operations = { | |||
143 | .setattr = jfs_setattr, | 144 | .setattr = jfs_setattr, |
144 | #ifdef CONFIG_JFS_POSIX_ACL | 145 | #ifdef CONFIG_JFS_POSIX_ACL |
145 | .get_acl = jfs_get_acl, | 146 | .get_acl = jfs_get_acl, |
147 | .set_acl = jfs_set_acl, | ||
146 | #endif | 148 | #endif |
147 | }; | 149 | }; |
148 | 150 | ||
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index ad84fe50ca9e..489f993b7b13 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h | |||
@@ -21,8 +21,8 @@ | |||
21 | #ifdef CONFIG_JFS_POSIX_ACL | 21 | #ifdef CONFIG_JFS_POSIX_ACL |
22 | 22 | ||
23 | struct posix_acl *jfs_get_acl(struct inode *inode, int type); | 23 | struct posix_acl *jfs_get_acl(struct inode *inode, int type); |
24 | int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); | ||
24 | int jfs_init_acl(tid_t, struct inode *, struct inode *); | 25 | int jfs_init_acl(tid_t, struct inode *, struct inode *); |
25 | int jfs_acl_chmod(struct inode *inode); | ||
26 | 26 | ||
27 | #else | 27 | #else |
28 | 28 | ||
@@ -32,10 +32,5 @@ static inline int jfs_init_acl(tid_t tid, struct inode *inode, | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | static inline int jfs_acl_chmod(struct inode *inode) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | #endif | 35 | #endif |
41 | #endif /* _H_JFS_ACL */ | 36 | #endif /* _H_JFS_ACL */ |
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h index e9e100fd7c09..e8d717dabca3 100644 --- a/fs/jfs/jfs_xattr.h +++ b/fs/jfs/jfs_xattr.h | |||
@@ -61,6 +61,8 @@ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t); | |||
61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); | 61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); |
62 | extern int jfs_removexattr(struct dentry *, const char *); | 62 | extern int jfs_removexattr(struct dentry *, const char *); |
63 | 63 | ||
64 | extern const struct xattr_handler *jfs_xattr_handlers[]; | ||
65 | |||
64 | #ifdef CONFIG_JFS_SECURITY | 66 | #ifdef CONFIG_JFS_SECURITY |
65 | extern int jfs_init_security(tid_t, struct inode *, struct inode *, | 67 | extern int jfs_init_security(tid_t, struct inode *, struct inode *, |
66 | const struct qstr *); | 68 | const struct qstr *); |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index aa8a3370631b..d59c7defb1ef 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1524,6 +1524,7 @@ const struct inode_operations jfs_dir_inode_operations = { | |||
1524 | .setattr = jfs_setattr, | 1524 | .setattr = jfs_setattr, |
1525 | #ifdef CONFIG_JFS_POSIX_ACL | 1525 | #ifdef CONFIG_JFS_POSIX_ACL |
1526 | .get_acl = jfs_get_acl, | 1526 | .get_acl = jfs_get_acl, |
1527 | .set_acl = jfs_set_acl, | ||
1527 | #endif | 1528 | #endif |
1528 | }; | 1529 | }; |
1529 | 1530 | ||
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 6669aa2042c3..e2b7483444fd 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "jfs_imap.h" | 44 | #include "jfs_imap.h" |
45 | #include "jfs_acl.h" | 45 | #include "jfs_acl.h" |
46 | #include "jfs_debug.h" | 46 | #include "jfs_debug.h" |
47 | #include "jfs_xattr.h" | ||
47 | 48 | ||
48 | MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); | 49 | MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); |
49 | MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); | 50 | MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); |
@@ -522,6 +523,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
522 | */ | 523 | */ |
523 | sb->s_op = &jfs_super_operations; | 524 | sb->s_op = &jfs_super_operations; |
524 | sb->s_export_op = &jfs_export_operations; | 525 | sb->s_export_op = &jfs_export_operations; |
526 | sb->s_xattr = jfs_xattr_handlers; | ||
525 | #ifdef CONFIG_QUOTA | 527 | #ifdef CONFIG_QUOTA |
526 | sb->dq_op = &dquot_operations; | 528 | sb->dq_op = &dquot_operations; |
527 | sb->s_qcop = &dquot_quotactl_ops; | 529 | sb->s_qcop = &dquot_quotactl_ops; |
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index d3472f4cd530..5324e4e2b992 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -666,81 +666,12 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, | |||
666 | } | 666 | } |
667 | 667 | ||
668 | /* | 668 | /* |
669 | * can_set_system_xattr | ||
670 | * | ||
671 | * This code is specific to the system.* namespace. It contains policy | ||
672 | * which doesn't belong in the main xattr codepath. | ||
673 | */ | ||
674 | static int can_set_system_xattr(struct inode *inode, const char *name, | ||
675 | const void *value, size_t value_len) | ||
676 | { | ||
677 | #ifdef CONFIG_JFS_POSIX_ACL | ||
678 | struct posix_acl *acl; | ||
679 | int rc; | ||
680 | |||
681 | if (!inode_owner_or_capable(inode)) | ||
682 | return -EPERM; | ||
683 | |||
684 | /* | ||
685 | * POSIX_ACL_XATTR_ACCESS is tied to i_mode | ||
686 | */ | ||
687 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) { | ||
688 | acl = posix_acl_from_xattr(&init_user_ns, value, value_len); | ||
689 | if (IS_ERR(acl)) { | ||
690 | rc = PTR_ERR(acl); | ||
691 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", | ||
692 | rc); | ||
693 | return rc; | ||
694 | } | ||
695 | if (acl) { | ||
696 | rc = posix_acl_equiv_mode(acl, &inode->i_mode); | ||
697 | posix_acl_release(acl); | ||
698 | if (rc < 0) { | ||
699 | printk(KERN_ERR | ||
700 | "posix_acl_equiv_mode returned %d\n", | ||
701 | rc); | ||
702 | return rc; | ||
703 | } | ||
704 | mark_inode_dirty(inode); | ||
705 | } | ||
706 | /* | ||
707 | * We're changing the ACL. Get rid of the cached one | ||
708 | */ | ||
709 | forget_cached_acl(inode, ACL_TYPE_ACCESS); | ||
710 | |||
711 | return 0; | ||
712 | } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { | ||
713 | acl = posix_acl_from_xattr(&init_user_ns, value, value_len); | ||
714 | if (IS_ERR(acl)) { | ||
715 | rc = PTR_ERR(acl); | ||
716 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", | ||
717 | rc); | ||
718 | return rc; | ||
719 | } | ||
720 | posix_acl_release(acl); | ||
721 | |||
722 | /* | ||
723 | * We're changing the default ACL. Get rid of the cached one | ||
724 | */ | ||
725 | forget_cached_acl(inode, ACL_TYPE_DEFAULT); | ||
726 | |||
727 | return 0; | ||
728 | } | ||
729 | #endif /* CONFIG_JFS_POSIX_ACL */ | ||
730 | return -EOPNOTSUPP; | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * Most of the permission checking is done by xattr_permission in the vfs. | 669 | * Most of the permission checking is done by xattr_permission in the vfs. |
735 | * The local file system is responsible for handling the system.* namespace. | ||
736 | * We also need to verify that this is a namespace that we recognize. | 670 | * We also need to verify that this is a namespace that we recognize. |
737 | */ | 671 | */ |
738 | static int can_set_xattr(struct inode *inode, const char *name, | 672 | static int can_set_xattr(struct inode *inode, const char *name, |
739 | const void *value, size_t value_len) | 673 | const void *value, size_t value_len) |
740 | { | 674 | { |
741 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
742 | return can_set_system_xattr(inode, name, value, value_len); | ||
743 | |||
744 | if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { | 675 | if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { |
745 | /* | 676 | /* |
746 | * This makes sure that we aren't trying to set an | 677 | * This makes sure that we aren't trying to set an |
@@ -748,7 +679,7 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
748 | * with "os2." | 679 | * with "os2." |
749 | */ | 680 | */ |
750 | if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) | 681 | if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) |
751 | return -EOPNOTSUPP; | 682 | return -EOPNOTSUPP; |
752 | return 0; | 683 | return 0; |
753 | } | 684 | } |
754 | 685 | ||
@@ -913,6 +844,14 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
913 | if ((rc = can_set_xattr(inode, name, value, value_len))) | 844 | if ((rc = can_set_xattr(inode, name, value, value_len))) |
914 | return rc; | 845 | return rc; |
915 | 846 | ||
847 | /* | ||
848 | * If this is a request for a synthetic attribute in the system.* | ||
849 | * namespace use the generic infrastructure to resolve a handler | ||
850 | * for it via sb->s_xattr. | ||
851 | */ | ||
852 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
853 | return generic_setxattr(dentry, name, value, value_len, flags); | ||
854 | |||
916 | if (value == NULL) { /* empty EA, do not remove */ | 855 | if (value == NULL) { /* empty EA, do not remove */ |
917 | value = ""; | 856 | value = ""; |
918 | value_len = 0; | 857 | value_len = 0; |
@@ -986,6 +925,14 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data, | |||
986 | { | 925 | { |
987 | int err; | 926 | int err; |
988 | 927 | ||
928 | /* | ||
929 | * If this is a request for a synthetic attribute in the system.* | ||
930 | * namespace use the generic infrastructure to resolve a handler | ||
931 | * for it via sb->s_xattr. | ||
932 | */ | ||
933 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
934 | return generic_getxattr(dentry, name, data, buf_size); | ||
935 | |||
989 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | 936 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { |
990 | /* | 937 | /* |
991 | * skip past "os2." prefix | 938 | * skip past "os2." prefix |
@@ -1077,6 +1024,14 @@ int jfs_removexattr(struct dentry *dentry, const char *name) | |||
1077 | if ((rc = can_set_xattr(inode, name, NULL, 0))) | 1024 | if ((rc = can_set_xattr(inode, name, NULL, 0))) |
1078 | return rc; | 1025 | return rc; |
1079 | 1026 | ||
1027 | /* | ||
1028 | * If this is a request for a synthetic attribute in the system.* | ||
1029 | * namespace use the generic infrastructure to resolve a handler | ||
1030 | * for it via sb->s_xattr. | ||
1031 | */ | ||
1032 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
1033 | return generic_removexattr(dentry, name); | ||
1034 | |||
1080 | tid = txBegin(inode->i_sb, 0); | 1035 | tid = txBegin(inode->i_sb, 0); |
1081 | mutex_lock(&ji->commit_mutex); | 1036 | mutex_lock(&ji->commit_mutex); |
1082 | rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | 1037 | rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); |
@@ -1088,6 +1043,19 @@ int jfs_removexattr(struct dentry *dentry, const char *name) | |||
1088 | return rc; | 1043 | return rc; |
1089 | } | 1044 | } |
1090 | 1045 | ||
1046 | /* | ||
1047 | * List of handlers for synthetic system.* attributes. All real ondisk | ||
1048 | * attributes are handled directly. | ||
1049 | */ | ||
1050 | const struct xattr_handler *jfs_xattr_handlers[] = { | ||
1051 | #ifdef JFS_POSIX_ACL | ||
1052 | &posix_acl_access_xattr_handler, | ||
1053 | &posix_acl_default_xattr_handler, | ||
1054 | #endif | ||
1055 | NULL, | ||
1056 | }; | ||
1057 | |||
1058 | |||
1091 | #ifdef CONFIG_JFS_SECURITY | 1059 | #ifdef CONFIG_JFS_SECURITY |
1092 | static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, | 1060 | static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, |
1093 | void *fs_info) | 1061 | void *fs_info) |