// File: williewillus[P]panda_scratchpad/src/wrapper/wrapper.cpp
// Function: wrapper::RecordCmFsOps::CmFallocate(int, int, long, long)
int RecordCmFsOps::CmFallocate(const int fd, const int mode, const off_t offset,
    off_t len) {
  struct stat pre_stat;
  const int pre_stat_res = fns_->FnStat(fd_map_[fd].c_str(), &pre_stat);
  if (pre_stat_res < 0) {
    return pre_stat_res;
  }

  const int res = fns_->FnFallocate(fd, mode, offset, len);
  if (res < 0) {
    return res;
  }

  struct stat post_stat;
  const int post_stat_res = fns_->FnStat(fd_map_[fd].c_str(), &post_stat);
  if (post_stat_res < 0) {
    return post_stat_res;
  }

  DiskMod mod;

  if (pre_stat.st_size != post_stat.st_size ||
      pre_stat.st_blocks != post_stat.st_blocks) {
    mod.mod_type = DiskMod::kDataMetadataMod;
  } else {
    mod.mod_type = DiskMod::kDataMod;
  }

  mod.path = fd_map_[fd];
  mod.file_mod_location = offset;
  mod.file_mod_len = len;

  if (mode & FALLOC_FL_PUNCH_HOLE) {
    // TODO(ashmrtn): Do we want this here? I'm not sure if it will cause
    // failures that we don't want, though man fallocate(2) says that
    // FALLOC_FL_PUNCH_HOLE must also have FALLOC_FL_KEEP_SIZE.
    assert(mode & FALLOC_FL_KEEP_SIZE);
    mod.mod_opts = DiskMod::kPunchHoleKeepSizeOpt;
  } else if (mode & FALLOC_FL_COLLAPSE_RANGE) {
    mod.mod_opts = DiskMod::kCollapseRangeOpt;
  } else if (mode & FALLOC_FL_ZERO_RANGE) {
    if (mode & FALLOC_FL_KEEP_SIZE) {
      mod.mod_opts = DiskMod::kZeroRangeKeepSizeOpt;
    } else {
      mod.mod_opts = DiskMod::kZeroRangeOpt;
    }
    /*
  } else if (mode & FALLOC_FL_INSERT_RANGE) {
    // TODO(ashmrtn): Figure out how to check with glibc defines.
    mod.mod_opts = DiskMod::kInsertRangeOpt;
    */
  } else if (mode & FALLOC_FL_KEEP_SIZE) {
    mod.mod_opts = DiskMod::kFallocateKeepSizeOpt;
  } else {
    mod.mod_opts = DiskMod::kFallocateOpt;
  }

  mods_.push_back(mod);

  return res;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x2d8(%rbp)
movq 0x90(%rdi), %rax
movq %rax, -0x2d0(%rbp)
addq $0x8, %rdi
leaq -0x14(%rbp), %rsi
callq 0x141d0
movq %rax, %rdi
callq 0x6220
movq %rax, -0x2c8(%rbp)
leaq -0xe1(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0x68b0
movq -0x2c8(%rbp), %rsi
movq -0x2c0(%rbp), %rdx
leaq -0xe0(%rbp), %rdi
callq 0x6670
jmp 0x11211
movq -0x2d0(%rbp), %rdi
movq (%rdi), %rax
movq 0x88(%rax), %rax
leaq -0xe0(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq *%rax
movl %eax, -0x2dc(%rbp)
jmp 0x1123a
leaq -0xe0(%rbp), %rdi
callq 0x69d8
leaq -0xe1(%rbp), %rdi
callq 0x6590
movl -0x2dc(%rbp), %eax
movl %eax, -0xbc(%rbp)
cmpl $0x0, -0xbc(%rbp)
jge 0x112b8
movl -0xbc(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x11585
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
jmp 0x112a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x69d8
leaq -0xe1(%rbp), %rdi
callq 0x6590
jmp 0x11591
movq -0x2d8(%rbp), %rax
movq 0x90(%rax), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq (%rdi), %rax
callq *0x60(%rax)
movl %eax, -0xf8(%rbp)
cmpl $0x0, -0xf8(%rbp)
jge 0x112f7
movl -0xf8(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x11585
movq -0x2d8(%rbp), %rdi
movq 0x90(%rdi), %rax
movq %rax, -0x2f8(%rbp)
addq $0x8, %rdi
leaq -0x14(%rbp), %rsi
callq 0x141d0
movq %rax, %rdi
callq 0x6220
movq %rax, -0x2f0(%rbp)
leaq -0x1b1(%rbp), %rdi
movq %rdi, -0x2e8(%rbp)
callq 0x68b0
movq -0x2f0(%rbp), %rsi
movq -0x2e8(%rbp), %rdx
leaq -0x1b0(%rbp), %rdi
callq 0x6670
jmp 0x11357
movq -0x2f8(%rbp), %rdi
movq (%rdi), %rax
movq 0x88(%rax), %rax
leaq -0x1b0(%rbp), %rsi
leaq -0x188(%rbp), %rdx
callq *%rax
movl %eax, -0x2fc(%rbp)
jmp 0x11380
leaq -0x1b0(%rbp), %rdi
callq 0x69d8
leaq -0x1b1(%rbp), %rdi
callq 0x6590
movl -0x2fc(%rbp), %eax
movl %eax, -0x18c(%rbp)
cmpl $0x0, -0x18c(%rbp)
jge 0x113fe
movl -0x18c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x11585
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
jmp 0x113ed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x69d8
leaq -0x1b1(%rbp), %rdi
callq 0x6590
jmp 0x11591
leaq -0x2b8(%rbp), %rdi
callq 0xe650
movq -0x88(%rbp), %rax
cmpq -0x158(%rbp), %rax
jne 0x11427
movq -0x78(%rbp), %rax
cmpq -0x148(%rbp), %rax
je 0x11433
movl $0x1, -0x298(%rbp)
jmp 0x1143d
movl $0x3, -0x298(%rbp)
movq -0x2d8(%rbp), %rdi
addq $0x8, %rdi
leaq -0x14(%rbp), %rsi
callq 0x141d0
movq %rax, -0x308(%rbp)
jmp 0x1145a
movq -0x308(%rbp), %rsi
leaq -0x2b8(%rbp), %rdi
callq 0x6060
jmp 0x1146f
movq -0x20(%rbp), %rax
movq %rax, -0x1e8(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movl -0x18(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x114eb
movl -0x18(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1149d
jmp 0x114df
leaq 0x13960(%rip), %rdi     # 0x24e04
leaq 0x13974(%rip), %rsi     # 0x24e1f
movl $0x1be, %edx            # imm = 0x1BE
leaq 0x1397c(%rip), %rcx     # 0x24e33
callq 0x6390
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xf0(%rbp)
movl %eax, -0xf4(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0xbf60
jmp 0x11591
movl $0x4, -0x294(%rbp)
jmp 0x11557
movl -0x18(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x11502
movl $0x5, -0x294(%rbp)
jmp 0x11555
movl -0x18(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x11530
movl -0x18(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x11524
movl $0x7, -0x294(%rbp)
jmp 0x1152e
movl $0x6, -0x294(%rbp)
jmp 0x11553
movl -0x18(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x11547
movl $0x3, -0x294(%rbp)
jmp 0x11551
movl $0x2, -0x294(%rbp)
jmp 0x11553
jmp 0x11555
jmp 0x11557
movq -0x2d8(%rbp), %rdi
addq $0x78, %rdi
leaq -0x2b8(%rbp), %rsi
callq 0x13df0
jmp 0x11570
movl -0xf8(%rbp), %eax
movl %eax, -0x4(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0xbf60
movl -0x4(%rbp), %eax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
movq -0xf0(%rbp), %rdi
callq 0x68a0
nopl (%rax)