// File: /workspace/github_c_makefile_star2_O0/albertito[P]libjio/libjio/trans.c
// Function: jopen
struct jfs *jopen(const char *name, int flags, int mode, unsigned int jflags)
{
	int jfd, rv;
	unsigned int t;
	char jdir[PATH_MAX], jlockfile[PATH_MAX];
	struct stat sinfo;
	pthread_mutexattr_t attr;
	struct jfs *fs;

	fs = malloc(sizeof(struct jfs));
	if (fs == NULL)
		return NULL;

	fs->fd = -1;
	fs->jfd = -1;
	fs->jdir = NULL;
	fs->jdirfd = -1;
	fs->jmap = MAP_FAILED;
	fs->as_cfg = NULL;

	/* we provide either read-only or read-write access, because when we
	 * commit a transaction we read the current contents before applying,
	 * and write access is needed for locking with fcntl; the test is done
	 * this way because O_RDONLY is usually 0, so "if (flags & O_RDONLY)"
	 * will fail. */
	if ((flags & O_WRONLY) || (flags & O_RDWR)) {
		flags = flags & ~O_WRONLY;
		flags = flags & ~O_RDONLY;
		flags = flags | O_RDWR;
	} else {
		jflags = jflags | J_RDONLY;
	}

	fs->name = strdup(name);
	fs->flags = jflags;
	fs->open_flags = flags;
	fs->ltrans = NULL;
	fs->ltrans_len = 0;

	/* Note on fs->lock usage: this lock is used only to protect the file
	 * pointer. This means that it must only be held while performing
	 * operations that depend or alter the file pointer (jread, jreadv,
	 * jwrite, jwritev), but the others (jpread, jpwrite) are left
	 * unprotected because they can be performed in parallel as long as
	 * they don't affect the same portion of the file (this is protected
	 * by lockf). The lock doesn't slow things down tho: any threaded app
	 * MUST implement this kind of locking anyways if it wants to prevent
	 * data corruption, we only make it easier for them by taking care of
	 * it here. If performance is essential, the jpread/jpwrite functions
	 * should be used, just as real life.
	 * About fs->ltlock, it's used to protect the lingering transactions
	 * list, fs->ltrans. */
	pthread_mutexattr_init(&attr);
	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
	pthread_mutex_init( &(fs->lock), &attr);
	pthread_mutex_init( &(fs->ltlock), &attr);
	pthread_mutexattr_destroy(&attr);

	fs->fd = open(name, flags, mode);
	if (fs->fd < 0)
		goto error_exit;

	/* nothing else to do for read-only access */
	if (jflags & J_RDONLY) {
		return fs;
	}

	if (!get_jdir(name, jdir))
		goto error_exit;
	mkdir(jdir, 0750);
	rv = lstat(jdir, &sinfo);
	if (rv < 0 || !S_ISDIR(sinfo.st_mode))
		goto error_exit;

	fs->jdir = malloc(strlen(jdir) + 1);
	if (fs->jdir == NULL)
		goto error_exit;
	strcpy(fs->jdir, jdir);

	/* open the directory, we will use it to flush transaction files'
	 * metadata in jtrans_commit() */
	fs->jdirfd = open(jdir, O_RDONLY);
	if (fs->jdirfd < 0)
		goto error_exit;

	snprintf(jlockfile, PATH_MAX, "%s/lock", jdir);
	jfd = open(jlockfile, O_RDWR | O_CREAT, 0600);
	if (jfd < 0)
		goto error_exit;

	fs->jfd = jfd;

	/* initialize the lock file by writing the first tid to it, but only
	 * if its empty, otherwise there is a race if two processes call
	 * jopen() simultaneously and both initialize the file */
	plockf(jfd, F_LOCKW, 0, 0);
	lstat(jlockfile, &sinfo);
	if (sinfo.st_size != sizeof(unsigned int)) {
		t = 0;
		rv = spwrite(jfd, &t, sizeof(t), 0);
		if (rv != sizeof(t)) {
			goto error_exit;
		}
	}
	plockf(jfd, F_UNLOCK, 0, 0);

	fs->jmap = (unsigned int *) mmap(NULL, sizeof(unsigned int),
			PROT_READ | PROT_WRITE, MAP_SHARED, jfd, 0);
	if (fs->jmap == MAP_FAILED)
		goto error_exit;

	return fs;

error_exit:
	/* if there was an error, clean up as much as possible so we don't
	 * leak anything, and return failure; jclose just does this cleaning
	 * for us */
	jclose(fs);
	return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20d0, %rsp           # imm = 0x20D0
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl $0x98, %edi
callq 0x23c0
movq %rax, -0x20d0(%rbp)
cmpq $0x0, -0x20d0(%rbp)
jne 0x3fa0
movq $0x0, -0x8(%rbp)
jmp 0x432e
movq -0x20d0(%rbp), %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movq -0x20d0(%rbp), %rax
movl $0xffffffff, 0x1c(%rax) # imm = 0xFFFFFFFF
movq -0x20d0(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x20d0(%rbp), %rax
movl $0xffffffff, 0x18(%rax) # imm = 0xFFFFFFFF
movq -0x20d0(%rbp), %rax
movq $-0x1, %rcx
movq %rcx, 0x20(%rax)
movq -0x20d0(%rbp), %rax
movq $0x0, 0x90(%rax)
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x4012
movl -0x14(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x402f
movl -0x14(%rbp), %eax
andl $-0x2, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
andl $-0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x14(%rbp)
jmp 0x403a
movl -0x1c(%rbp), %eax
orl $0x200, %eax            # imm = 0x200
movl %eax, -0x1c(%rbp)
movq -0x10(%rbp), %rdi
callq 0x25c0
movq %rax, %rcx
movq -0x20d0(%rbp), %rax
movq %rcx, 0x8(%rax)
movl -0x1c(%rbp), %ecx
movq -0x20d0(%rbp), %rax
movl %ecx, 0x28(%rax)
movl -0x14(%rbp), %ecx
movq -0x20d0(%rbp), %rax
movl %ecx, 0x2c(%rax)
movq -0x20d0(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x20d0(%rbp), %rax
movq $0x0, 0x38(%rax)
leaq -0x20c4(%rbp), %rdi
callq 0x2590
leaq -0x20c4(%rbp), %rdi
xorl %esi, %esi
callq 0x21d0
movq -0x20d0(%rbp), %rdi
addq $0x68, %rdi
leaq -0x20c4(%rbp), %rsi
callq 0x25d0
movq -0x20d0(%rbp), %rdi
addq $0x40, %rdi
leaq -0x20c4(%rbp), %rsi
callq 0x25d0
leaq -0x20c4(%rbp), %rdi
callq 0x25e0
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
movb $0x0, %al
callq 0x2500
movl %eax, %ecx
movq -0x20d0(%rbp), %rax
movl %ecx, (%rax)
movq -0x20d0(%rbp), %rax
cmpl $0x0, (%rax)
jge 0x410a
jmp 0x431a
movl -0x1c(%rbp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x4127
movq -0x20d0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x432e
movq -0x10(%rbp), %rdi
leaq -0x1030(%rbp), %rsi
callq 0x24a0
cmpl $0x0, %eax
jne 0x4141
jmp 0x431a
leaq -0x1030(%rbp), %rdi
movl $0x1e8, %esi            # imm = 0x1E8
callq 0x20b0
leaq -0x1030(%rbp), %rdi
leaq -0x20c0(%rbp), %rsi
callq 0x2280
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jl 0x4180
movl -0x20a8(%rbp), %eax
andl $0xf000, %eax           # imm = 0xF000
cmpl $0x4000, %eax           # imm = 0x4000
je 0x4185
jmp 0x431a
leaq -0x1030(%rbp), %rdi
callq 0x2140
movq %rax, %rdi
addq $0x1, %rdi
callq 0x23c0
movq %rax, %rcx
movq -0x20d0(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x20d0(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x41be
jmp 0x431a
movq -0x20d0(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x1030(%rbp), %rsi
callq 0x20a0
leaq -0x1030(%rbp), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x2500
movl %eax, %ecx
movq -0x20d0(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x20d0(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jge 0x4203
jmp 0x431a
leaq -0x2030(%rbp), %rdi
leaq -0x1030(%rbp), %rcx
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2dfb(%rip), %rdx      # 0x7018
movb $0x0, %al
callq 0x21c0
leaq -0x2030(%rbp), %rdi
movl $0x42, %esi
movl $0x180, %edx            # imm = 0x180
movb $0x0, %al
callq 0x2500
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0x424a
jmp 0x431a
movl -0x20(%rbp), %ecx
movq -0x20d0(%rbp), %rax
movl %ecx, 0x1c(%rax)
movl -0x20(%rbp), %edi
movl $0x110, %esi            # imm = 0x110
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x24d0
leaq -0x2030(%rbp), %rdi
leaq -0x20c0(%rbp), %rsi
callq 0x2280
cmpq $0x4, -0x2090(%rbp)
je 0x42b5
movl $0x0, -0x28(%rbp)
movl -0x20(%rbp), %edi
leaq -0x28(%rbp), %rsi
movl $0x4, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x2490
movl %eax, -0x24(%rbp)
movslq -0x24(%rbp), %rax
cmpq $0x4, %rax
je 0x42b3
jmp 0x431a
jmp 0x42b5
movl -0x20(%rbp), %edi
movl $0x10000, %esi          # imm = 0x10000
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x24d0
movl -0x20(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x4, %esi
movl $0x3, %edx
movl $0x1, %ecx
movq %r9, %rdi
callq 0x2160
movq %rax, %rcx
movq -0x20d0(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x20d0(%rbp), %rax
movq $-0x1, %rcx
cmpq %rcx, 0x20(%rax)
jne 0x430d
jmp 0x431a
movq -0x20d0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x432e
movq -0x20d0(%rbp), %rdi
callq 0x24e0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x20d0, %rsp           # imm = 0x20D0
popq %rbp
retq
nopl (%rax,%rax)