// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_env_write_meta
static int
mdb_env_write_meta(MDB_txn *txn)
{
	MDB_env *env;
	MDB_meta	meta, metab, *mp;
	unsigned flags;
	size_t mapsize;
	off_t off;
	int rc, len, toggle;
	char *ptr;
	HANDLE mfd;
#ifdef _WIN32
	OVERLAPPED ov;
#else
	int r2;
#endif

	toggle = txn->mt_txnid & 1;
	DPRINTF(("writing meta page %d for root page %"Z"u",
		toggle, txn->mt_dbs[MAIN_DBI].md_root));

	env = txn->mt_env;
	flags = txn->mt_flags & env->me_flags;
	mp = env->me_metas[toggle];
	mapsize = env->me_metas[toggle ^ 1]->mm_mapsize;
	/* Persist any increases of mapsize config */
	if (mapsize < env->me_mapsize)
		mapsize = env->me_mapsize;

	if (flags & MDB_WRITEMAP) {
		mp->mm_mapsize = mapsize;
		mp->mm_dbs[FREE_DBI] = txn->mt_dbs[FREE_DBI];
		mp->mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI];
		mp->mm_last_pg = txn->mt_next_pgno - 1;
#if (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) && /* TODO: portability */	\
	!(defined(__i386__) || defined(__x86_64__))
		/* LY: issue a memory barrier, if not x86. ITS#7969 */
		__sync_synchronize();
#endif
		mp->mm_txnid = txn->mt_txnid;
		if (!(flags & (MDB_NOMETASYNC|MDB_NOSYNC))) {
			unsigned meta_size = env->me_psize;
			rc = (env->me_flags & MDB_MAPASYNC) ? MS_ASYNC : MS_SYNC;
			ptr = (char *)mp - PAGEHDRSZ;
#ifndef _WIN32	/* POSIX msync() requires ptr = start of OS page */
			r2 = (ptr - env->me_map) & (env->me_os_psize - 1);
			ptr -= r2;
			meta_size += r2;
#endif
			if (MDB_MSYNC(ptr, meta_size, rc)) {
				rc = ErrCode();
				goto fail;
			}
		}
		goto done;
	}
	metab.mm_txnid = mp->mm_txnid;
	metab.mm_last_pg = mp->mm_last_pg;

	meta.mm_mapsize = mapsize;
	meta.mm_dbs[FREE_DBI] = txn->mt_dbs[FREE_DBI];
	meta.mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI];
	meta.mm_last_pg = txn->mt_next_pgno - 1;
	meta.mm_txnid = txn->mt_txnid;

	off = offsetof(MDB_meta, mm_mapsize);
	ptr = (char *)&meta + off;
	len = sizeof(MDB_meta) - off;
	off += (char *)mp - env->me_map;

	/* Write to the SYNC fd */
	mfd = (flags & (MDB_NOSYNC|MDB_NOMETASYNC)) ? env->me_fd : env->me_mfd;
#ifdef _WIN32
	{
		memset(&ov, 0, sizeof(ov));
		ov.Offset = off;
		if (!WriteFile(mfd, ptr, len, (DWORD *)&rc, &ov))
			rc = -1;
	}
#else
retry_write:
	rc = pwrite(mfd, ptr, len, off);
#endif
	if (rc != len) {
		rc = rc < 0 ? ErrCode() : EIO;
#ifndef _WIN32
		if (rc == EINTR)
			goto retry_write;
#endif
		DPUTS("write failed, disk error?");
		/* On a failure, the pagecache still contains the new data.
		 * Write some old data back, to prevent it from being used.
		 * Use the non-SYNC fd; we know it will fail anyway.
		 */
		meta.mm_last_pg = metab.mm_last_pg;
		meta.mm_txnid = metab.mm_txnid;
#ifdef _WIN32
		memset(&ov, 0, sizeof(ov));
		ov.Offset = off;
		WriteFile(env->me_fd, ptr, len, NULL, &ov);
#else
		r2 = pwrite(env->me_fd, ptr, len, off);
		(void)r2;	/* Silence warnings. We don't care about pwrite's return value */
#endif
fail:
		env->me_flags |= MDB_FATAL_ERROR;
		return rc;
	}
	/* MIPS has cache coherency issues, this is a no-op everywhere else */
	CACHEFLUSH(env->me_map + off, len, DCACHE);
done:
	/* Memory ordering issues are irrelevant; since the entire writer
	 * is wrapped by wmutex, all of these changes will become visible
	 * after the wmutex is unlocked. Since the DB is multi-version,
	 * readers will get consistent data regardless of how fresh or
	 * how stale their view of these values is.
	 */
	if (env->me_txns)
		env->me_txns->mti_txnid = txn->mt_txnid;

	return MDB_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
andq $0x1, %rax
movl %eax, -0x154(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl 0x7c(%rax), %eax
movq -0x18(%rbp), %rcx
andl 0xc(%rcx), %eax
movl %eax, -0x134(%rbp)
movq -0x18(%rbp), %rax
movslq -0x154(%rbp), %rcx
movq 0x48(%rax,%rcx,8), %rax
movq %rax, -0x130(%rbp)
movq -0x18(%rbp), %rax
movl -0x154(%rbp), %ecx
xorl $0x1, %ecx
movslq %ecx, %rcx
movq 0x48(%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x70(%rcx), %rax
jae 0x74b8
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rax
movq %rax, -0x140(%rbp)
movl -0x134(%rbp), %eax
andl $0x80000, %eax          # imm = 0x80000
cmpl $0x0, %eax
je 0x7633
movq -0x140(%rbp), %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rsi
movl $0x30, %edx
callq 0x2230
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
addq $0x30, %rdi
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rsi
addq $0x30, %rsi
movl $0x30, %edx
callq 0x2230
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rcx
subq $0x1, %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x78(%rax)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x80(%rax)
movl -0x134(%rbp), %eax
andl $0x50000, %eax          # imm = 0x50000
cmpl $0x0, %eax
jne 0x762e
movq -0x18(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x16c(%rbp)
movq -0x18(%rbp), %rax
movl 0xc(%rax), %edx
andl $0x100000, %edx         # imm = 0x100000
movl $0x4, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x14c(%rbp)
movq -0x130(%rbp), %rax
addq $-0x10, %rax
movq %rax, -0x160(%rbp)
movq -0x160(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x38(%rcx), %rcx
subq %rcx, %rax
movq -0x18(%rbp), %rcx
movl 0x14(%rcx), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
andq %rcx, %rax
movl %eax, -0x168(%rbp)
movl -0x168(%rbp), %ecx
movq -0x160(%rbp), %rax
movslq %ecx, %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x160(%rbp)
movl -0x168(%rbp), %eax
addl -0x16c(%rbp), %eax
movl %eax, -0x16c(%rbp)
movq -0x160(%rbp), %rdi
movl -0x16c(%rbp), %eax
movl %eax, %esi
movl -0x14c(%rbp), %edx
callq 0x20f0
cmpl $0x0, %eax
je 0x762c
callq 0x2050
movl (%rax), %eax
movl %eax, -0x14c(%rbp)
jmp 0x77ff
jmp 0x762e
jmp 0x781c
movq -0x130(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0xa8(%rbp)
movq -0x130(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0x140(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0xa0(%rbp), %rdi
addq $0x18, %rdi
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rsi
movl $0x30, %edx
callq 0x2230
leaq -0xa0(%rbp), %rdi
addq $0x18, %rdi
addq $0x30, %rdi
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rsi
addq $0x30, %rsi
movl $0x30, %edx
callq 0x2230
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
subq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rbp)
movq $0x10, -0x148(%rbp)
leaq -0xa0(%rbp), %rax
addq -0x148(%rbp), %rax
movq %rax, -0x160(%rbp)
movl $0x88, %eax
subq -0x148(%rbp), %rax
movl %eax, -0x150(%rbp)
movq -0x130(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x38(%rcx), %rcx
subq %rcx, %rax
addq -0x148(%rbp), %rax
movq %rax, -0x148(%rbp)
movl -0x134(%rbp), %eax
andl $0x50000, %eax          # imm = 0x50000
cmpl $0x0, %eax
je 0x7736
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x170(%rbp)
jmp 0x7743
movq -0x18(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x170(%rbp)
movl -0x170(%rbp), %eax
movl %eax, -0x164(%rbp)
movl -0x164(%rbp), %edi
movq -0x160(%rbp), %rsi
movslq -0x150(%rbp), %rdx
movq -0x148(%rbp), %rcx
callq 0x2290
movl %eax, -0x14c(%rbp)
movl -0x14c(%rbp), %eax
cmpl -0x150(%rbp), %eax
je 0x781a
cmpl $0x0, -0x14c(%rbp)
jge 0x779f
callq 0x2050
movl (%rax), %eax
movl %eax, -0x174(%rbp)
jmp 0x77ac
movl $0x5, %eax
movl %eax, -0x174(%rbp)
jmp 0x77ac
movl -0x174(%rbp), %eax
movl %eax, -0x14c(%rbp)
cmpl $0x4, -0x14c(%rbp)
jne 0x77c3
jmp 0x774f
movq -0xb0(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %edi
movq -0x160(%rbp), %rsi
movslq -0x150(%rbp), %rdx
movq -0x148(%rbp), %rcx
callq 0x2290
movl %eax, -0x168(%rbp)
movq -0x18(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x80000000, %ecx       # imm = 0x80000000
movl %ecx, 0xc(%rax)
movl -0x14c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x7842
jmp 0x781c
movq -0x18(%rbp), %rax
cmpq $0x0, 0x40(%rax)
je 0x783b
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq %rcx, 0x30(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
nop