#include <lunaix/fs.h>
#include <lunaix/mm/valloc.h>
+#include <lunaix/process.h>
#include <lunaix/spike.h>
#include <klibc/string.h>
assert(start);
struct v_dnode* dnode;
- struct v_inode* current_inode;
struct v_dnode* current_level = start;
+ struct v_inode* current_inode = current_level->inode;
struct hstr name = HSTR(fname_buffer, 0);
if (!lookahead && (walk_options & VFS_WALK_PARENT)) {
if (component) {
- component->hash = name.hash;
- component->len = j;
- strcpy(component->value, fname_buffer);
+ hstrcpy(component, &name);
}
break;
}
- current_inode = current_level->inode;
-
- if ((current_inode->itype & VFS_IFSYMLINK) &&
- !(walk_options & VFS_WALK_NOFOLLOW)) {
- const char* link;
-
- lock_inode(current_inode);
- if ((errno =
- current_inode->ops->read_symlink(current_inode, &link))) {
- unlock_inode(current_inode);
- goto error;
- }
- unlock_inode(current_inode);
-
- errno = __vfs_walk(current_level->parent,
- link,
- &dnode,
- NULL,
- 0,
- depth + 1,
- fname_buffer + name.len + 1);
-
- if (errno) {
- goto error;
- }
-
- // reposition the resolved subtree pointed by symlink
- vfs_dcache_rehash(current_level->parent, dnode);
- current_level = dnode;
- current_inode = dnode->inode;
- }
-
lock_dnode(current_level);
dnode = vfs_dcache_lookup(current_level, &name);
j = 0;
current_level = dnode;
+ current_inode = current_level->inode;
+
+ if ((current_inode->itype & VFS_IFSYMLINK) &&
+ !(walk_options & VFS_WALK_NOFOLLOW)) {
+ const char* link;
+
+ if (!current_inode->ops->read_symlink) {
+ errno = ENOTSUP;
+ goto error;
+ }
+
+ lock_inode(current_inode);
+ if ((errno =
+ current_inode->ops->read_symlink(current_inode, &link))) {
+ unlock_inode(current_inode);
+ goto error;
+ }
+ unlock_inode(current_inode);
+
+ errno = __vfs_walk(current_level->parent,
+ link,
+ &dnode,
+ NULL,
+ 0,
+ depth + 1,
+ fname_buffer + name.len + 1);
+
+ if (errno) {
+ goto error;
+ }
+
+ current_level = dnode;
+ current_inode = dnode->inode;
+ }
+
cont:
current = lookahead;
};