LCOV - code coverage report
Current view: top level - fs/btrfs - acl.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 0 58 0.0 %
Date: 2023-07-31 20:08:27 Functions: 0 3 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (C) 2007 Red Hat.  All rights reserved.
       4             :  */
       5             : 
       6             : #include <linux/fs.h>
       7             : #include <linux/string.h>
       8             : #include <linux/xattr.h>
       9             : #include <linux/posix_acl_xattr.h>
      10             : #include <linux/posix_acl.h>
      11             : #include <linux/sched.h>
      12             : #include <linux/sched/mm.h>
      13             : #include <linux/slab.h>
      14             : #include "ctree.h"
      15             : #include "btrfs_inode.h"
      16             : #include "xattr.h"
      17             : #include "acl.h"
      18             : 
      19           0 : struct posix_acl *btrfs_get_acl(struct inode *inode, int type, bool rcu)
      20             : {
      21           0 :         int size;
      22           0 :         const char *name;
      23           0 :         char *value = NULL;
      24           0 :         struct posix_acl *acl;
      25             : 
      26           0 :         if (rcu)
      27             :                 return ERR_PTR(-ECHILD);
      28             : 
      29           0 :         switch (type) {
      30             :         case ACL_TYPE_ACCESS:
      31             :                 name = XATTR_NAME_POSIX_ACL_ACCESS;
      32             :                 break;
      33           0 :         case ACL_TYPE_DEFAULT:
      34           0 :                 name = XATTR_NAME_POSIX_ACL_DEFAULT;
      35           0 :                 break;
      36             :         default:
      37             :                 return ERR_PTR(-EINVAL);
      38             :         }
      39             : 
      40           0 :         size = btrfs_getxattr(inode, name, NULL, 0);
      41           0 :         if (size > 0) {
      42           0 :                 value = kzalloc(size, GFP_KERNEL);
      43           0 :                 if (!value)
      44             :                         return ERR_PTR(-ENOMEM);
      45           0 :                 size = btrfs_getxattr(inode, name, value, size);
      46             :         }
      47           0 :         if (size > 0)
      48           0 :                 acl = posix_acl_from_xattr(&init_user_ns, value, size);
      49           0 :         else if (size == -ENODATA || size == 0)
      50             :                 acl = NULL;
      51             :         else
      52           0 :                 acl = ERR_PTR(size);
      53           0 :         kfree(value);
      54             : 
      55           0 :         return acl;
      56             : }
      57             : 
      58           0 : int __btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode,
      59             :                     struct posix_acl *acl, int type)
      60             : {
      61           0 :         int ret, size = 0;
      62           0 :         const char *name;
      63           0 :         char *value = NULL;
      64             : 
      65           0 :         switch (type) {
      66             :         case ACL_TYPE_ACCESS:
      67             :                 name = XATTR_NAME_POSIX_ACL_ACCESS;
      68             :                 break;
      69           0 :         case ACL_TYPE_DEFAULT:
      70           0 :                 if (!S_ISDIR(inode->i_mode))
      71           0 :                         return acl ? -EINVAL : 0;
      72             :                 name = XATTR_NAME_POSIX_ACL_DEFAULT;
      73             :                 break;
      74             :         default:
      75             :                 return -EINVAL;
      76             :         }
      77             : 
      78           0 :         if (acl) {
      79           0 :                 unsigned int nofs_flag;
      80             : 
      81           0 :                 size = posix_acl_xattr_size(acl->a_count);
      82             :                 /*
      83             :                  * We're holding a transaction handle, so use a NOFS memory
      84             :                  * allocation context to avoid deadlock if reclaim happens.
      85             :                  */
      86           0 :                 nofs_flag = memalloc_nofs_save();
      87           0 :                 value = kmalloc(size, GFP_KERNEL);
      88           0 :                 memalloc_nofs_restore(nofs_flag);
      89           0 :                 if (!value) {
      90           0 :                         ret = -ENOMEM;
      91           0 :                         goto out;
      92             :                 }
      93             : 
      94           0 :                 ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
      95           0 :                 if (ret < 0)
      96           0 :                         goto out;
      97             :         }
      98             : 
      99           0 :         if (trans)
     100           0 :                 ret = btrfs_setxattr(trans, inode, name, value, size, 0);
     101             :         else
     102           0 :                 ret = btrfs_setxattr_trans(inode, name, value, size, 0);
     103             : 
     104           0 : out:
     105           0 :         kfree(value);
     106             : 
     107           0 :         if (!ret)
     108           0 :                 set_cached_acl(inode, type, acl);
     109             : 
     110             :         return ret;
     111             : }
     112             : 
     113           0 : int btrfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
     114             :                   struct posix_acl *acl, int type)
     115             : {
     116           0 :         int ret;
     117           0 :         struct inode *inode = d_inode(dentry);
     118           0 :         umode_t old_mode = inode->i_mode;
     119             : 
     120           0 :         if (type == ACL_TYPE_ACCESS && acl) {
     121           0 :                 ret = posix_acl_update_mode(idmap, inode,
     122             :                                             &inode->i_mode, &acl);
     123           0 :                 if (ret)
     124             :                         return ret;
     125             :         }
     126           0 :         ret = __btrfs_set_acl(NULL, inode, acl, type);
     127           0 :         if (ret)
     128           0 :                 inode->i_mode = old_mode;
     129             :         return ret;
     130             : }

Generated by: LCOV version 1.14