+#define VFS_MAX_SYMLINK 16
+
+int
+vfs_walk(struct v_dnode* start,
+ const char* path,
+ struct v_dnode** dentry,
+ struct hstr* component,
+ int options)
+{
+ struct v_dnode* interim;
+ char* pathname = path;
+ int errno = __vfs_walk(start, path, &interim, component, options);
+ int counter = 0;
+
+ while (!errno) {
+ if (counter >= VFS_MAX_SYMLINK) {
+ errno = ELOOP;
+ continue;
+ }
+ if ((interim->inode->itype & VFS_IFSYMLINK) &&
+ !(options & VFS_WALK_NOFOLLOW) &&
+ interim->inode->ops.read_symlink) {
+ errno = interim->inode->ops.read_symlink(interim->inode, &pathname);
+ if (errno) {
+ break;
+ }
+ } else {
+ break;
+ }
+ errno = __vfs_walk(start, pathname, &interim, component, options);
+ counter++;
+ }
+
+ *dentry = errno ? 0 : interim;
+
+ return errno;
+}
+