// File: /workspace/github_c_makefile_star2_O3/sheheryarbutt[P]Ext2-File-System/ext2_checker.c
// Function: main
int main(int argc, char **argv) {

    if(argc != 2) {
        fprintf(stderr, "Usage: ext2_checker <image file name>\n");
        exit(1);
    }
    int fd = open(argv[1], O_RDWR);

    disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(disk == MAP_FAILED) {
	perror("mmap");
	exit(1);
    }
    int fixes=0;
    sb = (struct ext2_super_block *)(disk + EXT2_BLOCK_SIZE);
    gd = (struct ext2_group_desc *)(disk + (2*EXT2_BLOCK_SIZE));
	inode_table = (struct ext2_inode *)(disk + (5*EXT2_BLOCK_SIZE));

	int actual_free_inodes=0;
	int actual_free_blocks=0;
	unsigned int * bb=(unsigned int *)(disk + (EXT2_BLOCK_SIZE*3));

	for (int i=0; i<4; i++){ //4= 128/32 because 128 is the total block and 32 is 4 bytes=unsigned int
		int j=0;	
		while(j<32){
			if (bb[i]&(1<<j)){
				actual_free_blocks++;
			}	
			j++;
		}	
	}
	int j=0;
	unsigned int * ib = (unsigned int *)(disk+(EXT2_BLOCK_SIZE*4));
	while(j<32){
			if (ib[0]&(1<<j)){
				actual_free_inodes++;
			}
			j++;
	}
	int diff;
	if (sb->s_free_blocks_count!=actual_free_blocks){
		diff=abs(sb->s_free_blocks_count-actual_free_blocks);
		sb->s_free_blocks_count=actual_free_blocks;
		fixes+=diff;
		printf("Fixed: superblock's free blocks counter was off by %d compared to the bitmap\n",diff);
	}
	if (sb->s_free_inodes_count!=actual_free_inodes){
		diff=abs(sb->s_free_inodes_count-actual_free_inodes);
		sb->s_free_inodes_count=actual_free_inodes;
		fixes+=diff;
		printf("Fixed: superblock's free inodes counter was off by %d compared to the bitmap\n",diff);
	}
	if (gd->bg_free_blocks_count!=actual_free_blocks){
		diff=abs(gd->bg_free_blocks_count-actual_free_blocks);
		gd->bg_free_blocks_count=actual_free_blocks;
		fixes+=diff;
		printf("Fixed: block group's free blocks counter was off by %d compared to the bitmap\n",diff);
	}
	if (gd->bg_free_inodes_count!=actual_free_inodes){
		diff=abs(gd->bg_free_inodes_count-actual_free_inodes);
		gd->bg_free_inodes_count=actual_free_inodes;
		fixes+=diff;
		printf("Fixed: block group's free inodes counter was off by %d compared to the bitmap\n",diff);
	}
	if(fixes!=0){
		printf("%d file system inconsistencies repaired!\n",fixes);
	}else{
		printf("No file system inconsistencies detected!\n");
	}			   	   
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
cmpl $0x2, %edi
jne 0x1403
movq 0x8(%rsi), %rdi
xorl %r14d, %r14d
movl $0x2, %esi
xorl %eax, %eax
callq 0x10f0
movl $0x20000, %esi          # imm = 0x20000
xorl %edi, %edi
movl $0x3, %edx
movl $0x1, %ecx
movl %eax, %r8d
xorl %r9d, %r9d
callq 0x1080
movq %rax, 0x2dfb(%rip)      # 0x40b0
cmpq $-0x1, %rax
je 0x1408
leaq 0x400(%rax), %rcx
movq %rcx, 0x2deb(%rip)      # 0x40b8
leaq 0x800(%rax), %rdx
movq %rdx, 0x2de5(%rip)      # 0x40c0
movq %rax, %rdx
addq $0x1400, %rdx           # imm = 0x1400
movq %rdx, 0x2ddc(%rip)      # 0x40c8
xorl %edx, %edx
movl 0xc00(%rax,%rdx,4), %esi
xorl %edi, %edi
btl %edi, %esi
adcl $0x0, %r14d
incl %edi
cmpl $0x20, %edi
jne 0x12f7
incq %rdx
cmpq $0x4, %rdx
jne 0x12ee
movl 0x1000(%rax), %edx
xorl %esi, %esi
xorl %r15d, %r15d
btl %esi, %edx
adcl $0x0, %r15d
incl %esi
cmpl $0x20, %esi
jne 0x1319
movl 0x40c(%rax), %edx
xorl %ebx, %ebx
subl %r14d, %edx
je 0x1359
movl %edx, %ebx
negl %ebx
cmovsl %edx, %ebx
movl %r14d, 0x40c(%rax)
leaq 0xce7(%rip), %rdi       # 0x2030
movl %ebx, %esi
xorl %eax, %eax
callq 0x1090
movq 0x2d5f(%rip), %rcx      # 0x40b8
movl 0x10(%rcx), %eax
subl %r15d, %eax
je 0x137c
movl %eax, %esi
negl %esi
cmovsl %eax, %esi
movl %r15d, 0x10(%rcx)
addl %esi, %ebx
leaq 0xd09(%rip), %rdi       # 0x207e
xorl %eax, %eax
callq 0x1090
movq 0x2d3d(%rip), %rax      # 0x40c0
movzwl 0xc(%rax), %ecx
subl %r14d, %ecx
je 0x13af
movl %ecx, %esi
negl %esi
cmovsl %ecx, %esi
movw %r14w, 0xc(%rax)
addl %esi, %ebx
leaq 0xd2b(%rip), %rdi       # 0x20cc
xorl %eax, %eax
callq 0x1090
movq 0x2d11(%rip), %rax      # 0x40c0
movzwl 0xe(%rax), %ecx
subl %r15d, %ecx
je 0x13d4
movl %ecx, %esi
negl %esi
cmovsl %ecx, %esi
movw %r15w, 0xe(%rax)
addl %esi, %ebx
leaq 0xd4e(%rip), %rdi       # 0x211b
xorl %eax, %eax
callq 0x1090
testl %ebx, %ebx
je 0x13ea
leaq 0xd8b(%rip), %rdi       # 0x216a
movl %ebx, %esi
xorl %eax, %eax
callq 0x1090
jmp 0x13f6
leaq 0xda3(%rip), %rdi       # 0x2194
callq 0x1060
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
callq 0x1140
callq 0x1168
nopl (%rax)