aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-12-20 08:16:46 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-01-25 23:58:20 -0500
commitb0a7ab5706647844e7a1b91b0c31cdb3bee1e1cc (patch)
tree44ca5a54d751a42f36acb53116da3240fc3a7bb3 /fs/hfsplus
parenta6dda0e63e97122ce9e0ba04367e37cca28315fa (diff)
hfsplus: use generic posix ACL infrastructure
Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Vyacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/hfsplus')
-rw-r--r--fs/hfsplus/acl.h9
-rw-r--r--fs/hfsplus/dir.c1
-rw-r--r--fs/hfsplus/inode.c3
-rw-r--r--fs/hfsplus/posix_acl.c168
-rw-r--r--fs/hfsplus/xattr.c5
-rw-r--r--fs/hfsplus/xattr.h2
6 files changed, 26 insertions, 162 deletions
diff --git a/fs/hfsplus/acl.h b/fs/hfsplus/acl.h
index 07c0d4947527..95c8ed9ec17f 100644
--- a/fs/hfsplus/acl.h
+++ b/fs/hfsplus/acl.h
@@ -12,16 +12,13 @@
12 12
13/* posix_acl.c */ 13/* posix_acl.c */
14struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type); 14struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type);
15extern int hfsplus_posix_acl_chmod(struct inode *); 15int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
16 int type);
16extern int hfsplus_init_posix_acl(struct inode *, struct inode *); 17extern int hfsplus_init_posix_acl(struct inode *, struct inode *);
17 18
18#else /* CONFIG_HFSPLUS_FS_POSIX_ACL */ 19#else /* CONFIG_HFSPLUS_FS_POSIX_ACL */
19#define hfsplus_get_posix_acl NULL 20#define hfsplus_get_posix_acl NULL
20 21#define hfsplus_set_posix_acl NULL
21static inline int hfsplus_posix_acl_chmod(struct inode *inode)
22{
23 return 0;
24}
25 22
26static inline int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) 23static inline int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
27{ 24{
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 4a4fea002673..9ee62985e739 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -532,6 +532,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
532 .removexattr = hfsplus_removexattr, 532 .removexattr = hfsplus_removexattr,
533#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 533#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
534 .get_acl = hfsplus_get_posix_acl, 534 .get_acl = hfsplus_get_posix_acl,
535 .set_acl = hfsplus_set_posix_acl,
535#endif 536#endif
536}; 537};
537 538
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 37213d075f3c..2e10993fa966 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -319,7 +319,7 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
319 mark_inode_dirty(inode); 319 mark_inode_dirty(inode);
320 320
321 if (attr->ia_valid & ATTR_MODE) { 321 if (attr->ia_valid & ATTR_MODE) {
322 error = hfsplus_posix_acl_chmod(inode); 322 error = posix_acl_chmod(inode, inode->i_mode);
323 if (unlikely(error)) 323 if (unlikely(error))
324 return error; 324 return error;
325 } 325 }
@@ -393,6 +393,7 @@ static const struct inode_operations hfsplus_file_inode_operations = {
393 .removexattr = hfsplus_removexattr, 393 .removexattr = hfsplus_removexattr,
394#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 394#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
395 .get_acl = hfsplus_get_posix_acl, 395 .get_acl = hfsplus_get_posix_acl,
396 .set_acl = hfsplus_set_posix_acl,
396#endif 397#endif
397}; 398};
398 399
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c
index 277942f36f80..df0c9af68d05 100644
--- a/fs/hfsplus/posix_acl.c
+++ b/fs/hfsplus/posix_acl.c
@@ -17,9 +17,7 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
17 char *value = NULL; 17 char *value = NULL;
18 ssize_t size; 18 ssize_t size;
19 19
20 acl = get_cached_acl(inode, type); 20 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
21 if (acl != ACL_NOT_CACHED)
22 return acl;
23 21
24 switch (type) { 22 switch (type) {
25 case ACL_TYPE_ACCESS: 23 case ACL_TYPE_ACCESS:
@@ -56,17 +54,15 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
56 return acl; 54 return acl;
57} 55}
58 56
59static int hfsplus_set_posix_acl(struct inode *inode, 57int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
60 int type, 58 int type)
61 struct posix_acl *acl)
62{ 59{
63 int err; 60 int err;
64 char *xattr_name; 61 char *xattr_name;
65 size_t size = 0; 62 size_t size = 0;
66 char *value = NULL; 63 char *value = NULL;
67 64
68 if (S_ISLNK(inode->i_mode)) 65 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
69 return -EOPNOTSUPP;
70 66
71 switch (type) { 67 switch (type) {
72 case ACL_TYPE_ACCESS: 68 case ACL_TYPE_ACCESS:
@@ -115,7 +111,7 @@ end_set_acl:
115int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) 111int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
116{ 112{
117 int err = 0; 113 int err = 0;
118 struct posix_acl *acl = NULL; 114 struct posix_acl *default_acl, *acl;
119 115
120 hfs_dbg(ACL_MOD, 116 hfs_dbg(ACL_MOD,
121 "[%s]: ino %lu, dir->ino %lu\n", 117 "[%s]: ino %lu, dir->ino %lu\n",
@@ -124,151 +120,21 @@ int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
124 if (S_ISLNK(inode->i_mode)) 120 if (S_ISLNK(inode->i_mode))
125 return 0; 121 return 0;
126 122
127 acl = hfsplus_get_posix_acl(dir, ACL_TYPE_DEFAULT); 123 err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
128 if (IS_ERR(acl)) 124 if (err)
129 return PTR_ERR(acl);
130
131 if (acl) {
132 if (S_ISDIR(inode->i_mode)) {
133 err = hfsplus_set_posix_acl(inode,
134 ACL_TYPE_DEFAULT,
135 acl);
136 if (unlikely(err))
137 goto init_acl_cleanup;
138 }
139
140 err = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
141 if (unlikely(err < 0))
142 return err;
143
144 if (err > 0)
145 err = hfsplus_set_posix_acl(inode,
146 ACL_TYPE_ACCESS,
147 acl);
148 } else
149 inode->i_mode &= ~current_umask();
150
151init_acl_cleanup:
152 posix_acl_release(acl);
153 return err;
154}
155
156int hfsplus_posix_acl_chmod(struct inode *inode)
157{
158 int err;
159 struct posix_acl *acl;
160
161 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
162
163 if (S_ISLNK(inode->i_mode))
164 return -EOPNOTSUPP;
165
166 acl = hfsplus_get_posix_acl(inode, ACL_TYPE_ACCESS);
167 if (IS_ERR(acl) || !acl)
168 return PTR_ERR(acl);
169
170 err = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
171 if (unlikely(err))
172 return err; 125 return err;
173 126
174 err = hfsplus_set_posix_acl(inode, ACL_TYPE_ACCESS, acl); 127 if (default_acl) {
175 posix_acl_release(acl); 128 err = hfsplus_set_posix_acl(inode, default_acl,
176 return err; 129 ACL_TYPE_DEFAULT);
177} 130 posix_acl_release(default_acl);
178
179static int hfsplus_xattr_get_posix_acl(struct dentry *dentry,
180 const char *name,
181 void *buffer,
182 size_t size,
183 int type)
184{
185 int err = 0;
186 struct posix_acl *acl;
187
188 hfs_dbg(ACL_MOD,
189 "[%s]: ino %lu, buffer %p, size %zu, type %#x\n",
190 __func__, dentry->d_inode->i_ino, buffer, size, type);
191
192 if (strcmp(name, "") != 0)
193 return -EINVAL;
194
195 acl = hfsplus_get_posix_acl(dentry->d_inode, type);
196 if (IS_ERR(acl))
197 return PTR_ERR(acl);
198 if (acl == NULL)
199 return -ENODATA;
200
201 err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
202 posix_acl_release(acl);
203
204 return err;
205}
206
207static int hfsplus_xattr_set_posix_acl(struct dentry *dentry,
208 const char *name,
209 const void *value,
210 size_t size,
211 int flags,
212 int type)
213{
214 int err = 0;
215 struct inode *inode = dentry->d_inode;
216 struct posix_acl *acl = NULL;
217
218 hfs_dbg(ACL_MOD,
219 "[%s]: ino %lu, value %p, size %zu, flags %#x, type %#x\n",
220 __func__, inode->i_ino, value, size, flags, type);
221
222 if (strcmp(name, "") != 0)
223 return -EINVAL;
224
225 if (!inode_owner_or_capable(inode))
226 return -EPERM;
227
228 if (value) {
229 acl = posix_acl_from_xattr(&init_user_ns, value, size);
230 if (IS_ERR(acl))
231 return PTR_ERR(acl);
232 else if (acl) {
233 err = posix_acl_valid(acl);
234 if (err)
235 goto end_xattr_set_acl;
236 }
237 } 131 }
238 132
239 err = hfsplus_set_posix_acl(inode, type, acl); 133 if (acl) {
240 134 if (!err)
241end_xattr_set_acl: 135 err = hfsplus_set_posix_acl(inode, acl,
242 posix_acl_release(acl); 136 ACL_TYPE_ACCESS);
137 posix_acl_release(acl);
138 }
243 return err; 139 return err;
244} 140}
245
246static size_t hfsplus_xattr_list_posix_acl(struct dentry *dentry,
247 char *list,
248 size_t list_size,
249 const char *name,
250 size_t name_len,
251 int type)
252{
253 /*
254 * This method is not used.
255 * It is used hfsplus_listxattr() instead of generic_listxattr().
256 */
257 return -EOPNOTSUPP;
258}
259
260const struct xattr_handler hfsplus_xattr_acl_access_handler = {
261 .prefix = POSIX_ACL_XATTR_ACCESS,
262 .flags = ACL_TYPE_ACCESS,
263 .list = hfsplus_xattr_list_posix_acl,
264 .get = hfsplus_xattr_get_posix_acl,
265 .set = hfsplus_xattr_set_posix_acl,
266};
267
268const struct xattr_handler hfsplus_xattr_acl_default_handler = {
269 .prefix = POSIX_ACL_XATTR_DEFAULT,
270 .flags = ACL_TYPE_DEFAULT,
271 .list = hfsplus_xattr_list_posix_acl,
272 .get = hfsplus_xattr_get_posix_acl,
273 .set = hfsplus_xattr_set_posix_acl,
274};
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index 3c6136f98c73..bf88baa9bb65 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include "hfsplus_fs.h" 9#include "hfsplus_fs.h"
10#include <linux/posix_acl_xattr.h>
10#include "xattr.h" 11#include "xattr.h"
11#include "acl.h" 12#include "acl.h"
12 13
@@ -15,8 +16,8 @@ const struct xattr_handler *hfsplus_xattr_handlers[] = {
15 &hfsplus_xattr_user_handler, 16 &hfsplus_xattr_user_handler,
16 &hfsplus_xattr_trusted_handler, 17 &hfsplus_xattr_trusted_handler,
17#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 18#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
18 &hfsplus_xattr_acl_access_handler, 19 &posix_acl_access_xattr_handler,
19 &hfsplus_xattr_acl_default_handler, 20 &posix_acl_default_xattr_handler,
20#endif 21#endif
21 &hfsplus_xattr_security_handler, 22 &hfsplus_xattr_security_handler,
22 NULL 23 NULL
diff --git a/fs/hfsplus/xattr.h b/fs/hfsplus/xattr.h
index 841b5698c0fc..9e214490c313 100644
--- a/fs/hfsplus/xattr.h
+++ b/fs/hfsplus/xattr.h
@@ -14,8 +14,6 @@
14extern const struct xattr_handler hfsplus_xattr_osx_handler; 14extern const struct xattr_handler hfsplus_xattr_osx_handler;
15extern const struct xattr_handler hfsplus_xattr_user_handler; 15extern const struct xattr_handler hfsplus_xattr_user_handler;
16extern const struct xattr_handler hfsplus_xattr_trusted_handler; 16extern const struct xattr_handler hfsplus_xattr_trusted_handler;
17extern const struct xattr_handler hfsplus_xattr_acl_access_handler;
18extern const struct xattr_handler hfsplus_xattr_acl_default_handler;
19extern const struct xattr_handler hfsplus_xattr_security_handler; 17extern const struct xattr_handler hfsplus_xattr_security_handler;
20 18
21extern const struct xattr_handler *hfsplus_xattr_handlers[]; 19extern const struct xattr_handler *hfsplus_xattr_handlers[];