// File: /workspace/github_c_makefile_star2_O2/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, %ebx
movl %edi, %ebp
leaq 0x2f5f(%rip), %rax      # 0x50b8
movq (%rax), %r13
movslq %edi, %r12
shlq $0x7, %r12
movzwl -0x80(%r13,%r12), %ecx
movl %ecx, %eax
andl $0xa000, %eax           # imm = 0xA000
pushq $0x66
popq %rsi
cmpw $0xa000, %ax            # imm = 0xA000
jne 0x2183
pushq $0x73
popq %rdi
xorl %ecx, %ecx
xorl %r15d, %r15d
jmp 0x21a4
testw %cx, %cx
js 0x219d
cmpw $0x3fff, %cx            # imm = 0x3FFF
jbe 0x2335
pushq $0x64
popq %rdi
movb $0x1, %r15b
xorl %ecx, %ecx
jmp 0x21a4
movb $0x1, %cl
xorl %r15d, %r15d
movl %esi, %edi
movzbl (%rdx), %r8d
cmpl $0x1, %r8d
je 0x21c5
cmpl $0x7, %r8d
je 0x21c2
cmpl $0x2, %r8d
jne 0x2335
pushq $0x64
jmp 0x21c4
pushq $0x73
popq %rsi
xorl %r14d, %r14d
cmpl %edi, %esi
je 0x2205
movl %ecx, %esi
orb %r15b, %sil
jne 0x21d9
cmpw $0xa000, %ax            # imm = 0xA000
jne 0x21f1
xorl %eax, %eax
testb %r15b, %r15b
sete %al
leal (%rax,%rax,4), %eax
addl $0x2, %eax
testb %cl, %cl
pushq $0x1
popq %rcx
cmovel %eax, %ecx
movb %cl, (%rdx)
pushq $0x1
popq %r14
leaq 0xe42(%rip), %rdi       # 0x303e
movl %ebp, %esi
xorl %eax, %eax
callq 0x10a0
movl %r15d, 0x4(%rsp)
leaq (%r12,%r13), %r15
addq $-0x80, %r15
movl %ebp, %edi
callq 0x1d2f
cmpl $-0x1, %eax
je 0x2231
incl %r14d
leaq 0xe47(%rip), %rdi       # 0x306f
movl %ebp, %esi
xorl %eax, %eax
callq 0x10a0
addq %r12, %r13
movq %r13, 0x8(%rsp)
movq %r15, %rdi
callq 0x1460
leaq 0xe4f(%rip), %r12       # 0x3097
movq %rax, 0x10(%rsp)
movq %rax, %r15
movl (%r15), %r13d
cmpl $-0x1, %r13d
je 0x227e
movl %r13d, %edi
callq 0x1d8b
cmpl $-0x1, %eax
je 0x2278
incl %r14d
movq %r12, %rdi
movl %r13d, %esi
movl %ebp, %edx
xorl %eax, %eax
callq 0x10a0
addq $0x4, %r15
jmp 0x2250
movq 0x8(%rsp), %rax
cmpl $0x0, -0x6c(%rax)
je 0x22a0
andl $0x0, -0x6c(%rax)
incl %r14d
leaq 0xe48(%rip), %rdi       # 0x30df
movl %ebp, %esi
xorl %eax, %eax
callq 0x10a0
movl 0x4(%rsp), %eax
testb %al, %al
je 0x2323
xorl %ecx, %ecx
movq 0x10(%rsp), %rax
movslq (%rax,%rcx,4), %r13
cmpq $-0x1, %r13
je 0x2323
movq %rcx, 0x8(%rsp)
shlq $0xa, %r13
leaq 0x2de7(%rip), %rax      # 0x50b0
addq (%rax), %r13
xorl %r15d, %r15d
cmpl $0x3ff, %r15d           # imm = 0x3FF
ja 0x2319
movl %r15d, %r12d
movzwl 0x4(%r13,%r12), %eax
cmpw $0x400, %ax             # imm = 0x400
je 0x2319
addq %r13, %r12
movl (%r12), %edi
cmpl %ebx, %edi
sete %cl
cmpl %ebp, %edi
sete %dl
orb %cl, %dl
jne 0x2311
leaq 0x7(%r12), %rdx
movl %ebp, %esi
callq 0x2140
addl %eax, %r14d
movzwl 0x4(%r12), %eax
movzwl %ax, %eax
addl %eax, %r15d
jmp 0x22cf
movq 0x8(%rsp), %rcx
incq %rcx
jmp 0x22aa
movl %r14d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $-0x1
popq %rdi
callq 0x1110