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) };
20 hstrcpy(&entry->name, name);
25 xattr_free(struct v_xattr_entry* entry)
27 vfree(entry->name.value);
32 xattr_getcache(struct v_inode* inode, struct hstr* name)
34 struct v_xattr_entry *pos, *n;
35 llist_for_each(pos, n, &inode->xattrs, entries)
37 if (HSTR_EQ(&pos->name, name)) {
46 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr)
48 llist_append(&inode->xattrs, &xattr->entries);
52 xattr_delcache(struct v_inode* inode, struct v_xattr_entry* xattr)
54 llist_delete(&xattr->entries);
58 __vfs_getxattr(struct v_inode* inode,
59 struct v_xattr_entry** xentry,
62 if (!inode->ops->getxattr) {
67 size_t len = strlen(name);
69 if (len > VFS_NAME_MAXLEN) {
73 struct hstr hname = HSTR(name, len);
75 hstr_rehash(&hname, HSTR_FULL_HASH);
77 struct v_xattr_entry* entry = xattr_getcache(inode, &hname);
79 if (!(entry = xattr_new(&hname))) {
84 if (!(errno = inode->ops->getxattr(inode, entry))) {
86 xattr_addcache(inode, entry);
94 __vfs_setxattr(struct v_inode* inode,
99 if (!inode->ops->setxattr || !inode->ops->delxattr) {
104 size_t slen = strlen(name);
106 if (slen > VFS_NAME_MAXLEN) {
110 struct hstr hname = HSTR(name, slen);
112 hstr_rehash(&hname, HSTR_FULL_HASH);
114 struct v_xattr_entry* entry = xattr_getcache(inode, &hname);
116 if (!(entry = xattr_new(&hname))) {
120 xattr_delcache(inode, entry);
123 if ((errno = inode->ops->delxattr(inode, entry))) {
131 if ((errno = inode->ops->setxattr(inode, entry))) {
136 xattr_addcache(inode, entry);
141 __DEFINE_LXSYSCALL4(int,
152 struct v_dnode* dnode;
153 struct v_xattr_entry* xattr;
156 if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) {
160 if ((errno = __vfs_getxattr(dnode->inode, &xattr, name))) {
164 if (len < xattr->len) {
169 memcpy(value, xattr->value, len);
172 return DO_STATUS(errno);
175 __DEFINE_LXSYSCALL4(int,
186 struct v_dnode* dnode;
187 struct v_xattr_entry* xattr;
190 if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) {
194 if ((errno = __vfs_setxattr(dnode->inode, name, value, len))) {
199 return DO_STATUS(errno);
202 __DEFINE_LXSYSCALL4(int,
214 struct v_xattr_entry* xattr;
217 if ((errno = vfs_getfd(fd, &fd_s))) {
221 if ((errno = __vfs_getxattr(fd_s->file->inode, &xattr, name))) {
225 if (len < xattr->len) {
230 memcpy(value, xattr->value, len);
233 return DO_STATUS(errno);
236 __DEFINE_LXSYSCALL4(int,
248 struct v_xattr_entry* xattr;
251 if ((errno = vfs_getfd(fd, &fd_s))) {
255 if ((errno = __vfs_setxattr(fd_s->file->inode, name, value, len))) {
260 return DO_STATUS(errno);