162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#include <linux/init.h>
362306a36Sopenharmony_ci#include <linux/posix_acl.h>
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#define REISERFS_ACL_VERSION	0x0001
662306a36Sopenharmony_ci
762306a36Sopenharmony_citypedef struct {
862306a36Sopenharmony_ci	__le16 e_tag;
962306a36Sopenharmony_ci	__le16 e_perm;
1062306a36Sopenharmony_ci	__le32 e_id;
1162306a36Sopenharmony_ci} reiserfs_acl_entry;
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_citypedef struct {
1462306a36Sopenharmony_ci	__le16 e_tag;
1562306a36Sopenharmony_ci	__le16 e_perm;
1662306a36Sopenharmony_ci} reiserfs_acl_entry_short;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_citypedef struct {
1962306a36Sopenharmony_ci	__le32 a_version;
2062306a36Sopenharmony_ci} reiserfs_acl_header;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic inline size_t reiserfs_acl_size(int count)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	if (count <= 4) {
2562306a36Sopenharmony_ci		return sizeof(reiserfs_acl_header) +
2662306a36Sopenharmony_ci		    count * sizeof(reiserfs_acl_entry_short);
2762306a36Sopenharmony_ci	} else {
2862306a36Sopenharmony_ci		return sizeof(reiserfs_acl_header) +
2962306a36Sopenharmony_ci		    4 * sizeof(reiserfs_acl_entry_short) +
3062306a36Sopenharmony_ci		    (count - 4) * sizeof(reiserfs_acl_entry);
3162306a36Sopenharmony_ci	}
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic inline int reiserfs_acl_count(size_t size)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	ssize_t s;
3762306a36Sopenharmony_ci	size -= sizeof(reiserfs_acl_header);
3862306a36Sopenharmony_ci	s = size - 4 * sizeof(reiserfs_acl_entry_short);
3962306a36Sopenharmony_ci	if (s < 0) {
4062306a36Sopenharmony_ci		if (size % sizeof(reiserfs_acl_entry_short))
4162306a36Sopenharmony_ci			return -1;
4262306a36Sopenharmony_ci		return size / sizeof(reiserfs_acl_entry_short);
4362306a36Sopenharmony_ci	} else {
4462306a36Sopenharmony_ci		if (s % sizeof(reiserfs_acl_entry))
4562306a36Sopenharmony_ci			return -1;
4662306a36Sopenharmony_ci		return s / sizeof(reiserfs_acl_entry) + 4;
4762306a36Sopenharmony_ci	}
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#ifdef CONFIG_REISERFS_FS_POSIX_ACL
5162306a36Sopenharmony_cistruct posix_acl *reiserfs_get_acl(struct inode *inode, int type, bool rcu);
5262306a36Sopenharmony_ciint reiserfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
5362306a36Sopenharmony_ci		     struct posix_acl *acl, int type);
5462306a36Sopenharmony_ciint reiserfs_acl_chmod(struct dentry *dentry);
5562306a36Sopenharmony_ciint reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
5662306a36Sopenharmony_ci				 struct inode *dir, struct dentry *dentry,
5762306a36Sopenharmony_ci				 struct inode *inode);
5862306a36Sopenharmony_ciint reiserfs_cache_default_acl(struct inode *dir);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#else
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define reiserfs_cache_default_acl(inode) 0
6362306a36Sopenharmony_ci#define reiserfs_get_acl NULL
6462306a36Sopenharmony_ci#define reiserfs_set_acl NULL
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic inline int reiserfs_acl_chmod(struct dentry *dentry)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	return 0;
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic inline int
7262306a36Sopenharmony_cireiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
7362306a36Sopenharmony_ci			     const struct inode *dir, struct dentry *dentry,
7462306a36Sopenharmony_ci			     struct inode *inode)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	return 0;
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci#endif
79