1 #include <klibc/string.h>
3 #include <lunaix/mm/valloc.h>
4 #include <lunaix/syscall.h>
7 xattr_new(struct hstr* name)
9 struct v_xattr_entry* entry = valloc(sizeof(*entry));
14 (struct v_xattr_entry){ .name = HHSTR(valloc(VFS_NAME_MAXLEN), 0, 0) };
16 hstrcpy(&entry->name, name);
21 xattr_free(struct v_xattr_entry* entry)
23 vfree(entry->name.value);
28 xattr_getcache(struct v_inode* inode, struct hstr* name)
30 struct v_xattr_entry *pos, *n;
31 llist_for_each(pos, n, &inode->xattrs, entries)
33 if (HSTR_EQ(&pos->name, name)) {
42 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr)
44 llist_append(&inode->xattrs, &xattr->entries);
48 xattr_delcache(struct v_inode* inode, struct v_xattr_entry* xattr)
50 llist_delete(&xattr->entries);
54 __vfs_getxattr(struct v_inode* inode,
55 struct v_xattr_entry** xentry,
58 if (!inode->ops->getxattr) {
63 size_t len = strlen(name);
65 if (len > VFS_NAME_MAXLEN) {
69 struct hstr hname = HSTR(name, len);
71 hstr_rehash(&hname, HSTR_FULL_HASH);
73 struct v_xattr_entry* entry = xattr_getcache(inode, &hname);
75 if (!(entry = xattr_new(&hname))) {
80 if (!(errno = inode->ops->getxattr(inode, entry))) {
82 xattr_addcache(inode, entry);
90 __vfs_setxattr(struct v_inode* inode,
95 if (!inode->ops->setxattr || !inode->ops->delxattr) {
100 size_t slen = strlen(name);
102 if (slen > VFS_NAME_MAXLEN) {
106 struct hstr hname = HSTR(name, slen);
108 hstr_rehash(&hname, HSTR_FULL_HASH);
110 struct v_xattr_entry* entry = xattr_getcache(inode, &hname);
112 if (!(entry = xattr_new(&hname))) {
116 xattr_delcache(inode, entry);
119 if ((errno = inode->ops->delxattr(inode, entry))) {
127 if ((errno = inode->ops->setxattr(inode, entry))) {
132 xattr_addcache(inode, entry);
137 __DEFINE_LXSYSCALL4(int,
148 struct v_dnode* dnode;
149 struct v_xattr_entry* xattr;
152 if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) {
156 if ((errno = __vfs_getxattr(dnode->inode, &xattr, name))) {
160 if (len < xattr->len) {
165 memcpy(value, xattr->value, len);
168 return DO_STATUS(errno);
171 __DEFINE_LXSYSCALL4(int,
182 struct v_dnode* dnode;
183 struct v_xattr_entry* xattr;
186 if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) {
190 if ((errno = __vfs_setxattr(dnode->inode, name, value, len))) {
195 return DO_STATUS(errno);
198 __DEFINE_LXSYSCALL4(int,
210 struct v_xattr_entry* xattr;
213 if ((errno = vfs_getfd(fd, &fd_s))) {
217 if ((errno = __vfs_getxattr(fd_s->file->inode, &xattr, name))) {
221 if (len < xattr->len) {
226 memcpy(value, xattr->value, len);
229 return DO_STATUS(errno);
232 __DEFINE_LXSYSCALL4(int,
244 struct v_xattr_entry* xattr;
247 if ((errno = vfs_getfd(fd, &fd_s))) {
251 if ((errno = __vfs_setxattr(fd_s->file->inode, name, value, len))) {
256 return DO_STATUS(errno);