1 // SPDX-License-Identifier: GPL-2.0
3 * linux/fs/hfsplus/posix_acl.c
5 * Vyacheslav Dubeyko <slava@dubeyko.com>
7 * Handler for Posix Access Control Lists (ACLs) support.
10 #include "hfsplus_fs.h"
14 struct posix_acl
*hfsplus_get_posix_acl(struct inode
*inode
, int type
)
16 struct posix_acl
*acl
;
21 hfs_dbg(ACL_MOD
, "[%s]: ino %lu\n", __func__
, inode
->i_ino
);
25 xattr_name
= XATTR_NAME_POSIX_ACL_ACCESS
;
27 case ACL_TYPE_DEFAULT
:
28 xattr_name
= XATTR_NAME_POSIX_ACL_DEFAULT
;
31 return ERR_PTR(-EINVAL
);
34 size
= __hfsplus_getxattr(inode
, xattr_name
, NULL
, 0);
37 value
= (char *)hfsplus_alloc_attr_entry();
39 return ERR_PTR(-ENOMEM
);
40 size
= __hfsplus_getxattr(inode
, xattr_name
, value
, size
);
44 acl
= posix_acl_from_xattr(&init_user_ns
, value
, size
);
45 else if (size
== -ENODATA
)
50 hfsplus_destroy_attr_entry((hfsplus_attr_entry
*)value
);
55 static int __hfsplus_set_posix_acl(struct inode
*inode
, struct posix_acl
*acl
,
63 hfs_dbg(ACL_MOD
, "[%s]: ino %lu\n", __func__
, inode
->i_ino
);
67 xattr_name
= XATTR_NAME_POSIX_ACL_ACCESS
;
70 case ACL_TYPE_DEFAULT
:
71 xattr_name
= XATTR_NAME_POSIX_ACL_DEFAULT
;
72 if (!S_ISDIR(inode
->i_mode
))
73 return acl
? -EACCES
: 0;
81 size
= posix_acl_xattr_size(acl
->a_count
);
82 if (unlikely(size
> HFSPLUS_MAX_INLINE_DATA_SIZE
))
84 value
= (char *)hfsplus_alloc_attr_entry();
87 err
= posix_acl_to_xattr(&init_user_ns
, acl
, value
, size
);
88 if (unlikely(err
< 0))
92 err
= __hfsplus_setxattr(inode
, xattr_name
, value
, size
, 0);
95 hfsplus_destroy_attr_entry((hfsplus_attr_entry
*)value
);
98 set_cached_acl(inode
, type
, acl
);
103 int hfsplus_set_posix_acl(struct inode
*inode
, struct posix_acl
*acl
, int type
)
107 if (type
== ACL_TYPE_ACCESS
&& acl
) {
108 err
= posix_acl_update_mode(inode
, &inode
->i_mode
, &acl
);
112 return __hfsplus_set_posix_acl(inode
, acl
, type
);
115 int hfsplus_init_posix_acl(struct inode
*inode
, struct inode
*dir
)
118 struct posix_acl
*default_acl
, *acl
;
121 "[%s]: ino %lu, dir->ino %lu\n",
122 __func__
, inode
->i_ino
, dir
->i_ino
);
124 if (S_ISLNK(inode
->i_mode
))
127 err
= posix_acl_create(dir
, &inode
->i_mode
, &default_acl
, &acl
);
132 err
= __hfsplus_set_posix_acl(inode
, default_acl
,
134 posix_acl_release(default_acl
);
139 err
= __hfsplus_set_posix_acl(inode
, acl
,
141 posix_acl_release(acl
);