1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) International Business Machines Corp., 2002-2004
4 * Copyright (C) Andreas Gruenbacher, 2001
5 * Copyright (C) Linus Torvalds, 1991, 1992
8 #include <linux/sched.h>
9 #include <linux/slab.h>
11 #include <linux/posix_acl_xattr.h>
12 #include "jfs_incore.h"
13 #include "jfs_txnmgr.h"
14 #include "jfs_xattr.h"
17 struct posix_acl
*jfs_get_acl(struct inode
*inode
, int type
, bool rcu
)
19 struct posix_acl
*acl
;
25 return ERR_PTR(-ECHILD
);
29 ea_name
= XATTR_NAME_POSIX_ACL_ACCESS
;
31 case ACL_TYPE_DEFAULT
:
32 ea_name
= XATTR_NAME_POSIX_ACL_DEFAULT
;
35 return ERR_PTR(-EINVAL
);
38 size
= __jfs_getxattr(inode
, ea_name
, NULL
, 0);
41 value
= kmalloc(size
, GFP_KERNEL
);
43 return ERR_PTR(-ENOMEM
);
44 size
= __jfs_getxattr(inode
, ea_name
, value
, size
);
53 acl
= posix_acl_from_xattr(&init_user_ns
, value
, size
);
59 static int __jfs_set_acl(tid_t tid
, struct inode
*inode
, int type
,
60 struct posix_acl
*acl
)
69 ea_name
= XATTR_NAME_POSIX_ACL_ACCESS
;
71 case ACL_TYPE_DEFAULT
:
72 ea_name
= XATTR_NAME_POSIX_ACL_DEFAULT
;
79 size
= posix_acl_xattr_size(acl
->a_count
);
80 value
= kmalloc(size
, GFP_KERNEL
);
83 rc
= posix_acl_to_xattr(&init_user_ns
, acl
, value
, size
);
87 rc
= __jfs_setxattr(tid
, inode
, ea_name
, value
, size
, 0);
92 set_cached_acl(inode
, type
, acl
);
97 int jfs_set_acl(struct mnt_idmap
*idmap
, struct dentry
*dentry
,
98 struct posix_acl
*acl
, int type
)
103 struct inode
*inode
= d_inode(dentry
);
104 umode_t mode
= inode
->i_mode
;
106 tid
= txBegin(inode
->i_sb
, 0);
107 mutex_lock(&JFS_IP(inode
)->commit_mutex
);
108 if (type
== ACL_TYPE_ACCESS
&& acl
) {
109 rc
= posix_acl_update_mode(&nop_mnt_idmap
, inode
, &mode
, &acl
);
112 if (mode
!= inode
->i_mode
)
115 rc
= __jfs_set_acl(tid
, inode
, type
, acl
);
118 inode
->i_mode
= mode
;
119 inode_set_ctime_current(inode
);
120 mark_inode_dirty(inode
);
122 rc
= txCommit(tid
, 1, &inode
, 0);
126 mutex_unlock(&JFS_IP(inode
)->commit_mutex
);
130 int jfs_init_acl(tid_t tid
, struct inode
*inode
, struct inode
*dir
)
132 struct posix_acl
*default_acl
, *acl
;
135 rc
= posix_acl_create(dir
, &inode
->i_mode
, &default_acl
, &acl
);
140 rc
= __jfs_set_acl(tid
, inode
, ACL_TYPE_DEFAULT
, default_acl
);
141 posix_acl_release(default_acl
);
143 inode
->i_default_acl
= NULL
;
148 rc
= __jfs_set_acl(tid
, inode
, ACL_TYPE_ACCESS
, acl
);
149 posix_acl_release(acl
);
154 JFS_IP(inode
)->mode2
= (JFS_IP(inode
)->mode2
& 0xffff0000) |