root/fs/fuse/acl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fuse_get_acl
  2. fuse_set_acl

   1 /*
   2  * FUSE: Filesystem in Userspace
   3  * Copyright (C) 2016 Canonical Ltd. <seth.forshee@canonical.com>
   4  *
   5  * This program can be distributed under the terms of the GNU GPL.
   6  * See the file COPYING.
   7  */
   8 
   9 #include "fuse_i.h"
  10 
  11 #include <linux/posix_acl.h>
  12 #include <linux/posix_acl_xattr.h>
  13 
  14 struct posix_acl *fuse_get_acl(struct inode *inode, int type)
  15 {
  16         struct fuse_conn *fc = get_fuse_conn(inode);
  17         int size;
  18         const char *name;
  19         void *value = NULL;
  20         struct posix_acl *acl;
  21 
  22         if (!fc->posix_acl || fc->no_getxattr)
  23                 return NULL;
  24 
  25         if (type == ACL_TYPE_ACCESS)
  26                 name = XATTR_NAME_POSIX_ACL_ACCESS;
  27         else if (type == ACL_TYPE_DEFAULT)
  28                 name = XATTR_NAME_POSIX_ACL_DEFAULT;
  29         else
  30                 return ERR_PTR(-EOPNOTSUPP);
  31 
  32         value = kmalloc(PAGE_SIZE, GFP_KERNEL);
  33         if (!value)
  34                 return ERR_PTR(-ENOMEM);
  35         size = fuse_getxattr(inode, name, value, PAGE_SIZE);
  36         if (size > 0)
  37                 acl = posix_acl_from_xattr(fc->user_ns, value, size);
  38         else if ((size == 0) || (size == -ENODATA) ||
  39                  (size == -EOPNOTSUPP && fc->no_getxattr))
  40                 acl = NULL;
  41         else if (size == -ERANGE)
  42                 acl = ERR_PTR(-E2BIG);
  43         else
  44                 acl = ERR_PTR(size);
  45 
  46         kfree(value);
  47         return acl;
  48 }
  49 
  50 int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type)
  51 {
  52         struct fuse_conn *fc = get_fuse_conn(inode);
  53         const char *name;
  54         int ret;
  55 
  56         if (!fc->posix_acl || fc->no_setxattr)
  57                 return -EOPNOTSUPP;
  58 
  59         if (type == ACL_TYPE_ACCESS)
  60                 name = XATTR_NAME_POSIX_ACL_ACCESS;
  61         else if (type == ACL_TYPE_DEFAULT)
  62                 name = XATTR_NAME_POSIX_ACL_DEFAULT;
  63         else
  64                 return -EINVAL;
  65 
  66         if (acl) {
  67                 /*
  68                  * Fuse userspace is responsible for updating access
  69                  * permissions in the inode, if needed. fuse_setxattr
  70                  * invalidates the inode attributes, which will force
  71                  * them to be refreshed the next time they are used,
  72                  * and it also updates i_ctime.
  73                  */
  74                 size_t size = posix_acl_xattr_size(acl->a_count);
  75                 void *value;
  76 
  77                 if (size > PAGE_SIZE)
  78                         return -E2BIG;
  79 
  80                 value = kmalloc(size, GFP_KERNEL);
  81                 if (!value)
  82                         return -ENOMEM;
  83 
  84                 ret = posix_acl_to_xattr(fc->user_ns, acl, value, size);
  85                 if (ret < 0) {
  86                         kfree(value);
  87                         return ret;
  88                 }
  89 
  90                 ret = fuse_setxattr(inode, name, value, size, 0);
  91                 kfree(value);
  92         } else {
  93                 ret = fuse_removexattr(inode, name);
  94         }
  95         forget_all_cached_acls(inode);
  96         fuse_invalidate_attr(inode);
  97 
  98         return ret;
  99 }

/* [<][>][^][v][top][bottom][index][help] */