1 #include <klibc/string.h>
3 #include <lunaix/mm/valloc.h>
4 #include <lunaix/process.h>
5 #include <lunaix/syscall.h>
6 #include <lunaix/syscall_utils.h>
8 #define DO_STATUS(errno) SYSCALL_ESTATUS(__current->k_status = errno)
11 xattr_new(struct hstr* name)
13 struct v_xattr_entry* entry = valloc(sizeof(*entry));
18 (struct v_xattr_entry){ .name = HHSTR(valloc(VFS_NAME_MAXLEN), 0, 0),
21 hstrcpy(&entry->name, name);
26 xattr_free(struct v_xattr_entry* entry)
28 vfree((void*)entry->name.value);
33 xattr_getcache(struct v_inode* inode, struct hstr* name)
35 struct v_xattr_entry *pos, *n;
36 llist_for_each(pos, n, &inode->xattrs, entries)
38 if (HSTR_EQ(&pos->name, name)) {
47 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr)
49 llist_append(&inode->xattrs, &xattr->entries);
53 xattr_delcache(struct v_inode* inode, struct v_xattr_entry* xattr)
55 llist_delete(&xattr->entries);
59 __vfs_getxattr(struct v_inode* inode,
60 struct v_xattr_entry** xentry,
63 if (!inode->ops->getxattr) {
68 size_t len = strlen(name);
70 if (len > VFS_NAME_MAXLEN) {
74 struct hstr hname = HSTR(name, len);
76 hstr_rehash(&hname, HSTR_FULL_HASH);
78 struct v_xattr_entry* entry = xattr_getcache(inode, &hname);
80 if (!(entry = xattr_new(&hname))) {
85 if (!(errno = inode->ops->getxattr(inode, entry))) {
87 xattr_addcache(inode, entry);
95 __vfs_setxattr(struct v_inode* inode,
100 if (!inode->ops->setxattr || !inode->ops->delxattr) {
105 size_t slen = strlen(name);
107 if (slen > VFS_NAME_MAXLEN) {
111 struct hstr hname = HSTR(name, slen);
113 hstr_rehash(&hname, HSTR_FULL_HASH);
115 struct v_xattr_entry* entry = xattr_getcache(inode, &hname);
117 if (!(entry = xattr_new(&hname))) {
121 xattr_delcache(inode, entry);
124 if ((errno = inode->ops->delxattr(inode, entry))) {
132 if ((errno = inode->ops->setxattr(inode, entry))) {
137 xattr_addcache(inode, entry);
142 __DEFINE_LXSYSCALL4(int,
153 struct v_dnode* dnode;
154 struct v_xattr_entry* xattr;
157 if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) {
161 if ((errno = __vfs_getxattr(dnode->inode, &xattr, name))) {
165 if (len < xattr->len) {
170 memcpy(value, xattr->value, len);
173 return DO_STATUS(errno);
176 __DEFINE_LXSYSCALL4(int,
187 struct v_dnode* dnode;
188 struct v_xattr_entry* xattr;
191 if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) {
195 if ((errno = __vfs_setxattr(dnode->inode, name, value, len))) {
200 return DO_STATUS(errno);
203 __DEFINE_LXSYSCALL4(int,
215 struct v_xattr_entry* xattr;
218 if ((errno = vfs_getfd(fd, &fd_s))) {
222 if ((errno = __vfs_getxattr(fd_s->file->inode, &xattr, name))) {
226 if (len < xattr->len) {
231 memcpy(value, xattr->value, len);
234 return DO_STATUS(errno);
237 __DEFINE_LXSYSCALL4(int,
249 struct v_xattr_entry* xattr;
252 if ((errno = vfs_getfd(fd, &fd_s))) {
256 if ((errno = __vfs_setxattr(fd_s->file->inode, name, value, len))) {
261 return DO_STATUS(errno);