cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

acl.c (3276B)


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