root/fs/gfs2/acl.c

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

DEFINITIONS

This source file includes following definitions.
  1. gfs2_acl_name
  2. __gfs2_get_acl
  3. gfs2_get_acl
  4. __gfs2_set_acl
  5. gfs2_set_acl

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
   4  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
   5  */
   6 
   7 #include <linux/sched.h>
   8 #include <linux/slab.h>
   9 #include <linux/spinlock.h>
  10 #include <linux/completion.h>
  11 #include <linux/buffer_head.h>
  12 #include <linux/xattr.h>
  13 #include <linux/posix_acl.h>
  14 #include <linux/posix_acl_xattr.h>
  15 #include <linux/gfs2_ondisk.h>
  16 
  17 #include "gfs2.h"
  18 #include "incore.h"
  19 #include "acl.h"
  20 #include "xattr.h"
  21 #include "glock.h"
  22 #include "inode.h"
  23 #include "meta_io.h"
  24 #include "rgrp.h"
  25 #include "trans.h"
  26 #include "util.h"
  27 
  28 static const char *gfs2_acl_name(int type)
  29 {
  30         switch (type) {
  31         case ACL_TYPE_ACCESS:
  32                 return XATTR_POSIX_ACL_ACCESS;
  33         case ACL_TYPE_DEFAULT:
  34                 return XATTR_POSIX_ACL_DEFAULT;
  35         }
  36         return NULL;
  37 }
  38 
  39 static struct posix_acl *__gfs2_get_acl(struct inode *inode, int type)
  40 {
  41         struct gfs2_inode *ip = GFS2_I(inode);
  42         struct posix_acl *acl;
  43         const char *name;
  44         char *data;
  45         int len;
  46 
  47         if (!ip->i_eattr)
  48                 return NULL;
  49 
  50         name = gfs2_acl_name(type);
  51         len = gfs2_xattr_acl_get(ip, name, &data);
  52         if (len <= 0)
  53                 return ERR_PTR(len);
  54         acl = posix_acl_from_xattr(&init_user_ns, data, len);
  55         kfree(data);
  56         return acl;
  57 }
  58 
  59 struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
  60 {
  61         struct gfs2_inode *ip = GFS2_I(inode);
  62         struct gfs2_holder gh;
  63         bool need_unlock = false;
  64         struct posix_acl *acl;
  65 
  66         if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
  67                 int ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
  68                                              LM_FLAG_ANY, &gh);
  69                 if (ret)
  70                         return ERR_PTR(ret);
  71                 need_unlock = true;
  72         }
  73         acl = __gfs2_get_acl(inode, type);
  74         if (need_unlock)
  75                 gfs2_glock_dq_uninit(&gh);
  76         return acl;
  77 }
  78 
  79 int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
  80 {
  81         int error;
  82         size_t len;
  83         char *data;
  84         const char *name = gfs2_acl_name(type);
  85 
  86         if (acl) {
  87                 len = posix_acl_xattr_size(acl->a_count);
  88                 data = kmalloc(len, GFP_NOFS);
  89                 if (data == NULL)
  90                         return -ENOMEM;
  91                 error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
  92                 if (error < 0)
  93                         goto out;
  94         } else {
  95                 data = NULL;
  96                 len = 0;
  97         }
  98 
  99         error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
 100         if (error)
 101                 goto out;
 102         set_cached_acl(inode, type, acl);
 103 out:
 104         kfree(data);
 105         return error;
 106 }
 107 
 108 int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 109 {
 110         struct gfs2_inode *ip = GFS2_I(inode);
 111         struct gfs2_holder gh;
 112         bool need_unlock = false;
 113         int ret;
 114         umode_t mode;
 115 
 116         if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode)))
 117                 return -E2BIG;
 118 
 119         ret = gfs2_rsqa_alloc(ip);
 120         if (ret)
 121                 return ret;
 122 
 123         if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
 124                 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
 125                 if (ret)
 126                         return ret;
 127                 need_unlock = true;
 128         }
 129 
 130         mode = inode->i_mode;
 131         if (type == ACL_TYPE_ACCESS && acl) {
 132                 ret = posix_acl_update_mode(inode, &mode, &acl);
 133                 if (ret)
 134                         goto unlock;
 135         }
 136 
 137         ret = __gfs2_set_acl(inode, acl, type);
 138         if (!ret && mode != inode->i_mode) {
 139                 inode->i_ctime = current_time(inode);
 140                 inode->i_mode = mode;
 141                 mark_inode_dirty(inode);
 142         }
 143 unlock:
 144         if (need_unlock)
 145                 gfs2_glock_dq_uninit(&gh);
 146         return ret;
 147 }

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