+done:
+ return DO_STATUS(errno);
+}
+
+__DEFINE_LXSYSCALL2(int,
+ symlink,
+ const char*,
+ pathname,
+ const char*,
+ link_target)
+{
+ int errno;
+ struct v_dnode* dnode;
+ if ((errno = vfs_walk(__current->cwd, pathname, &dnode, NULL, 0))) {
+ goto done;
+ }
+ if ((dnode->super_block->fs->types & FSTYPE_ROFS)) {
+ errno = EROFS;
+ goto done;
+ }
+ if (!dnode->inode->ops.symlink) {
+ errno = ENOTSUP;
+ goto done;
+ }
+
+ errno = dnode->inode->ops.symlink(dnode->inode, link_target);
+
+done:
+ return DO_STATUS(errno);
+}
+
+int
+__vfs_do_chdir(struct v_dnode* dnode)
+{
+ int errno = 0;
+ if (!(dnode->inode->itype & VFS_IFDIR)) {
+ errno = ENOTDIR;
+ goto done;
+ }
+
+ if (__current->cwd) {
+ __current->cwd->ref_count--;
+ }
+
+ dnode->ref_count++;
+ __current->cwd = dnode;
+
+done:
+ return errno;
+}
+
+__DEFINE_LXSYSCALL1(int, chdir, const char*, path)
+{
+ struct v_dnode* dnode;
+ int errno = 0;
+
+ if ((errno = vfs_walk(__current->cwd, path, &dnode, NULL, 0))) {
+ goto done;
+ }
+
+ errno = __vfs_do_chdir(dnode);
+
+done:
+ return DO_STATUS(errno);
+}
+
+__DEFINE_LXSYSCALL1(int, fchdir, int, fd)
+{
+ struct v_fd* fd_s;
+ int errno = 0;
+
+ if ((errno = __vfs_getfd(fd, &fd_s))) {
+ goto done;
+ }
+
+ errno = __vfs_do_chdir(fd_s->file->dnode);
+
+done: