// File: /workspace/github_c_makefile_star2_O0/ngkaho1234[P]ext4-extents-tree/extents.c
// Function: ext4_ext_delete
int
ext4_ext_delete(struct ext4_ext_cursor *cur)
{
	int ret = 0;
	uint16_t nritems;
	int i;
	int rootdepth;
	struct ext4_extent_header *hdr;

	rootdepth = ext4_ext_cursor_depth(cur);
	hdr = cur->c_paths[0].p_hdr;

	/*
	 * We return ENOENT as error if we found the buffer of the lowest
	 * level is unpinned, have no entries in it, or the pointer being
	 * out-of-range.
	 */
	if (!hdr || !ext4_ext_header_entries(hdr))
		return ENOENT;
	if (cur->c_paths[0].p_ptr == -1)
		return ENOENT;
	if (cur->c_paths[0].p_ptr >= ext4_ext_header_entries(hdr))
		return ENOENT;

	/*
	 * Delete the extent at leaf.
	 */
	ext4_ext_delete_item(cur, 0);

	for (i = 0; i < rootdepth; i++) {
		int merged = 0;
		ssize_t ptr;
		struct ext4_ext_cursor *ncur;
		struct ext4_extent_idx *idx;
		struct ext4_extent_header *uhdr;

		hdr = cur->c_paths[i].p_hdr;

		nritems = ext4_ext_header_entries(hdr);
		if (nritems) {
			/*
			 * Try to merge the node with left sibling or
			 * right sibling.
			 */
			ret = ext4_ext_try_merge(cur, i, &ncur, &merged);
			if (ret)
				goto out;

			if (merged == 1) {
				ext4_assert(ncur);

				/*
				 * After merging to left sibling,
				 * we need not to update the first key of the
				 * left sibling at every level.
				 */

				/*
				 * Throw away the cursor to sibling.
				 */
				ext4_ext_cursor_free(ncur);
			} else if (merged == 2) {
				ext4_assert(ncur);

				/*
				 * After merging to right sibling,
				 * we need to update the first key of the
				 * right sibling at every level until we
				 * meet a non-leftmost key.
				 */
				ext4_ext_update_index(ncur, i, 0);

				/*
				 * Throw away the cursor to sibling.
				 */
				ext4_ext_cursor_free(ncur);
			} else {
				/*
				 * No merge happens, so do nothing.
				 */
				ext4_assert(!ncur);
				break;
			}
		}
		/*
		 * If we have merged two nodes into one, or we leave
		 * nothing in the node after deletion of an item,
		 * we free the block of the node.
		 *
		 * At the next iteration we delete the key of the node.
		 */

		/*
		 * Get the respective key in parent node.
		 */
		uhdr = cur->c_paths[i + 1].p_hdr;
		ptr = cur->c_paths[i + 1].p_ptr;
		idx = EXT_FIRST_INDEX(uhdr) + ptr;

		/*
		 * Unpin the buffer of this node, and free
		 * the block of it.
		 */
		ext4_ext_cursor_unpin(cur, i, 1);
		cur->c_cursor_op.c_free_block_func(cur, ext4_idx_block(idx));

		/*
		 * Delete the index of the current node at parent node.
		 */
		ext4_ext_delete_item(cur, i + 1);
	}

	if (i < rootdepth) {
		/*
		 * We might have removed the leftmost key in the node,
		 * so we need to update the first key of the right
		 * sibling at every level until we meet a non-leftmost
		 * key.
		 */
		ext4_ext_update_index(cur, i, 0);
	} else {
		if (!ext4_ext_tree_empty(cur)) {
			/*
			 * Reload the cursor's path so that it points to
			 * a valid key again.
			 */
			ret = ext4_ext_reload_paths(cur, i, true);
			if (ret)
				goto out;

			ret = ext4_ext_tree_shrink(cur);
		} else {
			/*
			 * For empty root we need to make sure that the
			 * depth of the root level is 0.
			 */
			hdr = cur->c_root;
			ext4_ext_header_set_depth(hdr, 0);
			cur->c_cursor_op.c_root_dirty_func(cur);
			ext4_ext_cursor_unpin(cur, rootdepth, 1);
		}
	}

out:
	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movq -0x10(%rbp), %rdi
callq 0x6720
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x8205
movq -0x28(%rbp), %rdi
callq 0x69a0
cmpw $0x0, %ax
jne 0x8211
movl $0x2, -0x4(%rbp)
jmp 0x84c5
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
cmpq $-0x1, 0x10(%rax)
jne 0x822c
movl $0x2, -0x4(%rbp)
jmp 0x84c5
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rdi
callq 0x69a0
movw %ax, %cx
movq -0x58(%rbp), %rax
movzwl %cx, %ecx
cmpq %rcx, %rax
jl 0x8260
movl $0x2, -0x4(%rbp)
jmp 0x84c5
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x84d0
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x8437
movl $0x0, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x69a0
movw %ax, -0x16(%rbp)
cmpw $0x0, -0x16(%rbp)
je 0x838b
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
leaq -0x40(%rbp), %rdx
leaq -0x2c(%rbp), %rcx
callq 0x8660
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x82da
jmp 0x84bf
cmpl $0x1, -0x2c(%rbp)
jne 0x8313
cmpq $0x0, -0x40(%rbp)
je 0x82e9
jmp 0x8308
leaq 0x2890(%rip), %rdi      # 0xab80
leaq 0x26e4(%rip), %rsi      # 0xa9db
movl $0x96a, %edx            # imm = 0x96A
leaq 0x284e(%rip), %rcx      # 0xab51
callq 0x20c0
movq -0x40(%rbp), %rdi
callq 0x6470
jmp 0x8389
cmpl $0x2, -0x2c(%rbp)
jne 0x835a
cmpq $0x0, -0x40(%rbp)
je 0x8322
jmp 0x8341
leaq 0x2857(%rip), %rdi      # 0xab80
leaq 0x26ab(%rip), %rsi      # 0xa9db
movl $0x977, %edx            # imm = 0x977
leaq 0x2815(%rip), %rcx      # 0xab51
callq 0x20c0
movq -0x40(%rbp), %rdi
movl -0x1c(%rbp), %esi
xorl %edx, %edx
callq 0x7070
movq -0x40(%rbp), %rdi
callq 0x6470
jmp 0x8387
cmpq $0x0, -0x40(%rbp)
jne 0x8363
jmp 0x8382
leaq 0x2815(%rip), %rdi      # 0xab7f
leaq 0x266a(%rip), %rsi      # 0xa9db
movl $0x989, %edx            # imm = 0x989
leaq 0x27d4(%rip), %rcx      # 0xab51
callq 0x20c0
jmp 0x8437
jmp 0x8389
jmp 0x838b
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x50(%rbp), %rax
addq $0xc, %rax
imulq $0xc, -0x38(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl $0x1, %edx
callq 0x62d0
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x48(%rbp), %rdi
callq 0x6970
movq -0x68(%rbp), %rdi
movq %rax, %rsi
movq -0x60(%rbp), %rax
callq *%rax
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
addl $0x1, %esi
callq 0x84d0
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x8272
movl -0x1c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x844f
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
xorl %edx, %edx
callq 0x7070
jmp 0x84bd
movq -0x10(%rbp), %rdi
callq 0x6a70
testb $0x1, %al
jne 0x8486
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl $0x1, %edx
callq 0x7280
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x8478
jmp 0x84bf
movq -0x10(%rbp), %rdi
callq 0x86d0
movl %eax, -0x14(%rbp)
jmp 0x84bb
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x80a0
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x10(%rbp), %rdi
callq *%rax
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %esi
movl $0x1, %edx
callq 0x62d0
jmp 0x84bd
jmp 0x84bf
movl -0x14(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nop