// File: /workspace/github_c_makefile_star2_O0/dlbeer[P]dhara/dhara/journal.c
// Function: find_head
static int find_head(struct dhara_journal *j, dhara_page_t start,
		     dhara_error_t *err)
{
	j->head = next_upage(j, start);
	if (!j->head)
		roll_stats(j);

	/* Starting from the last good checkpoint, find either:
	 *
	 *   (a) the next free user-page in the same block
	 *   (b) or, the first page of the next block
	 *
	 * The block we end up on might be bad, but that's ok -- we'll
	 * skip it when we go to prepare the next write.
	 */
	for (;;) {
		/* How many free pages trail this checkpoint group? */
		const unsigned int ppc = 1 << j->log2_ppc;
		unsigned int n = 0;
		dhara_page_t first = j->head & ~(dhara_page_t)(ppc - 1);

		while (n < ppc &&
			dhara_nand_is_free(j->nand, first + ppc - n - 1))
			n++;

		/* If we have some, then we've found our next free
		 * userpage.
		 */
		if (n > 1) {
			j->head = first + ppc - n;
			break;
		}

		/* Skip to the next checkpoint group */
		j->head = first + ppc;
		if (j->head >= (j->nand->num_blocks << j->nand->log2_ppb)) {
			j->head = 0;
			roll_stats(j);
		}

		/* If we hit the end of the block, we're done */
		if (is_aligned(j->head, j->nand->log2_ppb)) {
			/* Make sure we don't chase over the tail */
			if (align_eq(j->head, j->tail, j->nand->log2_ppb))
				j->tail = next_block(j->nand,
					j->tail >> j->nand->log2_ppb) <<
						j->nand->log2_ppb;
			break;
		}
	}

	return 0;
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movl %esi, 0x1c(%rsp)
movq %rdx, 0x10(%rsp)
movq 0x20(%rsp), %rdi
movl 0x1c(%rsp), %esi
callq 0x33c0
movl %eax, %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0x24(%rax)
movq 0x20(%rsp), %rax
cmpl $0x0, 0x24(%rax)
jne 0x2ccf
movq 0x20(%rsp), %rdi
callq 0x3da0
jmp 0x2cd1
movq 0x20(%rsp), %rax
movzbl 0x10(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, 0xc(%rsp)
movl $0x0, 0x8(%rsp)
movq 0x20(%rsp), %rax
movl 0x24(%rax), %eax
movl 0xc(%rsp), %ecx
subl $0x1, %ecx
xorl $-0x1, %ecx
andl %ecx, %eax
movl %eax, 0x4(%rsp)
movl 0x8(%rsp), %ecx
xorl %eax, %eax
cmpl 0xc(%rsp), %ecx
movb %al, 0x3(%rsp)
jae 0x2d3b
movq 0x20(%rsp), %rax
movq (%rax), %rdi
movl 0x4(%rsp), %esi
addl 0xc(%rsp), %esi
subl 0x8(%rsp), %esi
subl $0x1, %esi
callq 0x5230
cmpl $0x0, %eax
setne %al
movb %al, 0x3(%rsp)
movb 0x3(%rsp), %al
testb $0x1, %al
jne 0x2d45
jmp 0x2d52
movl 0x8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8(%rsp)
jmp 0x2d05
cmpl $0x1, 0x8(%rsp)
jbe 0x2d72
movl 0x4(%rsp), %ecx
addl 0xc(%rsp), %ecx
subl 0x8(%rsp), %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0x24(%rax)
jmp 0x2e45
movl 0x4(%rsp), %ecx
addl 0xc(%rsp), %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0x24(%rax)
movq 0x20(%rsp), %rax
movl 0x24(%rax), %eax
movq 0x20(%rsp), %rcx
movq (%rcx), %rcx
movl 0x4(%rcx), %edx
movq 0x20(%rsp), %rcx
movq (%rcx), %rcx
movzbl 0x1(%rcx), %ecx
shll %cl, %edx
movl %edx, %ecx
cmpl %ecx, %eax
jb 0x2dbf
movq 0x20(%rsp), %rax
movl $0x0, 0x24(%rax)
movq 0x20(%rsp), %rdi
callq 0x3da0
movq 0x20(%rsp), %rax
movl 0x24(%rax), %edi
movq 0x20(%rsp), %rax
movq (%rax), %rax
movzbl 0x1(%rax), %esi
callq 0x3280
cmpl $0x0, %eax
je 0x2e40
movq 0x20(%rsp), %rax
movl 0x24(%rax), %edi
movq 0x20(%rsp), %rax
movl 0x20(%rax), %esi
movq 0x20(%rsp), %rax
movq (%rax), %rax
movzbl 0x1(%rax), %edx
callq 0x3120
cmpl $0x0, %eax
je 0x2e3e
movq 0x20(%rsp), %rax
movq (%rax), %rdi
movq 0x20(%rsp), %rax
movl 0x20(%rax), %esi
movq 0x20(%rsp), %rax
movq (%rax), %rax
movzbl 0x1(%rax), %ecx
shrl %cl, %esi
callq 0x32b0
movq 0x20(%rsp), %rcx
movq (%rcx), %rcx
movzbl 0x1(%rcx), %ecx
shll %cl, %eax
movl %eax, %ecx
movq 0x20(%rsp), %rax
movl %ecx, 0x20(%rax)
jmp 0x2e45
jmp 0x2cd1
xorl %eax, %eax
addq $0x28, %rsp
retq
nopl (%rax)