// File: /workspace/github_c_makefile_star2_O0/Tarsnap[P]kivaloo/lbs/storage.c
// Function: storage_write
int
storage_write(struct storage_state * S,
    uint64_t blkno, uint64_t nblks, uint8_t * buf)
{
	struct file_state fs_new;
	struct file_state * fs;
	int newfile;
	uint64_t fnum;
	char * s = NULL;	/* free(NULL) simplifies error path. */

	/* Sanity checks.  We must have nblks * S->blocklen <= SIZE_MAX. */
	assert((nblks != 0) && (S->blocklen != 0));
	assert(nblks <= SIZE_MAX / S->blocklen);

	/* Pick up a write lock. */
	if (storage_util_writelock(S))
		goto err0;

	/* Sanity-check the write position. */
	if (blkno != S->nextblk) {
		warn0("Attempt to append data with wrong blkno");
		warn0("(%016" PRIx64 ", should be %016" PRIx64 ")",
		    blkno, S->nextblk);
		goto err2;
	}

	/* Get a pointer to the last file (or NULL if no files exist). */
	fs = elasticqueue_get(S->files, elasticqueue_getlen(S->files) - 1);

	/**
	 * Figure out if we should continue appending to the last file, or
	 * create a new file.  We start a new file if either of the following
	 * conditions apply:
	 * 1. We have no files yet.
	 * 2. The last file is more than 1/16 of the total stored data.
	 * 3. Adding to the last file will result in the file having too
	 *    many blocks.
	 */
	if (fs == NULL)
		newfile = 1;
	else if (fs->len > (S->nextblk - S->minblk) / 16)
		newfile = 1;
	else if (fs->len + nblks > S->maxnblks)
		newfile = 1;
	else
		newfile = 0;

	/* If we're creating a new file, add a new file_state to the queue. */
	if (newfile) {
		fs_new.start = blkno;
		fs_new.len = 0;
		fs = &fs_new;
		if (elasticqueue_add(S->files, fs))
			goto err2;
	}

	/* Record which file we're appending to. */
	fnum = fs->start;

	/* Release the lock. */
	if (storage_util_unlock(S))
		goto err0;

	/* Write the block(s) to the end of the file. */
	if ((s = storage_util_mkpath(S, fnum)) == NULL)
		goto err0;
	if (disk_write(s, newfile, (size_t)(S->blocklen * nblks), buf,
	    S->nosync)) {
		goto err1;
	}
	free(s);

	/* Make sure any file creation is flushed to disk. */
	if ((newfile) && (S->nosync == 0)) {
		if (disk_syncdir(S->storagedir))
			goto err0;
	}

	/* Pick up a write lock. */
	if (storage_util_writelock(S))
		goto err0;

	/*
	 * Get a pointer to the last file.  We must do this here since the
	 * queue may have been modified while we didn't have a lock.
	 */
	fs = elasticqueue_get(S->files, elasticqueue_getlen(S->files) - 1);

	/* Adjust block count. */
	fs->len += nblks;

	/* Adjust next-block-to-write value. */
	S->nextblk += nblks;

	/* Release the lock. */
	if (storage_util_unlock(S))
		goto err0;

	/* Success! */
	return (0);

err2:
	storage_util_unlock(S);
err1:
	free(s);
err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq $0x0, -0x58(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x5e94
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x5e94
jmp 0x5eb3
leaq 0xcddc(%rip), %rdi      # 0x12c77
leaq 0xcc79(%rip), %rsi      # 0x12b1b
movl $0x12c, %edx            # imm = 0x12C
leaq 0xcdec(%rip), %rcx      # 0x12c9a
callq 0x2240
movq -0x20(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rcx
movq $-0x1, %rax
xorl %edx, %edx
divq 0x8(%rcx)
movq %rax, %rcx
movq -0x60(%rbp), %rax
cmpq %rcx, %rax
ja 0x5eda
jmp 0x5ef9
leaq 0xce02(%rip), %rdi      # 0x12ce3
leaq 0xcc33(%rip), %rsi      # 0x12b1b
movl $0x12d, %edx            # imm = 0x12D
leaq 0xcda6(%rip), %rcx      # 0x12c9a
callq 0x2240
movq -0x10(%rbp), %rdi
callq 0x68f0
cmpl $0x0, %eax
je 0x5f0c
jmp 0x614f
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x70(%rcx), %rax
je 0x5f61
jmp 0x5f1c
leaq 0xcde0(%rip), %rdi      # 0x12d03
movb $0x0, %al
callq 0xf2c0
callq 0x20a0
movl $0x0, (%rax)
jmp 0x5f37
movq -0x18(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rdx
leaq 0xcde1(%rip), %rdi      # 0x12d2b
movb $0x0, %al
callq 0xf2c0
callq 0x20a0
movl $0x0, (%rax)
jmp 0x613d
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdi
callq 0x7290
movq -0x68(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0x72b0
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x5f9e
movl $0x1, -0x44(%rbp)
jmp 0x5ff2
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x70(%rcx), %rcx
movq -0x10(%rbp), %rdx
subq 0x68(%rdx), %rcx
shrq $0x4, %rcx
cmpq %rcx, %rax
jbe 0x5fc8
movl $0x1, -0x44(%rbp)
jmp 0x5ff0
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
addq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jbe 0x5fe7
movl $0x1, -0x44(%rbp)
jmp 0x5fee
movl $0x0, -0x44(%rbp)
jmp 0x5ff0
jmp 0x5ff2
cmpl $0x0, -0x44(%rbp)
je 0x602d
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movq $0x0, -0x30(%rbp)
leaq -0x38(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0x7130
cmpl $0x0, %eax
je 0x602b
jmp 0x613d
jmp 0x602d
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
callq 0x6960
cmpl $0x0, %eax
je 0x604b
jmp 0x614f
movq -0x10(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x69d0
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
jne 0x6067
jmp 0x614f
movq -0x58(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdx
imulq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movl 0x20(%rax), %r8d
callq 0x6e70
cmpl $0x0, %eax
je 0x6096
jmp 0x6146
movq -0x58(%rbp), %rdi
callq 0x2040
cmpl $0x0, -0x44(%rbp)
je 0x60c7
movq -0x10(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0x60c7
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x6a60
cmpl $0x0, %eax
je 0x60c5
jmp 0x614f
jmp 0x60c7
movq -0x10(%rbp), %rdi
callq 0x68f0
cmpl $0x0, %eax
je 0x60d7
jmp 0x614f
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdi
callq 0x7290
movq -0x70(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0x72b0
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rcx
movq -0x40(%rbp), %rax
addq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
addq 0x70(%rax), %rcx
movq %rcx, 0x70(%rax)
movq -0x10(%rbp), %rdi
callq 0x6960
cmpl $0x0, %eax
je 0x6134
jmp 0x614f
movl $0x0, -0x4(%rbp)
jmp 0x6156
movq -0x10(%rbp), %rdi
callq 0x6960
movq -0x58(%rbp), %rdi
callq 0x2040
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nop