// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
testq %rdx, %rdx
je 0x4b24
movq %rdi, %rbx
movq 0x8(%rdi), %rax
testq %rax, %rax
je 0x4b24
movq %rdx, %r14
mulq %rdx
jo 0x4b43
movq %rcx, %r15
movq %rsi, %r12
movq %rbx, %rdi
callq 0x4fcf
testl %eax, %eax
jne 0x4a60
cmpq %r12, 0x70(%rbx)
jne 0x4a1b
movq 0x60(%rbx), %r13
movq %r13, %rdi
callq 0x55fe
leaq -0x1(%rax), %rsi
movq %r13, %rdi
callq 0x5603
testq %rax, %rax
je 0x49f0
movq %rax, %r13
movq 0x8(%rax), %rax
movq 0x70(%rbx), %rcx
subq 0x68(%rbx), %rcx
shrq $0x4, %rcx
cmpq %rcx, %rax
ja 0x49f0
addq %r14, %rax
cmpq 0x10(%rbx), %rax
jbe 0x4a72
leaq 0x8(%rsp), %r13
movq %r12, (%r13)
andq $0x0, 0x8(%r13)
movq 0x60(%rbx), %rdi
movq %r13, %rsi
callq 0x5555
testl %eax, %eax
jne 0x4a4d
pushq $0x1
popq %rbp
movl $0x0, 0x4(%rsp)
jmp 0x4a7a
leaq 0x80fd(%rip), %rdi      # 0xcb1f
xorl %eax, %eax
callq 0x9ec8
callq 0x20a0
movq %rax, %r14
andl $0x0, (%rax)
movq 0x70(%rbx), %rdx
leaq 0x8108(%rip), %rdi      # 0xcb47
movq %r12, %rsi
xorl %eax, %eax
callq 0x9ec8
andl $0x0, (%r14)
movq %rbx, %rdi
callq 0x5006
xorl %r12d, %r12d
movq %r12, %rdi
callq 0x2040
pushq $-0x1
popq %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x1, %al
movl %eax, 0x4(%rsp)
xorl %ebp, %ebp
movq (%r13), %r12
movq %rbx, %rdi
callq 0x5006
testl %eax, %eax
jne 0x4a60
movq %rbx, %rdi
movq %r12, %rsi
callq 0x503d
testq %rax, %rax
je 0x4a60
movq %rax, %r12
movq 0x8(%rbx), %rdx
imulq %r14, %rdx
movl 0x20(%rbx), %r8d
movq %rax, %rdi
movl %ebp, %esi
movq %r15, %rcx
callq 0x5381
testl %eax, %eax
jne 0x4a58
movq %r12, %rdi
callq 0x2040
cmpb $0x0, 0x4(%rsp)
jne 0x4acf
cmpl $0x0, 0x20(%rbx)
je 0x4b12
movq %rbx, %rdi
callq 0x4fcf
testl %eax, %eax
jne 0x4a60
movq 0x60(%rbx), %r15
movq %r15, %rdi
callq 0x55fe
leaq -0x1(%rax), %rsi
movq %r15, %rdi
callq 0x5603
addq %r14, 0x8(%rax)
addq %r14, 0x70(%rbx)
movq %rbx, %rdi
callq 0x5006
testl %eax, %eax
jne 0x4a60
xorl %eax, %eax
jmp 0x4a63
movq (%rbx), %rdi
callq 0x50a4
testl %eax, %eax
jne 0x4a60
jmp 0x4acf
leaq 0x7f68(%rip), %rdi      # 0xca93
leaq 0x7e05(%rip), %rsi      # 0xc937
leaq 0x7f7d(%rip), %rcx      # 0xcab6
movl $0x12c, %edx            # imm = 0x12C
callq 0x2220
leaq 0x7fb5(%rip), %rdi      # 0xcaff
leaq 0x7de6(%rip), %rsi      # 0xc937
leaq 0x7f5e(%rip), %rcx      # 0xcab6
movl $0x12d, %edx            # imm = 0x12D
callq 0x2220