// File: chlunde[P]qtar/firstblock.cc
// Function: firstblock(char const*)
uint64_t firstblock(const char *fname)
{
	int ret, fd;
	struct fiemap *fiemap;
	struct fiemap_extent *extent;
	unsigned long block = 0;
	char buf[sizeof(struct fiemap) + sizeof(struct fiemap_extent)] = {0};

	fd = open(fname, O_RDONLY);
	if (fd == -1) {
		printf("Open failed: %s: %s\n", fname, strerror(errno));
		return 0;
	}

	if (use_fibmap) {
		ret = ioctl(fd, FIBMAP, &block);
		if (ret == 0) {
			close(fd);
			return block;
		}
		printf("FIBMAP failed: %s: %s\n", fname, strerror(errno));
		use_fibmap = 0;
	}

	fiemap = (struct fiemap *)buf;

	fiemap->fm_start = 0;
	fiemap->fm_length = 4096;
	fiemap->fm_flags = 0;
	fiemap->fm_extent_count = 1;

	ret = ioctl(fd, FS_IOC_FIEMAP, fiemap);
	if (ret == -1) {
		if (errno == EBADR) {
			printf("Kernel does not the flags: 0x%x\n",
				fiemap->fm_flags);
			close(fd);
			return -1;
		}
		printf("fiemap error %d: \"%s\"\n", errno,
			strerror(errno));
		close(fd);
		return 0;
	}


	close(fd);

	if (fiemap->fm_extent_count == 0 || fiemap->fm_mapped_extents == 0) {
#if 0
		printf("extent_count == 0: %s\n", fname);
#endif
		return 0;
	}
	extent = &fiemap->fm_extents[0];
	return extent->fe_physical >> 4;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movq $0x0, -0x30(%rbp)
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x58, %edx
callq 0x3190
movq -0x10(%rbp), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x3220
movl %eax, -0x18(%rbp)
cmpl $-0x1, -0x18(%rbp)
jne 0xc70c
movq -0x10(%rbp), %rax
movq %rax, -0x98(%rbp)
callq 0x3040
movl (%rax), %edi
callq 0x30f0
movq -0x98(%rbp), %rsi
movq %rax, %rdx
leaq 0xa08(%rip), %rdi       # 0xd100
movb $0x0, %al
callq 0x3050
movq $0x0, -0x8(%rbp)
jmp 0xc88b
cmpl $0x0, 0x6bad(%rip)      # 0x132c0
je 0xc77f
movl -0x18(%rbp), %edi
movl $0x1, %esi
leaq -0x30(%rbp), %rdx
movb $0x0, %al
callq 0x33d0
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0xc746
movl -0x18(%rbp), %edi
callq 0x3520
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc88b
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
callq 0x3040
movl (%rax), %edi
callq 0x30f0
movq -0xa0(%rbp), %rsi
movq %rax, %rdx
leaq 0x9a7(%rip), %rdi       # 0xd115
movb $0x0, %al
callq 0x3050
movl $0x0, 0x6b41(%rip)      # 0x132c0
leaq -0x90(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq $0x0, (%rax)
movq -0x20(%rbp), %rax
movq $0x1000, 0x8(%rax)      # imm = 0x1000
movq -0x20(%rbp), %rax
movl $0x0, 0x10(%rax)
movq -0x20(%rbp), %rax
movl $0x1, 0x18(%rax)
movl -0x18(%rbp), %edi
movq -0x20(%rbp), %rdx
movl $0xc020660b, %esi       # imm = 0xC020660B
movb $0x0, %al
callq 0x33d0
movl %eax, -0x14(%rbp)
cmpl $-0x1, -0x14(%rbp)
jne 0xc849
callq 0x3040
cmpl $0x35, (%rax)
jne 0xc807
movq -0x20(%rbp), %rax
movl 0x10(%rax), %esi
leaq 0x941(%rip), %rdi       # 0xd12c
movb $0x0, %al
callq 0x3050
movl -0x18(%rbp), %edi
callq 0x3520
movq $-0x1, -0x8(%rbp)
jmp 0xc88b
callq 0x3040
movl (%rax), %eax
movl %eax, -0xa4(%rbp)
callq 0x3040
movl (%rax), %edi
callq 0x30f0
movl -0xa4(%rbp), %esi
movq %rax, %rdx
leaq 0x91d(%rip), %rdi       # 0xd14d
movb $0x0, %al
callq 0x3050
movl -0x18(%rbp), %edi
callq 0x3520
movq $0x0, -0x8(%rbp)
jmp 0xc88b
movl -0x18(%rbp), %edi
callq 0x3520
movq -0x20(%rbp), %rax
cmpl $0x0, 0x18(%rax)
je 0xc865
movq -0x20(%rbp), %rax
cmpl $0x0, 0x14(%rax)
jne 0xc86f
movq $0x0, -0x8(%rbp)
jmp 0xc88b
movq -0x20(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x4, %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xb0, %rsp
popq %rbp
retq