// File: /workspace/github_c_makefile_star2_O0/albertito[P]libjio/libjio/trans.c
// Function: jtrans_commit
ssize_t jtrans_commit(struct jtrans *ts)
{
	ssize_t r, retval = -1;
	struct operation *op;
	struct jlinger *linger;
	jop_t *jop = NULL;
	size_t written = 0;

	pthread_mutex_lock(&(ts->lock));

	/* clear the flags */
	ts->flags = ts->flags & ~J_COMMITTED;
	ts->flags = ts->flags & ~J_ROLLBACKED;

	if (ts->numops_r + ts->numops_w == 0)
		goto exit;

	/* fail for read-only accesses if we have write operations */
	if (ts->numops_w && (ts->flags & J_RDONLY))
		goto exit;

	/* Lock all the regions we're going to work with; otherwise there
	 * could be another transaction trying to write the same spots and we
	 * could end up with interleaved writes, that could break atomicity
	 * warantees if we need to rollback.
	 * Note we do this before creating a new transaction, so we know it's
	 * not possible to have two overlapping transactions on disk at the
	 * same time. */
	if (lock_file_ranges(ts, F_LOCKW) != 0)
		goto unlock_exit;

	/* create and fill the transaction file only if we have at least one
	 * write operation */
	if (ts->numops_w) {
		jop = journal_new(ts->fs, ts->flags);
		if (jop == NULL)
			goto unlock_exit;
	}

	for (op = ts->op; op != NULL; op = op->next) {
		if (op->direction == D_READ)
			continue;

		r = journal_add_op(jop, op->buf, op->len, op->offset);
		if (r != 0)
			goto unlink_exit;

		fiu_exit_on("jio/commit/tf_opdata");
	}

	if (jop)
		journal_pre_commit(jop);

	fiu_exit_on("jio/commit/tf_data");

	if (!(ts->flags & J_NOROLLBACK)) {
		for (op = ts->op; op != NULL; op = op->next) {
			if (op->direction == D_READ)
				continue;

			 r = operation_read_prev(ts, op);
			 if (r < 0)
				 goto unlink_exit;
		}
	}

	if (jop) {
		r = journal_commit(jop);
		if (r < 0)
			goto unlink_exit;
	}

	/* now that we have a safe transaction file, let's apply it */
	written = 0;
	for (op = ts->op; op != NULL; op = op->next) {
		if (op->direction == D_READ) {
			r = spread(ts->fs->fd, op->buf, op->len, op->offset);
			if (r != op->len)
				goto rollback_exit;

			continue;
		}

		/* from now on, write ops (which are more interesting) */

		r = spwrite(ts->fs->fd, op->buf, op->len, op->offset);
		if (r != op->len)
			goto rollback_exit;

		written += r;

		if (have_sync_range && !(ts->flags & J_LINGER)) {
			r = sync_range_submit(ts->fs->fd, op->len,
					op->offset);
			if (r != 0)
				goto rollback_exit;
		}

		fiu_exit_on("jio/commit/wrote_op");
	}

	fiu_exit_on("jio/commit/wrote_all_ops");

	if (jop && (ts->flags & J_LINGER)) {
		struct jlinger *lp;

		linger = malloc(sizeof(struct jlinger));
		if (linger == NULL)
			goto rollback_exit;

		linger->jop = jop;
		linger->next = NULL;

		pthread_mutex_lock(&(ts->fs->ltlock));

		/* add it to the end of the list so they're in order */
		if (ts->fs->ltrans == NULL) {
			ts->fs->ltrans = linger;
		} else {
			lp = ts->fs->ltrans;
			while (lp->next != NULL)
				lp = lp->next;
			lp->next = linger;
		}

		ts->fs->ltrans_len += written;
		autosync_check(ts->fs);

		pthread_mutex_unlock(&(ts->fs->ltlock));

		/* Leave the journal_free() up to jsync() */
		jop = NULL;
	} else if (jop) {
		if (have_sync_range) {
			for (op = ts->op; op != NULL; op = op->next) {
				if (op->direction == D_READ)
					continue;

				r = sync_range_wait(ts->fs->fd, op->len,
						op->offset);
				if (r != 0)
					goto rollback_exit;
			}
		} else {
			if (fdatasync(ts->fs->fd) != 0)
				goto rollback_exit;
		}
	}

	/* mark the transaction as committed */
	ts->flags = ts->flags | J_COMMITTED;

	retval = 1;

rollback_exit:
	/* If the transaction failed we try to recover by rolling it back.
	 * Only used if it has at least one write operation.
	 *
	 * NOTE: on extreme conditions (ENOSPC/disk failure) this can fail
	 * too! There's nothing much we can do in that case, the caller should
	 * take care of it by itself.
	 *
	 * Transactions that were successfuly recovered by rolling them back
	 * will have J_ROLLBACKED in their flags. */
	if (jop && !(ts->flags & J_COMMITTED) &&
			!(ts->flags & J_ROLLBACKING)) {
		r = ts->flags;
		ts->flags = ts->flags | J_NOLOCK | J_ROLLBACKING;
		if (jtrans_rollback(ts) >= 0) {
			ts->flags = r | J_ROLLBACKED;
			retval = -1;
		} else {
			ts->flags = r;
			retval = -2;
		}
	}

unlink_exit:
	/* If the journal operation is no longer needed, we remove it from the
	 * disk.
	 *
	 * Extreme conditions (filesystem just got read-only, for example) can
	 * cause journal_free() to fail, but there's not much left to do at
	 * that point, and the caller will have to be careful and stop its
	 * operations. In that case, we will return -2, and the transaction
	 * will be marked as J_COMMITTED to indicate that the data was
	 * effectively written to disk. */
	if (jop) {
		/* Note we only unlink if we've written down the real data, or
		 * at least rolled it back properly */
		int data_is_safe = (ts->flags & J_COMMITTED) ||
			(ts->flags & J_ROLLBACKED);
		r = journal_free(jop, data_is_safe ? 1 : 0);
		if (r != 0)
			retval = -2;

		jop = NULL;
	}

unlock_exit:
	/* always unlock everything at the end; otherwise we could have
	 * half-overlapping transactions applying simultaneously, and if
	 * anything goes wrong it would be possible to break consistency */
	lock_file_ranges(ts, F_UNLOCK);

exit:
	pthread_mutex_unlock(&(ts->lock));

	return retval;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq $-0x1, -0x18(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
callq 0x25f0
movq -0x8(%rbp), %rax
movl 0xc(%rax), %ecx
andl $0xfffffbff, %ecx       # imm = 0xFFFFFBFF
movq -0x8(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x8(%rbp), %rax
movl 0xc(%rax), %ecx
andl $0xfffff7ff, %ecx       # imm = 0xFFFFF7FF
movq -0x8(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x8(%rbp), %rcx
addl 0x14(%rcx), %eax
cmpl $0x0, %eax
jne 0x3541
jmp 0x3a63
movq -0x8(%rbp), %rax
cmpl $0x0, 0x14(%rax)
je 0x3561
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x3561
jmp 0x3a63
movq -0x8(%rbp), %rdi
movl $0x110, %esi            # imm = 0x110
callq 0x3a80
cmpl $0x0, %eax
je 0x3579
jmp 0x3a55
movq -0x8(%rbp), %rax
cmpl $0x0, 0x14(%rax)
je 0x35a8
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x8(%rbp), %rax
movl 0xc(%rax), %esi
callq 0x2060
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x35a6
jmp 0x3a55
jmp 0x35a8
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x360a
movq -0x20(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x35c7
jmp 0x35fc
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rcx
callq 0x2150
cltq
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x35fa
jmp 0x39df
jmp 0x35fc
movq -0x20(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x35b4
cmpq $0x0, -0x30(%rbp)
je 0x361a
movq -0x30(%rbp), %rdi
callq 0x23d0
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x3679
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x3677
movq -0x20(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x3648
jmp 0x3669
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x3bf0
cltq
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jge 0x3667
jmp 0x39df
jmp 0x3669
movq -0x20(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x3635
jmp 0x3679
cmpq $0x0, -0x30(%rbp)
je 0x369d
movq -0x30(%rbp), %rdi
callq 0x22c0
cltq
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jge 0x369b
jmp 0x39df
jmp 0x369d
movq $0x0, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x37b1
movq -0x20(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x3708
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl (%rax), %edi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rcx
callq 0x2300
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x10(%rcx), %rax
je 0x3703
jmp 0x394b
jmp 0x37a0
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl (%rax), %edi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rcx
callq 0x2490
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x10(%rcx), %rax
je 0x3745
jmp 0x394b
movq -0x10(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq 0x5880(%rip), %rax      # 0x8fd8
cmpl $0x0, (%rax)
je 0x379e
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
jne 0x379e
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl (%rax), %edi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdx
callq 0x2050
cltq
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x379c
jmp 0x394b
jmp 0x379e
jmp 0x37a0
movq -0x20(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x36b1
cmpq $0x0, -0x30(%rbp)
je 0x389f
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x389f
movl $0x10, %edi
callq 0x23c0
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x37e9
jmp 0x394b
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
addq $0x40, %rdi
callq 0x25f0
movq -0x8(%rbp), %rax
movq (%rax), %rax
cmpq $0x0, 0x30(%rax)
jne 0x382f
movq -0x28(%rbp), %rcx
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x30(%rax)
jmp 0x3863
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x30(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x3857
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x383e
movq -0x28(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rcx
movq -0x8(%rbp), %rax
movq (%rax), %rax
addq 0x38(%rax), %rcx
movq %rcx, 0x38(%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
callq 0x24c0
movq -0x8(%rbp), %rax
movq (%rax), %rdi
addq $0x40, %rdi
callq 0x23a0
movq $0x0, -0x30(%rbp)
jmp 0x392f
cmpq $0x0, -0x30(%rbp)
je 0x392d
movq 0x5727(%rip), %rax      # 0x8fd8
cmpl $0x0, (%rax)
je 0x3914
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x3912
movq -0x20(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x38d5
jmp 0x3904
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl (%rax), %edi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdx
callq 0x2030
cltq
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x3902
jmp 0x394b
jmp 0x3904
movq -0x20(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x38c2
jmp 0x392b
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl (%rax), %edi
callq 0x2080
cmpl $0x0, %eax
je 0x3929
jmp 0x394b
jmp 0x392b
jmp 0x392d
jmp 0x392f
movq -0x8(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x400, %ecx            # imm = 0x400
movq -0x8(%rbp), %rax
movl %ecx, 0xc(%rax)
movq $0x1, -0x18(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x39dd
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
jne 0x39dd
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x1000, %eax           # imm = 0x1000
cmpl $0x0, %eax
jne 0x39dd
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x1, %ecx
orl $0x1000, %ecx           # imm = 0x1000
movq -0x8(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x8(%rbp), %rdi
callq 0x20e0
cmpq $0x0, %rax
jl 0x39c6
movq -0x10(%rbp), %rax
orq $0x800, %rax            # imm = 0x800
movl %eax, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xc(%rax)
movq $-0x1, -0x18(%rbp)
jmp 0x39db
movq -0x10(%rbp), %rax
movl %eax, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xc(%rax)
movq $-0x2, -0x18(%rbp)
jmp 0x39dd
jmp 0x39df
cmpq $0x0, -0x30(%rbp)
je 0x3a53
movq -0x8(%rbp), %rax
movl 0xc(%rax), %ecx
andl $0x400, %ecx            # imm = 0x400
movb $0x1, %al
cmpl $0x0, %ecx
movb %al, -0x45(%rbp)
jne 0x3a12
movq -0x8(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
setne %al
movb %al, -0x45(%rbp)
movb -0x45(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x44(%rbp)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %ecx
xorl %esi, %esi
movl $0x1, %eax
cmpl $0x0, %ecx
cmovnel %eax, %esi
callq 0x23f0
cltq
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x3a4b
movq $-0x2, -0x18(%rbp)
movq $0x0, -0x30(%rbp)
jmp 0x3a55
movq -0x8(%rbp), %rdi
movl $0x10000, %esi          # imm = 0x10000
callq 0x3a80
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
callq 0x23a0
movq -0x18(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)