^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) International Business Machines Corp., 2002-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) Andreas Gruenbacher, 2001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) Linus Torvalds, 1991, 1992
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/posix_acl_xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "jfs_incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "jfs_txnmgr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "jfs_xattr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "jfs_acl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct posix_acl *jfs_get_acl(struct inode *inode, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct posix_acl *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) char *ea_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) char *value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) switch(type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) case ACL_TYPE_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) case ACL_TYPE_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ea_name = XATTR_NAME_POSIX_ACL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) size = __jfs_getxattr(inode, ea_name, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) value = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) size = __jfs_getxattr(inode, ea_name, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (size == -ENODATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) acl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) acl = ERR_PTR(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) acl = posix_acl_from_xattr(&init_user_ns, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) kfree(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct posix_acl *acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) char *ea_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) char *value = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case ACL_TYPE_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case ACL_TYPE_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ea_name = XATTR_NAME_POSIX_ACL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) size = posix_acl_xattr_size(acl->a_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) value = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) rc = posix_acl_to_xattr(&init_user_ns, acl, value, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) kfree(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) set_cached_acl(inode, type, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) tid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int update_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) umode_t mode = inode->i_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) tid = txBegin(inode->i_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mutex_lock(&JFS_IP(inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (type == ACL_TYPE_ACCESS && acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) rc = posix_acl_update_mode(inode, &mode, &acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto end_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (mode != inode->i_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) update_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) rc = __jfs_set_acl(tid, inode, type, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (update_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) inode->i_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) rc = txCommit(tid, 1, &inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) end_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) txEnd(tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mutex_unlock(&JFS_IP(inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct posix_acl *default_acl, *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) rc = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (default_acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rc = __jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, default_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) posix_acl_release(default_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) inode->i_default_acl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (acl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) rc = __jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) posix_acl_release(acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) inode->i_acl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) inode->i_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }