diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-12-20 08:16:47 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-01-25 23:58:20 -0500 |
commit | f2963d4551e7f500025d687586a25a09ea28941e (patch) | |
tree | c119c05fc7d7596d19fd6904386419278bf8515c /fs/jffs2/acl.c | |
parent | b0a7ab5706647844e7a1b91b0c31cdb3bee1e1cc (diff) |
jffs2: use generic posix ACL infrastructure
Also don't bother to set up a .get_acl method for symlinks as we do not
support access control (ACLs or even mode bits) for symlinks in Linux.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/jffs2/acl.c')
-rw-r--r-- | fs/jffs2/acl.c | 141 |
1 files changed, 11 insertions, 130 deletions
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 4d6e31b19816..009ec0b5993d 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -178,10 +178,6 @@ struct posix_acl *jffs2_get_acl(struct inode *inode, int type) | |||
178 | char *value = NULL; | 178 | char *value = NULL; |
179 | int rc, xprefix; | 179 | int rc, xprefix; |
180 | 180 | ||
181 | acl = get_cached_acl(inode, type); | ||
182 | if (acl != ACL_NOT_CACHED) | ||
183 | return acl; | ||
184 | |||
185 | switch (type) { | 181 | switch (type) { |
186 | case ACL_TYPE_ACCESS: | 182 | case ACL_TYPE_ACCESS: |
187 | xprefix = JFFS2_XPREFIX_ACL_ACCESS; | 183 | xprefix = JFFS2_XPREFIX_ACL_ACCESS; |
@@ -232,13 +228,10 @@ static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *a | |||
232 | return rc; | 228 | return rc; |
233 | } | 229 | } |
234 | 230 | ||
235 | static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 231 | int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
236 | { | 232 | { |
237 | int rc, xprefix; | 233 | int rc, xprefix; |
238 | 234 | ||
239 | if (S_ISLNK(inode->i_mode)) | ||
240 | return -EOPNOTSUPP; | ||
241 | |||
242 | switch (type) { | 235 | switch (type) { |
243 | case ACL_TYPE_ACCESS: | 236 | case ACL_TYPE_ACCESS: |
244 | xprefix = JFFS2_XPREFIX_ACL_ACCESS; | 237 | xprefix = JFFS2_XPREFIX_ACL_ACCESS; |
@@ -277,30 +270,21 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
277 | 270 | ||
278 | int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode) | 271 | int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode) |
279 | { | 272 | { |
280 | struct posix_acl *acl; | 273 | struct posix_acl *default_acl, *acl; |
281 | int rc; | 274 | int rc; |
282 | 275 | ||
283 | cache_no_acl(inode); | 276 | cache_no_acl(inode); |
284 | 277 | ||
285 | if (S_ISLNK(*i_mode)) | 278 | rc = posix_acl_create(dir_i, i_mode, &default_acl, &acl); |
286 | return 0; /* Symlink always has no-ACL */ | 279 | if (rc) |
287 | 280 | return rc; | |
288 | acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT); | ||
289 | if (IS_ERR(acl)) | ||
290 | return PTR_ERR(acl); | ||
291 | |||
292 | if (!acl) { | ||
293 | *i_mode &= ~current_umask(); | ||
294 | } else { | ||
295 | if (S_ISDIR(*i_mode)) | ||
296 | set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); | ||
297 | |||
298 | rc = __posix_acl_create(&acl, GFP_KERNEL, i_mode); | ||
299 | if (rc < 0) | ||
300 | return rc; | ||
301 | if (rc > 0) | ||
302 | set_cached_acl(inode, ACL_TYPE_ACCESS, acl); | ||
303 | 281 | ||
282 | if (default_acl) { | ||
283 | set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl); | ||
284 | posix_acl_release(default_acl); | ||
285 | } | ||
286 | if (acl) { | ||
287 | set_cached_acl(inode, ACL_TYPE_ACCESS, acl); | ||
304 | posix_acl_release(acl); | 288 | posix_acl_release(acl); |
305 | } | 289 | } |
306 | return 0; | 290 | return 0; |
@@ -324,106 +308,3 @@ int jffs2_init_acl_post(struct inode *inode) | |||
324 | 308 | ||
325 | return 0; | 309 | return 0; |
326 | } | 310 | } |
327 | |||
328 | int jffs2_acl_chmod(struct inode *inode) | ||
329 | { | ||
330 | struct posix_acl *acl; | ||
331 | int rc; | ||
332 | |||
333 | if (S_ISLNK(inode->i_mode)) | ||
334 | return -EOPNOTSUPP; | ||
335 | acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS); | ||
336 | if (IS_ERR(acl) || !acl) | ||
337 | return PTR_ERR(acl); | ||
338 | rc = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); | ||
339 | if (rc) | ||
340 | return rc; | ||
341 | rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, acl); | ||
342 | posix_acl_release(acl); | ||
343 | return rc; | ||
344 | } | ||
345 | |||
346 | static size_t jffs2_acl_access_listxattr(struct dentry *dentry, char *list, | ||
347 | size_t list_size, const char *name, size_t name_len, int type) | ||
348 | { | ||
349 | const int retlen = sizeof(POSIX_ACL_XATTR_ACCESS); | ||
350 | |||
351 | if (list && retlen <= list_size) | ||
352 | strcpy(list, POSIX_ACL_XATTR_ACCESS); | ||
353 | return retlen; | ||
354 | } | ||
355 | |||
356 | static size_t jffs2_acl_default_listxattr(struct dentry *dentry, char *list, | ||
357 | size_t list_size, const char *name, size_t name_len, int type) | ||
358 | { | ||
359 | const int retlen = sizeof(POSIX_ACL_XATTR_DEFAULT); | ||
360 | |||
361 | if (list && retlen <= list_size) | ||
362 | strcpy(list, POSIX_ACL_XATTR_DEFAULT); | ||
363 | return retlen; | ||
364 | } | ||
365 | |||
366 | static int jffs2_acl_getxattr(struct dentry *dentry, const char *name, | ||
367 | void *buffer, size_t size, int type) | ||
368 | { | ||
369 | struct posix_acl *acl; | ||
370 | int rc; | ||
371 | |||
372 | if (name[0] != '\0') | ||
373 | return -EINVAL; | ||
374 | |||
375 | acl = jffs2_get_acl(dentry->d_inode, type); | ||
376 | if (IS_ERR(acl)) | ||
377 | return PTR_ERR(acl); | ||
378 | if (!acl) | ||
379 | return -ENODATA; | ||
380 | rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); | ||
381 | posix_acl_release(acl); | ||
382 | |||
383 | return rc; | ||
384 | } | ||
385 | |||
386 | static int jffs2_acl_setxattr(struct dentry *dentry, const char *name, | ||
387 | const void *value, size_t size, int flags, int type) | ||
388 | { | ||
389 | struct posix_acl *acl; | ||
390 | int rc; | ||
391 | |||
392 | if (name[0] != '\0') | ||
393 | return -EINVAL; | ||
394 | if (!inode_owner_or_capable(dentry->d_inode)) | ||
395 | return -EPERM; | ||
396 | |||
397 | if (value) { | ||
398 | acl = posix_acl_from_xattr(&init_user_ns, value, size); | ||
399 | if (IS_ERR(acl)) | ||
400 | return PTR_ERR(acl); | ||
401 | if (acl) { | ||
402 | rc = posix_acl_valid(acl); | ||
403 | if (rc) | ||
404 | goto out; | ||
405 | } | ||
406 | } else { | ||
407 | acl = NULL; | ||
408 | } | ||
409 | rc = jffs2_set_acl(dentry->d_inode, type, acl); | ||
410 | out: | ||
411 | posix_acl_release(acl); | ||
412 | return rc; | ||
413 | } | ||
414 | |||
415 | const struct xattr_handler jffs2_acl_access_xattr_handler = { | ||
416 | .prefix = POSIX_ACL_XATTR_ACCESS, | ||
417 | .flags = ACL_TYPE_DEFAULT, | ||
418 | .list = jffs2_acl_access_listxattr, | ||
419 | .get = jffs2_acl_getxattr, | ||
420 | .set = jffs2_acl_setxattr, | ||
421 | }; | ||
422 | |||
423 | const struct xattr_handler jffs2_acl_default_xattr_handler = { | ||
424 | .prefix = POSIX_ACL_XATTR_DEFAULT, | ||
425 | .flags = ACL_TYPE_DEFAULT, | ||
426 | .list = jffs2_acl_default_listxattr, | ||
427 | .get = jffs2_acl_getxattr, | ||
428 | .set = jffs2_acl_setxattr, | ||
429 | }; | ||