// File: /workspace/github_c_makefile_star2_O0/krinkinmu[P]64bit/vfs.c
// Function: vfs_link
int vfs_link(const char *oldname, const char *newname)
{
	int rc;
	struct fs_entry *oldentry = vfs_resolve_path(oldname, &rc);

	if (!oldentry)
		return rc;

	struct vfs_walk_data wd;

	vfs_walk_start(&wd, newname);
	rc = vfs_walk_parent(&wd);
	if (rc) {
		vfs_walk_stop(&wd);
		vfs_entry_put(oldentry);
		return rc;
	}

	struct fs_entry *dir = wd.entry;
	struct fs_node *node = dir->node;

	if (!node->ops->lookup || !node->ops->link) {
		vfs_walk_stop(&wd);
		vfs_entry_put(oldentry);
		return -ENOTSUP;
	}
	
	mutex_lock(&node->mux);
	struct fs_entry *newentry = vfs_lookup(dir, wd.next, true, &rc);

	if (!newentry) {
		mutex_unlock(&node->mux);
		vfs_walk_stop(&wd);
		vfs_entry_put(oldentry);
		return rc;
	}

	if (newentry->node) {
		mutex_unlock(&node->mux);
		vfs_walk_stop(&wd);
		vfs_entry_put(oldentry);
		vfs_entry_put(newentry);
		return -EEXIST;
	}

	rc = node->ops->link(oldentry, node, newentry);
	mutex_unlock(&node->mux);
	vfs_walk_stop(&wd);
	vfs_entry_put(oldentry);
	vfs_entry_put(newentry);
	return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
callq 0xffffffff8010a100
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0xffffffff80109f36
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff8010a0e6
movq -0x18(%rbp), %rsi
leaq -0x138(%rbp), %rdi
callq 0xffffffff8010a1a0
leaq -0x138(%rbp), %rdi
callq 0xffffffff8010a200
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0xffffffff80109f7b
leaq -0x138(%rbp), %rdi
callq 0xffffffff8010a260
movq -0x28(%rbp), %rdi
callq 0xffffffff80109680
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff8010a0e6
movq -0x138(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x148(%rbp)
movq -0x148(%rbp), %rax
movq 0x20(%rax), %rax
cmpq $0x0, 0x28(%rax)
je 0xffffffff80109fbf
movq -0x148(%rbp), %rax
movq 0x20(%rax), %rax
cmpq $0x0, 0x8(%rax)
jne 0xffffffff80109fe0
leaq -0x138(%rbp), %rdi
callq 0xffffffff8010a260
movq -0x28(%rbp), %rdi
callq 0xffffffff80109680
movl $0xfffffffd, -0x4(%rbp) # imm = 0xFFFFFFFD
jmp 0xffffffff8010a0e6
movq -0x148(%rbp), %rdi
callq 0xffffffff8010dff0
movq -0x140(%rbp), %rdi
leaq -0x138(%rbp), %rsi
addq $0x8, %rsi
movl $0x1, %edx
leaq -0x1c(%rbp), %rcx
callq 0xffffffff8010a290
movq %rax, -0x150(%rbp)
cmpq $0x0, -0x150(%rbp)
jne 0xffffffff8010a049
movq -0x148(%rbp), %rdi
callq 0xffffffff8010e140
leaq -0x138(%rbp), %rdi
callq 0xffffffff8010a260
movq -0x28(%rbp), %rdi
callq 0xffffffff80109680
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff8010a0e6
movq -0x150(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0xffffffff8010a08d
movq -0x148(%rbp), %rdi
callq 0xffffffff8010e140
leaq -0x138(%rbp), %rdi
callq 0xffffffff8010a260
movq -0x28(%rbp), %rdi
callq 0xffffffff80109680
movq -0x150(%rbp), %rdi
callq 0xffffffff80109680
movl $0xfffffffb, -0x4(%rbp) # imm = 0xFFFFFFFB
jmp 0xffffffff8010a0e6
movq -0x148(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movq -0x28(%rbp), %rdi
movq -0x148(%rbp), %rsi
movq -0x150(%rbp), %rdx
callq *%rax
movl %eax, -0x1c(%rbp)
movq -0x148(%rbp), %rdi
callq 0xffffffff8010e140
leaq -0x138(%rbp), %rdi
callq 0xffffffff8010a260
movq -0x28(%rbp), %rdi
callq 0xffffffff80109680
movq -0x150(%rbp), %rdi
callq 0xffffffff80109680
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
nopw %cs:(%rax,%rax)