LCOV - code coverage report
Current view: top level - fs/fuse - xattr.c (source / functions) Hit Total Coverage
Test: Real Lines: 0 107 0.0 %
Date: 2020-10-17 15:46:16 Functions: 0 10 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * FUSE: Filesystem in Userspace
       3                 :            :  * Copyright (C) 2001-2016  Miklos Szeredi <miklos@szeredi.hu>
       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/xattr.h>
      12                 :            : #include <linux/posix_acl_xattr.h>
      13                 :            : 
      14                 :          0 : int fuse_setxattr(struct inode *inode, const char *name, const void *value,
      15                 :            :                   size_t size, int flags)
      16                 :            : {
      17                 :            :         struct fuse_conn *fc = get_fuse_conn(inode);
      18                 :          0 :         FUSE_ARGS(args);
      19                 :            :         struct fuse_setxattr_in inarg;
      20                 :            :         int err;
      21                 :            : 
      22                 :          0 :         if (fc->no_setxattr)
      23                 :            :                 return -EOPNOTSUPP;
      24                 :            : 
      25                 :          0 :         memset(&inarg, 0, sizeof(inarg));
      26                 :          0 :         inarg.size = size;
      27                 :          0 :         inarg.flags = flags;
      28                 :          0 :         args.opcode = FUSE_SETXATTR;
      29                 :          0 :         args.nodeid = get_node_id(inode);
      30                 :          0 :         args.in_numargs = 3;
      31                 :          0 :         args.in_args[0].size = sizeof(inarg);
      32                 :          0 :         args.in_args[0].value = &inarg;
      33                 :          0 :         args.in_args[1].size = strlen(name) + 1;
      34                 :          0 :         args.in_args[1].value = name;
      35                 :          0 :         args.in_args[2].size = size;
      36                 :          0 :         args.in_args[2].value = value;
      37                 :          0 :         err = fuse_simple_request(fc, &args);
      38                 :          0 :         if (err == -ENOSYS) {
      39                 :          0 :                 fc->no_setxattr = 1;
      40                 :            :                 err = -EOPNOTSUPP;
      41                 :            :         }
      42                 :          0 :         if (!err) {
      43                 :          0 :                 fuse_invalidate_attr(inode);
      44                 :          0 :                 fuse_update_ctime(inode);
      45                 :            :         }
      46                 :          0 :         return err;
      47                 :            : }
      48                 :            : 
      49                 :          0 : ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value,
      50                 :            :                       size_t size)
      51                 :            : {
      52                 :            :         struct fuse_conn *fc = get_fuse_conn(inode);
      53                 :          0 :         FUSE_ARGS(args);
      54                 :            :         struct fuse_getxattr_in inarg;
      55                 :            :         struct fuse_getxattr_out outarg;
      56                 :            :         ssize_t ret;
      57                 :            : 
      58                 :          0 :         if (fc->no_getxattr)
      59                 :            :                 return -EOPNOTSUPP;
      60                 :            : 
      61                 :          0 :         memset(&inarg, 0, sizeof(inarg));
      62                 :          0 :         inarg.size = size;
      63                 :          0 :         args.opcode = FUSE_GETXATTR;
      64                 :          0 :         args.nodeid = get_node_id(inode);
      65                 :          0 :         args.in_numargs = 2;
      66                 :          0 :         args.in_args[0].size = sizeof(inarg);
      67                 :          0 :         args.in_args[0].value = &inarg;
      68                 :          0 :         args.in_args[1].size = strlen(name) + 1;
      69                 :          0 :         args.in_args[1].value = name;
      70                 :            :         /* This is really two different operations rolled into one */
      71                 :          0 :         args.out_numargs = 1;
      72                 :          0 :         if (size) {
      73                 :          0 :                 args.out_argvar = true;
      74                 :          0 :                 args.out_args[0].size = size;
      75                 :          0 :                 args.out_args[0].value = value;
      76                 :            :         } else {
      77                 :          0 :                 args.out_args[0].size = sizeof(outarg);
      78                 :          0 :                 args.out_args[0].value = &outarg;
      79                 :            :         }
      80                 :          0 :         ret = fuse_simple_request(fc, &args);
      81                 :          0 :         if (!ret && !size)
      82                 :          0 :                 ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX);
      83                 :          0 :         if (ret == -ENOSYS) {
      84                 :          0 :                 fc->no_getxattr = 1;
      85                 :            :                 ret = -EOPNOTSUPP;
      86                 :            :         }
      87                 :          0 :         return ret;
      88                 :            : }
      89                 :            : 
      90                 :          0 : static int fuse_verify_xattr_list(char *list, size_t size)
      91                 :            : {
      92                 :            :         size_t origsize = size;
      93                 :            : 
      94                 :          0 :         while (size) {
      95                 :          0 :                 size_t thislen = strnlen(list, size);
      96                 :            : 
      97                 :          0 :                 if (!thislen || thislen == size)
      98                 :            :                         return -EIO;
      99                 :            : 
     100                 :          0 :                 size -= thislen + 1;
     101                 :          0 :                 list += thislen + 1;
     102                 :            :         }
     103                 :            : 
     104                 :          0 :         return origsize;
     105                 :            : }
     106                 :            : 
     107                 :          0 : ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
     108                 :            : {
     109                 :            :         struct inode *inode = d_inode(entry);
     110                 :            :         struct fuse_conn *fc = get_fuse_conn(inode);
     111                 :          0 :         FUSE_ARGS(args);
     112                 :            :         struct fuse_getxattr_in inarg;
     113                 :            :         struct fuse_getxattr_out outarg;
     114                 :            :         ssize_t ret;
     115                 :            : 
     116                 :          0 :         if (!fuse_allow_current_process(fc))
     117                 :            :                 return -EACCES;
     118                 :            : 
     119                 :          0 :         if (fc->no_listxattr)
     120                 :            :                 return -EOPNOTSUPP;
     121                 :            : 
     122                 :          0 :         memset(&inarg, 0, sizeof(inarg));
     123                 :          0 :         inarg.size = size;
     124                 :          0 :         args.opcode = FUSE_LISTXATTR;
     125                 :          0 :         args.nodeid = get_node_id(inode);
     126                 :          0 :         args.in_numargs = 1;
     127                 :          0 :         args.in_args[0].size = sizeof(inarg);
     128                 :          0 :         args.in_args[0].value = &inarg;
     129                 :            :         /* This is really two different operations rolled into one */
     130                 :          0 :         args.out_numargs = 1;
     131                 :          0 :         if (size) {
     132                 :          0 :                 args.out_argvar = true;
     133                 :          0 :                 args.out_args[0].size = size;
     134                 :          0 :                 args.out_args[0].value = list;
     135                 :            :         } else {
     136                 :          0 :                 args.out_args[0].size = sizeof(outarg);
     137                 :          0 :                 args.out_args[0].value = &outarg;
     138                 :            :         }
     139                 :          0 :         ret = fuse_simple_request(fc, &args);
     140                 :          0 :         if (!ret && !size)
     141                 :          0 :                 ret = min_t(ssize_t, outarg.size, XATTR_LIST_MAX);
     142                 :          0 :         if (ret > 0 && size)
     143                 :          0 :                 ret = fuse_verify_xattr_list(list, ret);
     144                 :          0 :         if (ret == -ENOSYS) {
     145                 :          0 :                 fc->no_listxattr = 1;
     146                 :            :                 ret = -EOPNOTSUPP;
     147                 :            :         }
     148                 :          0 :         return ret;
     149                 :            : }
     150                 :            : 
     151                 :          0 : int fuse_removexattr(struct inode *inode, const char *name)
     152                 :            : {
     153                 :            :         struct fuse_conn *fc = get_fuse_conn(inode);
     154                 :          0 :         FUSE_ARGS(args);
     155                 :            :         int err;
     156                 :            : 
     157                 :          0 :         if (fc->no_removexattr)
     158                 :            :                 return -EOPNOTSUPP;
     159                 :            : 
     160                 :          0 :         args.opcode = FUSE_REMOVEXATTR;
     161                 :          0 :         args.nodeid = get_node_id(inode);
     162                 :          0 :         args.in_numargs = 1;
     163                 :          0 :         args.in_args[0].size = strlen(name) + 1;
     164                 :          0 :         args.in_args[0].value = name;
     165                 :          0 :         err = fuse_simple_request(fc, &args);
     166                 :          0 :         if (err == -ENOSYS) {
     167                 :          0 :                 fc->no_removexattr = 1;
     168                 :            :                 err = -EOPNOTSUPP;
     169                 :            :         }
     170                 :          0 :         if (!err) {
     171                 :          0 :                 fuse_invalidate_attr(inode);
     172                 :          0 :                 fuse_update_ctime(inode);
     173                 :            :         }
     174                 :          0 :         return err;
     175                 :            : }
     176                 :            : 
     177                 :          0 : static int fuse_xattr_get(const struct xattr_handler *handler,
     178                 :            :                          struct dentry *dentry, struct inode *inode,
     179                 :            :                          const char *name, void *value, size_t size)
     180                 :            : {
     181                 :          0 :         return fuse_getxattr(inode, name, value, size);
     182                 :            : }
     183                 :            : 
     184                 :          0 : static int fuse_xattr_set(const struct xattr_handler *handler,
     185                 :            :                           struct dentry *dentry, struct inode *inode,
     186                 :            :                           const char *name, const void *value, size_t size,
     187                 :            :                           int flags)
     188                 :            : {
     189                 :          0 :         if (!value)
     190                 :          0 :                 return fuse_removexattr(inode, name);
     191                 :            : 
     192                 :          0 :         return fuse_setxattr(inode, name, value, size, flags);
     193                 :            : }
     194                 :            : 
     195                 :          0 : static bool no_xattr_list(struct dentry *dentry)
     196                 :            : {
     197                 :          0 :         return false;
     198                 :            : }
     199                 :            : 
     200                 :          0 : static int no_xattr_get(const struct xattr_handler *handler,
     201                 :            :                         struct dentry *dentry, struct inode *inode,
     202                 :            :                         const char *name, void *value, size_t size)
     203                 :            : {
     204                 :          0 :         return -EOPNOTSUPP;
     205                 :            : }
     206                 :            : 
     207                 :          0 : static int no_xattr_set(const struct xattr_handler *handler,
     208                 :            :                         struct dentry *dentry, struct inode *nodee,
     209                 :            :                         const char *name, const void *value,
     210                 :            :                         size_t size, int flags)
     211                 :            : {
     212                 :          0 :         return -EOPNOTSUPP;
     213                 :            : }
     214                 :            : 
     215                 :            : static const struct xattr_handler fuse_xattr_handler = {
     216                 :            :         .prefix = "",
     217                 :            :         .get    = fuse_xattr_get,
     218                 :            :         .set    = fuse_xattr_set,
     219                 :            : };
     220                 :            : 
     221                 :            : const struct xattr_handler *fuse_xattr_handlers[] = {
     222                 :            :         &fuse_xattr_handler,
     223                 :            :         NULL
     224                 :            : };
     225                 :            : 
     226                 :            : const struct xattr_handler *fuse_acl_xattr_handlers[] = {
     227                 :            :         &posix_acl_access_xattr_handler,
     228                 :            :         &posix_acl_default_xattr_handler,
     229                 :            :         &fuse_xattr_handler,
     230                 :            :         NULL
     231                 :            : };
     232                 :            : 
     233                 :            : static const struct xattr_handler fuse_no_acl_access_xattr_handler = {
     234                 :            :         .name  = XATTR_NAME_POSIX_ACL_ACCESS,
     235                 :            :         .flags = ACL_TYPE_ACCESS,
     236                 :            :         .list  = no_xattr_list,
     237                 :            :         .get   = no_xattr_get,
     238                 :            :         .set   = no_xattr_set,
     239                 :            : };
     240                 :            : 
     241                 :            : static const struct xattr_handler fuse_no_acl_default_xattr_handler = {
     242                 :            :         .name  = XATTR_NAME_POSIX_ACL_DEFAULT,
     243                 :            :         .flags = ACL_TYPE_ACCESS,
     244                 :            :         .list  = no_xattr_list,
     245                 :            :         .get   = no_xattr_get,
     246                 :            :         .set   = no_xattr_set,
     247                 :            : };
     248                 :            : 
     249                 :            : const struct xattr_handler *fuse_no_acl_xattr_handlers[] = {
     250                 :            :         &fuse_no_acl_access_xattr_handler,
     251                 :            :         &fuse_no_acl_default_xattr_handler,
     252                 :            :         &fuse_xattr_handler,
     253                 :            :         NULL
     254                 :            : };
    

Generated by: LCOV version 1.14