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