// File: /workspace/github_c_makefile_star2_O0/Carben-dev[P]ext2fs-simple-utilities/ext2_utils.c
// Function: add_to_dir_entry
void add_to_dir_entry(struct ext2_inode *parent_inode,
                      unsigned int inode_num,
                      char *name,
                      unsigned char type)
{
    int parent_inode_last_block_index = (parent_inode->i_blocks / 2) - 1;
    unsigned char *parent_inode_data = disk + EXT2_BLOCK_SIZE * parent_inode->i_block[parent_inode_last_block_index];
    
    // Find out the last entry
    int curr_entry_off = 0;
    struct ext2_dir_entry *entry;
    while (1) {
        entry = (struct ext2_dir_entry *)(parent_inode_data + curr_entry_off);
        if (entry->rec_len + curr_entry_off == EXT2_BLOCK_SIZE) {
            
            //handle case: no space for last entry
            if (entry->rec_len - sizeof(struct ext2_dir_entry) - entry->name_len < sizeof(struct ext2_dir_entry) + strlen(name)) {
                // allocate new block on datablock
                int new_block_number = dalloc();
                if (new_block_number < 0) {
                    exit(ENOSPC);
                }
                
                // add this block back to parent inode
                parent_inode->i_block[parent_inode_last_block_index + 1] = new_block_number;
                parent_inode->i_blocks += 2;
                
                // add entry in this block
                entry = (struct ext2_dir_entry *)(disk + EXT2_BLOCK_SIZE * new_block_number);
                // Build entry in parent for new dir
                entry->file_type    = type;
                entry->inode        = inode_num;
                entry->name_len     = strlen(name);
                entry->rec_len      = EXT2_BLOCK_SIZE;
                memcpy(entry->name, name, entry->name_len);
                // align name, padding null char to the end of entry->name
                int padding_len = 4 - (entry->name_len % 4);
                memset(entry->name + entry->name_len, '\0', padding_len);
                
                // Update link count for self
                struct ext2_inode *self_inode = inode_table + (inode_num - 1);
                self_inode->i_links_count++;
                return;
            }
            
            
            break;
        }
        curr_entry_off += entry->rec_len;
    }
    
    // Update the last entry's rec_len
    int last_entry_len = sizeof(struct ext2_dir_entry) + entry->name_len;
    if (last_entry_len % 4) {   // align
        last_entry_len += 4 - (last_entry_len % 4);
    }
    entry->rec_len = last_entry_len;
    
    // Move to next
    curr_entry_off += entry->rec_len;
    entry = (struct ext2_dir_entry *)(parent_inode_data + curr_entry_off);
    
    // Build entry in parent for new dir
    entry->file_type    = type;
    entry->inode        = inode_num;
    entry->name_len     = strlen(name);
    entry->rec_len      = EXT2_BLOCK_SIZE - curr_entry_off;
    memcpy(entry->name, name, entry->name_len);
    // align name, padding null char to the end of entry->name
    int padding_len = 4 - (entry->name_len % 4);
    memset(entry->name + entry->name_len, '\0', padding_len);
    
    // Update link count for self
    struct ext2_inode *self_inode = inode_table + (inode_num - 1);
    self_inode->i_links_count++;
    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb %cl, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movb %al, -0x19(%rbp)
movq -0x8(%rbp), %rax
movl 0x1c(%rax), %eax
shrl %eax
subl $0x1, %eax
movl %eax, -0x20(%rbp)
leaq 0x42f2(%rip), %rax      # 0x60b0
movq (%rax), %rax
movq -0x8(%rbp), %rcx
movslq -0x20(%rbp), %rdx
movl 0x28(%rcx,%rdx,4), %ecx
shll $0xa, %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
addl -0x2c(%rbp), %eax
cmpl $0x400, %eax            # imm = 0x400
jne 0x1f48
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
subq $0x8, %rax
movq -0x38(%rbp), %rcx
movzbl 0x6(%rcx), %ecx
subq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rdi
callq 0x1070
movq %rax, %rcx
movq -0x60(%rbp), %rax
addq $0x8, %rcx
cmpq %rcx, %rax
jae 0x1f46
callq 0x1ba0
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jge 0x1e55
movl $0x1c, %edi
callq 0x1120
movl -0x3c(%rbp), %edx
movq -0x8(%rbp), %rax
movl -0x20(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, 0x28(%rax,%rcx,4)
movq -0x8(%rbp), %rax
movl 0x1c(%rax), %ecx
addl $0x2, %ecx
movl %ecx, 0x1c(%rax)
leaq 0x4233(%rip), %rax      # 0x60b0
movq (%rax), %rax
movl -0x3c(%rbp), %ecx
shll $0xa, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movb -0x19(%rbp), %cl
movq -0x38(%rbp), %rax
movb %cl, 0x7(%rax)
movl -0xc(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, (%rax)
movq -0x18(%rbp), %rdi
callq 0x1070
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, 0x6(%rax)
movq -0x38(%rbp), %rax
movw $0x400, 0x4(%rax)       # imm = 0x400
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
movq -0x18(%rbp), %rsi
movq -0x38(%rbp), %rax
movzbl 0x6(%rax), %eax
movl %eax, %edx
callq 0x10d0
movq -0x38(%rbp), %rax
movzbl 0x6(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl $0x4, %eax
subl %edx, %eax
movl %eax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
movq -0x38(%rbp), %rax
movzbl 0x6(%rax), %eax
cltq
addq %rax, %rdi
movslq -0x40(%rbp), %rdx
xorl %esi, %esi
callq 0x10b0
leaq 0x419d(%rip), %rax      # 0x60b8
movq (%rax), %rax
movl -0xc(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
shlq $0x7, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movw 0x1a(%rax), %cx
addw $0x1, %cx
movw %cx, 0x1a(%rax)
jmp 0x2077
jmp 0x1f5b
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
jmp 0x1de0
movq -0x38(%rbp), %rax
movzbl 0x6(%rax), %eax
addq $0x8, %rax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
je 0x1f92
movl -0x4c(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl $0x4, %eax
subl %edx, %eax
addl -0x4c(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movw %ax, %cx
movq -0x38(%rbp), %rax
movw %cx, 0x4(%rax)
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movb -0x19(%rbp), %cl
movq -0x38(%rbp), %rax
movb %cl, 0x7(%rax)
movl -0xc(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, (%rax)
movq -0x18(%rbp), %rdi
callq 0x1070
movb %al, %cl
movq -0x38(%rbp), %rax
movb %cl, 0x6(%rax)
movl $0x400, %eax            # imm = 0x400
subl -0x2c(%rbp), %eax
movw %ax, %cx
movq -0x38(%rbp), %rax
movw %cx, 0x4(%rax)
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
movq -0x18(%rbp), %rsi
movq -0x38(%rbp), %rax
movzbl 0x6(%rax), %eax
movl %eax, %edx
callq 0x10d0
movq -0x38(%rbp), %rax
movzbl 0x6(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl $0x4, %eax
subl %edx, %eax
movl %eax, -0x50(%rbp)
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
movq -0x38(%rbp), %rax
movzbl 0x6(%rax), %eax
cltq
addq %rax, %rdi
movslq -0x50(%rbp), %rdx
xorl %esi, %esi
callq 0x10b0
leaq 0x4067(%rip), %rax      # 0x60b8
movq (%rax), %rax
movl -0xc(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
shlq $0x7, %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movw 0x1a(%rax), %cx
addw $0x1, %cx
movw %cx, 0x1a(%rax)
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)