// File: /workspace/github_c_makefile_star2_O3/Carben-dev[P]ext2fs-simple-utilities/ext2_utils.c
// Function: each_checker_rec
int each_checker_rec(int curr_inode_num,
                     int parent_inode_num,
                     unsigned char *ft_type_ptr) {
    struct ext2_inode *curr_inode = inode_table + curr_inode_num - 1;
    int num_fixed = 0;
    char inode_type;
    char entry_type;
    
    // check if file type in dir_entry and inode consistent
    if ((curr_inode->i_mode & EXT2_S_IFLNK) == EXT2_S_IFLNK) {
        inode_type = 's';
    } else if (curr_inode->i_mode & EXT2_S_IFREG) {
        inode_type = 'f';
    } else if (curr_inode->i_mode & EXT2_S_IFDIR) {
        inode_type = 'd';
    } else {
        exit(-1);
    }
    
    switch (*ft_type_ptr) {
        case EXT2_FT_REG_FILE:
            entry_type = 'f';
            break;
        case EXT2_FT_DIR:
            entry_type = 'd';
            break;
        case EXT2_FT_SYMLINK:
            entry_type = 's';
            break;
        default:
            exit(-1);
            break;
    }
    
    if (entry_type != inode_type) {
        if (inode_type == 'f') {
            *ft_type_ptr = EXT2_FT_REG_FILE;
        } else if (inode_type == 'd') {
            *ft_type_ptr = EXT2_FT_DIR;
        } else if (inode_type == 's') {
            *ft_type_ptr = EXT2_FT_SYMLINK;
        }
        num_fixed++;
        printf("Fixed: Entry type vs inode mismatch: inode [%d]\n", curr_inode_num);
    }
    
    // check if inode bitmap consistent
    // reuse function from restore
    if (restore_inode_bitmap(curr_inode_num) != -1) {
        num_fixed++;
        printf("Fixed: inode [%d] not marked as in-use\n", curr_inode_num);
    }
    
    // check if block bitmap consistent
    int *curr_inode_iblock_array = read_i_block_into_array(curr_inode);
    int i = 0;
    while (curr_inode_iblock_array[i] != -1) {
        if (restore_block_bitmap(curr_inode_iblock_array[i]) != -1) {
            num_fixed++;
            printf("Fixed: %d in-use data blocks not marked in data bitmap for inode: [%d]\n", curr_inode_iblock_array[i], curr_inode_num);
        }
        i++;
    }
    
    // check if dtime is 0
    if (curr_inode->i_dtime != 0) {
        curr_inode->i_dtime = 0;
        num_fixed++;
        printf("Fixed: valid inode marked for deletion: [%d]\n", curr_inode_num);
    }
    
    /*
     *  Base case curr_inode is regfile or symlinks
     */
    if (inode_type != 'd') { // not dir then is f or s
        return num_fixed;
    }
    
    /*
     *  Recursive part
     *  curr_inode is dir
     */
    i = 0;
    while (curr_inode_iblock_array[i] != -1) {
        unsigned char *curr_entry_data = disk + EXT2_BLOCK_SIZE * curr_inode_iblock_array[i];
        int curr_off = 0;
        struct ext2_dir_entry *entry;
        
        while (curr_off < EXT2_BLOCK_SIZE) {
            entry = (struct ext2_dir_entry *)(curr_entry_data + curr_off);
            if (entry->rec_len == EXT2_BLOCK_SIZE) {
                break;
            }
            if ((entry->inode != parent_inode_num) &&
                (entry->inode != curr_inode_num)) { // skip "." and ".." and "lost+found"
                num_fixed += each_checker_rec(entry->inode, curr_inode_num, &entry->file_type);
            }
            
            curr_off += entry->rec_len;
        }
        
        i++;
    }
    
    
    return num_fixed;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %esi, 0xc(%rsp)
movl %edi, %ebp
leaq 0x2d1d(%rip), %rax      # 0x50b8
movq (%rax), %rbx
movslq %edi, %r12
shlq $0x7, %r12
movzwl -0x80(%rbx,%r12), %ecx
movl $0xa000, %esi           # imm = 0xA000
movl %ecx, %eax
andl %esi, %eax
cmpl %esi, %eax
jne 0x23c1
movl $0x73, %esi
xorl %ecx, %ecx
jmp 0x23e8
testw %cx, %cx
js 0x23e1
movzwl %cx, %ecx
cmpl $0x3fff, %ecx           # imm = 0x3FFF
jbe 0x258c
movl $0x64, %esi
movb $0x1, %r15b
xorl %ecx, %ecx
jmp 0x23eb
movl $0x66, %esi
movb $0x1, %cl
xorl %r15d, %r15d
movzbl (%rdx), %edi
cmpl $0x1, %edi
je 0x240f
cmpl $0x7, %edi
je 0x2408
cmpl $0x2, %edi
jne 0x258c
movl $0x64, %edi
jmp 0x2414
movl $0x73, %edi
jmp 0x2414
movl $0x66, %edi
xorl %r14d, %r14d
cmpl %esi, %edi
je 0x245c
movl %ecx, %esi
orb %r15b, %sil
jne 0x242c
movzwl %ax, %eax
cmpl $0xa000, %eax           # imm = 0xA000
jne 0x2446
xorl %eax, %eax
testb %r15b, %r15b
sete %al
leal (%rax,%rax,4), %eax
addl $0x2, %eax
testb %cl, %cl
movl $0x1, %ecx
cmovel %eax, %ecx
movb %cl, (%rdx)
leaq 0xc23(%rip), %rdi       # 0x3070
movl %ebp, %esi
xorl %eax, %eax
callq 0x10a0
movl $0x1, %r14d
movl %r15d, 0x8(%rsp)
leaq (%rbx,%r12), %r15
addq $-0x80, %r15
movl %ebp, %edi
callq 0x1dbe
cmpl $-0x1, %eax
je 0x2488
incl %r14d
leaq 0xc22(%rip), %rdi       # 0x30a1
movl %ebp, %esi
xorl %eax, %eax
callq 0x10a0
addq %r12, %rbx
movq %r15, %rdi
callq 0x148d
movl (%rax), %r12d
cmpl $-0x1, %r12d
movq %rax, 0x10(%rsp)
je 0x24d8
leaq 0x4(%rax), %r15
movl %r12d, %r13d
movl %r13d, %edi
callq 0x1e2a
cmpl $-0x1, %eax
je 0x24cb
incl %r14d
leaq 0xc0a(%rip), %rdi       # 0x30c9
movl %r13d, %esi
movl %ebp, %edx
xorl %eax, %eax
callq 0x10a0
movl (%r15), %r13d
addq $0x4, %r15
cmpl $-0x1, %r13d
jne 0x24a8
cmpl $0x0, -0x6c(%rbx)
je 0x24f8
movl $0x0, -0x6c(%rbx)
incl %r14d
leaq 0xc22(%rip), %rdi       # 0x3111
movl %ebp, %esi
xorl %eax, %eax
callq 0x10a0
movl 0x8(%rsp), %ecx
cmpl $-0x1, %r12d
sete %al
xorb $0x1, %cl
orb %al, %cl
jne 0x257a
xorl %r13d, %r13d
movslq %r12d, %r12
shlq $0xa, %r12
leaq 0x2b95(%rip), %rax      # 0x50b0
addq (%rax), %r12
xorl %r15d, %r15d
movl %r15d, %ebx
movzwl 0x4(%r12,%rbx), %eax
cmpl $0x400, %eax            # imm = 0x400
je 0x2567
addq %r12, %rbx
movl (%rbx), %edi
cmpl 0xc(%rsp), %edi
sete %cl
cmpl %ebp, %edi
sete %dl
orb %cl, %dl
jne 0x2558
leaq 0x7(%rbx), %rdx
movl %ebp, %esi
callq 0x2380
addl %eax, %r14d
movzwl 0x4(%rbx), %eax
movzwl %ax, %eax
addl %eax, %r15d
cmpl $0x400, %r15d           # imm = 0x400
jb 0x2521
movq 0x10(%rsp), %rax
movl 0x4(%rax,%r13,4), %r12d
incq %r13
cmpl $-0x1, %r12d
jne 0x250d
movl %r14d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1110