// File: /workspace/github_c_makefile_star2_O3/carlitosmarin[P]Sistema-Ficheros-SOII/./src/ficheros_basico.c
// Function: liberar_bloques_inodo
int liberar_bloques_inodo (unsigned int inodo, unsigned int blogico) {	
	struct inodo in;
	in = leer_inodo(inodo);
	
	//Tipos de punteros
	unsigned int npdirectos = puntD; // Directos = 12
	unsigned int npindirectos0 = tamBloque/sizeof(unsigned int); //en 1024 bytes caben 256 punteros
	unsigned int npindirectos1 = npindirectos0*npindirectos0;
	unsigned int npindirectos2 = npindirectos1*npindirectos0;
	
	int ultBloque = in.tamBytesLogicos/tamBloque, blog = blogico, bAuxiliar; //Ultimo bloque con contenido
	if(ultBloque < blogico) return 0;
	int bucle, bucle2, bucle3;
	int punt[3] = {0,0,0}; //Indica el nivel de cada puntero
	
    unsigned int bufferNivel0[npindirectos0];
    unsigned int bufferNivel1[npindirectos0];
    unsigned int bufferNivel2[npindirectos0];
    unsigned char bufferAuxiliar[tamBloque];
    memset(bufferAuxiliar,0,tamBloque);
    
	int idx;
	
	if(blog < npdirectos) idx = -1; //Si esta en los punteros directos
	else if (blog < npdirectos+npindirectos0) { //Indirectos 0
		idx = 0;
		punt[idx] = blog - npdirectos;
	} else if (blog < npdirectos+npindirectos0+npindirectos1) {
		idx = 1;
		punt[idx-1] = (blog-(npdirectos+npindirectos0))%npindirectos0; //puntero nivel 0
		punt[idx] = (blog-(npdirectos+npindirectos0))/npindirectos0; //puntero nivel 1
	} else if (blog < npdirectos+npindirectos0+npindirectos1+npindirectos2) {
		idx = 2;
		punt[idx-2] = ((blog-(npdirectos+npindirectos0+npindirectos1))%npindirectos1)%npindirectos0; //puntero nivel 0
		punt[idx-1] = ((blog-(npdirectos+npindirectos0+npindirectos1))%npindirectos1)/npindirectos0; //puntero nivel 1
		punt[idx] = (blog-(npdirectos+npindirectos0+npindirectos1))/npindirectos1; //puntero nivel 2
	}
	
	if (idx == -1) {
		for(; blog <= ultBloque && blog < npdirectos; blog++) {
		//PUNTEROS DIRECTOS
		//El bloque logico es uno de los 12 primeros bloques logicos del inodo
			if(in.punterosDirectos[blog] > 0) {
				liberar_bloque(in.punterosDirectos[blog]);
				in.cantBloquesOcupados--;
				in.ctime = time(NULL);
			}
			in.punterosDirectos[blog] = 0; //0 el puntero actual
		}
		idx = 0; //Pasamos a punteros indirectos0
	} 
		//PUNTEROS INDIRECTOS 0
		//El bloque logico esta comprendido entre 12 y el 267 (12+256-1)
	if(idx = 0 && in.punterosIndirectos[idx] != 0) { //Si apunta a algo
		if(bread(in.punterosIndirectos[idx],bufferNivel0) < 0) return -1; //Leer el bloque de punteros de nivel 0
		for(bucle = punt[idx]; blog <= ultBloque && bucle < npindirectos0; bucle++, blog++) {
			if(bufferNivel0[bucle] != 0) {
				liberar_bloque(bufferNivel0[bucle]);
				in.cantBloquesOcupados--;
				in.ctime = time(NULL);
				bufferNivel0[bucle] = 0;
			}
		}
		if(strcmp((const char *)bufferNivel0,(const char *)bufferAuxiliar) == 0) { 
			//No quedan punteros ocupados en el bloque de nivel 0
			liberar_bloque(in.punterosIndirectos[idx]);
			in.punterosIndirectos[0] = 0;
			in.cantBloquesOcupados--;
			in.ctime = time(NULL);
		} else {
			if(bwrite(in.punterosIndirectos[idx],bufferNivel0) < 0) return -2; //Error BWRITE 
			//Escribimos el bloque modificado				
		}
		idx = 1; //Pasamos a punteros indirectos 1
	} else if(idx == 0) {
		blog = npindirectos0 + npdirectos;
		idx = 1;
	}
	//PUNTEROS INDIRECTOS 1
	//El bloque logico esta comprendido entre 268 y el 65.803 (12+256+256²-1)
	if(idx == 1 && in.punterosIndirectos[idx] != 0) {
		if(bread(in.punterosIndirectos[idx],bufferNivel1) < 0) return -1; //Leer el bloque de punteros de nivel 1
		for(bucle = punt[idx]; blog <= ultBloque && bucle < npindirectos0; bucle++){
		bAuxiliar = blog;
		if(bufferNivel1[bucle] != 0) {
			if(bread(bufferNivel1[bucle], bufferNivel0) < 0) return -1;
			for(bucle2 = punt[idx-1]; bAuxiliar <= ultBloque && bucle2 < npindirectos0; bucle2++, bAuxiliar++) {
				if(bufferNivel0[bucle2] != 0) {
					liberar_bloque(bufferNivel0[bucle2]);
					in.cantBloquesOcupados--;
					in.ctime = time(NULL);
					bufferNivel0[bucle2] = 0;
				}	
			}
			if(strcmp((const char *)bufferNivel0,(const char *)bufferAuxiliar) == 0) { 
				//No quedan punteros ocupados en el bloque de nivel 0
				liberar_bloque(bufferNivel1[bucle]);
				bufferNivel1[bucle] = 0;
				in.cantBloquesOcupados--;
				in.ctime = time(NULL);
			} else {
			if(bwrite(bufferNivel1[bucle],bufferNivel0) < 0) return -2; //Error BWRITE 
			//Escribimos el bloque modificado
			}
		} else blog += npindirectos0;
		
		punt[idx-1] = 0;
			
		}
		//Comprobamos si tenemos que liberar los punteros
		if(strcmp((const char *)bufferNivel1,(const char *)bufferAuxiliar) == 0) { 
			liberar_bloque(in.punterosIndirectos[idx]); 
			in.punterosIndirectos[idx] = 0;
			in.cantBloquesOcupados--;
			in.ctime = time(NULL);	
		} else {
			if(bwrite(in.punterosIndirectos[idx],bufferNivel1) < 0) return -2;
		}
		idx = 2; //Pasamos a punteros indirectos 2
	} else if (idx == 1) {
		blog = npdirectos+npindirectos0+npindirectos1;
		idx = 2;
	}
	
	//PUNTEROS INDIRECTOS 2
	//El bloque logico esta comprendido entre 65.804 y el 16.843.019 (12+256+256²+256³-1)
	if(idx == 2 && in.punterosIndirectos[idx] != 0) { 
		if(bread(in.punterosIndirectos[idx],bufferNivel2) < 0) return -1; //Leer el bloque de nivel 2
		for(bucle3 = punt[idx]; blog <= ultBloque && bucle3 < npindirectos0; bucle3++) {
			if(bufferNivel2[bucle3] != 0) {
				if(bread(bufferNivel2[bucle3],bufferNivel1) < 0) return -1;
				for(bucle2 = punt[idx-1]; blog <= ultBloque && bucle2 < npindirectos0; bucle2++) {
					bAuxiliar = blog;
					if(bufferNivel1[bucle2] != 0) {
						if(bread(bufferNivel1[bucle2], bufferNivel0) < 0) return -1;
						for(bucle = punt[idx-2]; bAuxiliar <= ultBloque && bucle < npindirectos0; bucle++, bAuxiliar++) {
							if(bufferNivel0[bucle] != 0) {
								liberar_bloque(bufferNivel0[bucle]);
								in.cantBloquesOcupados--;
								in.ctime = time(NULL);
								bufferNivel0[bucle] = 0;
							}	
						}
						//Comprobar si tenemos  que liberar punteros
						if(strcmp((const char *)bufferNivel0,(const char *)bufferAuxiliar) == 0) { 
							//No quedan punteros ocupados en el bloque de nivel 0
							liberar_bloque(bufferNivel1[bucle2]);
							bufferNivel1[bucle2] = 0;
							in.cantBloquesOcupados--;
							in.ctime = time(NULL);
						} else {
							if(bwrite(bufferNivel1[bucle2],bufferNivel0) < 0) return -2; 
						}	
					}
					blog += npindirectos0;
					punt[idx-2] = 0;
				}
				//Comprobar si tenemos  que liberar punteros
				if(strcmp((const char *)bufferNivel0,(const char *)bufferAuxiliar) == 0) { 
					//No quedan punteros ocupados en el bloque de nivel 0
					liberar_bloque(bufferNivel2[bucle3]);
					bufferNivel2[bucle3] = 0;
					in.cantBloquesOcupados--;
					in.ctime = time(NULL);
				} else {
					if(bwrite(bufferNivel2[bucle3],bufferNivel1) < 0) return -2; 
				}	
			}
			punt[idx-1] = 0;
		}
		//Comprobar si tenemos  que liberar punteros
		if(strcmp((const char *)bufferNivel2,(const char *)bufferAuxiliar) == 0) { 
			//No quedan punteros ocupados en el bloque de nivel 0
			liberar_bloque(in.punterosIndirectos[idx]);
			in.punterosIndirectos[idx] = 0;
			in.cantBloquesOcupados--;
			in.ctime = time(NULL);
		} else {
			if(bwrite(in.punterosIndirectos[idx-1],bufferNivel1) < 0) return -2; 
		}
	}		
		
	if(escribir_inodo(in, inodo) < 0) return -3; //Escribimos el inodo modificado
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4c8, %rsp            # imm = 0x4C8
movl %esi, %r12d
movl %edi, %r14d
leaq -0xf0(%rbp), %rbx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x1995
movl 0x24(%rbx), %edx
movl %edx, %eax
shrl $0xa, %eax
xorl %ecx, %ecx
movl %eax, -0x30(%rbp)
cmpl %r12d, %eax
jb 0x21a3
movl %edx, -0x48(%rbp)
movl %r14d, -0x70(%rbp)
movq %rsp, %rbx
movq %rsp, %r15
addq $-0x400, %r15           # imm = 0xFC00
movq %r15, %rsp
movq %rsp, %r14
addq $-0x400, %r14           # imm = 0xFC00
movq %r14, %rsp
movq %rsp, %r13
addq $-0x400, %r13           # imm = 0xFC00
movq %r13, %rsp
leaq -0x4f0(%rbp), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x10b0
cmpl $0xb, %r12d
movq %r14, -0x60(%rbp)
movl %r12d, %ecx
movq %rbx, -0x40(%rbp)
ja 0x1ce3
movq %r13, -0x50(%rbp)
movl -0xc8(%rbp), %ebx
movq -0xd8(%rbp), %rax
movl %ecx, %r14d
movl -0x30(%rbp), %ecx
cmpl $0xb, %ecx
movl $0xb, %r13d
cmovbl %ecx, %r13d
decq %r14
movl -0xc0(%rbp,%r14,4), %edi
testl %edi, %edi
je 0x1cad
callq 0x18c7
decl %ebx
xorl %edi, %edi
callq 0x1120
movl $0x0, -0xc0(%rbp,%r14,4)
incq %r14
cmpq %r13, %r14
jb 0x1c93
movl %ebx, -0xc8(%rbp)
movq %rax, -0xd8(%rbp)
xorl %ecx, %ecx
xorl %ebx, %ebx
movl $0x0, -0x58(%rbp)
movq -0x60(%rbp), %r14
movq -0x50(%rbp), %r13
jmp 0x1d2d
cmpl $0x10b, %ecx            # imm = 0x10B
ja 0x1cf2
addl $-0xc, %ecx
xorl %ebx, %ebx
jmp 0x1d08
cmpl $0x1010b, %ecx          # imm = 0x1010B
ja 0x1d11
addl $0xfffffef4, %ecx       # imm = 0xFFFFFEF4
movl %ecx, %ebx
movzbl %cl, %ecx
shrl $0x8, %ebx
movl $0x0, -0x58(%rbp)
jmp 0x1d2d
addl $0xfffefef4, %ecx       # imm = 0xFFFEFEF4
movl $0xff, %eax
movl %ecx, %ebx
movl %ecx, %edx
andl %eax, %ecx
shrl $0x8, %ebx
andl %eax, %ebx
shrl $0x10, %edx
movl %edx, -0x58(%rbp)
movl -0x90(%rbp), %edi
testl %edi, %edi
je 0x1eb5
movl %ebx, -0x34(%rbp)
movl %ecx, %ebx
movq %rdi, -0x68(%rbp)
movq %r14, %rsi
callq 0x131d
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
testl %eax, %eax
js 0x219c
movl $0x10c, -0x2c(%rbp)     # imm = 0x10C
cmpl $0x43000, -0x48(%rbp)   # imm = 0x43000
jb 0x1e85
movq %r13, -0x50(%rbp)
movl -0xc8(%rbp), %r13d
movq -0xd8(%rbp), %r12
movl -0x34(%rbp), %ecx
movl %ebx, %ebx
movl $0x10c, -0x2c(%rbp)     # imm = 0x10C
movl (%r14,%rcx,4), %edi
testl %edi, %edi
je 0x1e26
movq %rcx, -0x48(%rbp)
movq %r15, %rsi
callq 0x131d
testl %eax, %eax
js 0x213b
movl -0x2c(%rbp), %r14d
cmpl -0x30(%rbp), %r14d
jg 0x1df0
movl (%r15,%rbx,4), %edi
testl %edi, %edi
je 0x1dd7
callq 0x18c7
decl %r13d
xorl %edi, %edi
callq 0x1120
movq %rax, %r12
movl $0x0, (%r15,%rbx,4)
cmpl -0x30(%rbp), %r14d
jge 0x1df0
leaq 0x1(%rbx), %rax
incl %r14d
cmpq $0xff, %rbx
movq %rax, %rbx
jb 0x1db5
movq %r15, %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x10f0
movq -0x60(%rbp), %r14
movq -0x48(%rbp), %rbx
movl (%r14,%rbx,4), %edi
testl %eax, %eax
je 0x1e30
movq %r15, %rsi
callq 0x12e5
testl %eax, %eax
movl -0x2c(%rbp), %eax
movq %rbx, %rcx
jns 0x1e50
jmp 0x2134
movl -0x2c(%rbp), %eax
addl $0x100, %eax            # imm = 0x100
jmp 0x1e50
callq 0x18c7
movl $0x0, (%r14,%rbx,4)
decl %r13d
xorl %edi, %edi
callq 0x1120
movq %rax, %r12
movl -0x2c(%rbp), %eax
movq %rbx, %rcx
movl %eax, -0x2c(%rbp)
cmpl -0x30(%rbp), %eax
jg 0x1e71
leaq 0x1(%rcx), %rax
movl $0x0, %ebx
cmpq $0xff, %rcx
movq %rax, %rcx
jb 0x1d8b
movl %r13d, -0xc8(%rbp)
movq %r12, -0xd8(%rbp)
xorl %ebx, %ebx
movq -0x50(%rbp), %r13
leaq -0x4f0(%rbp), %rsi
movq %r14, %rdi
callq 0x10f0
testl %eax, %eax
je 0x1ec1
movq -0x68(%rbp), %r12
movl %r12d, %edi
movq %r14, %rsi
callq 0x12e5
testl %eax, %eax
movl %ebx, %ecx
movl -0x34(%rbp), %ebx
jns 0x1ef0
jmp 0x2134
movl $0x1010c, -0x2c(%rbp)   # imm = 0x1010C
xorl %r12d, %r12d
jmp 0x1ef0
movq -0x68(%rbp), %rdi
callq 0x18c7
movl $0x0, -0x90(%rbp)
decl -0xc8(%rbp)
xorl %edi, %edi
callq 0x1120
xorl %r12d, %r12d
movq %rax, -0xd8(%rbp)
movl %ebx, %ecx
movl -0x34(%rbp), %ebx
movl -0x8c(%rbp), %edi
testl %edi, %edi
je 0x216c
movl %ecx, -0x34(%rbp)
movq %r12, -0x68(%rbp)
movl %edi, -0x6c(%rbp)
movq %r13, %rsi
callq 0x131d
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
testl %eax, %eax
js 0x219c
movl -0x2c(%rbp), %r12d
cmpl -0x30(%rbp), %r12d
setle %al
movl -0x58(%rbp), %edx
cmpl $0x100, %edx            # imm = 0x100
setb %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x2111
movq %r13, -0x50(%rbp)
movl -0xc8(%rbp), %r13d
movq -0xd8(%rbp), %rax
movq %rax, -0x48(%rbp)
movl %edx, %ecx
movq -0x50(%rbp), %rax
movl (%rax,%rcx,4), %edi
testl %edi, %edi
je 0x20df
movq %rcx, -0x58(%rbp)
movq %r14, %rsi
callq 0x131d
testl %eax, %eax
js 0x213b
cmpl -0x30(%rbp), %r12d
jg 0x2080
cmpl $0xff, %ebx
movl -0x34(%rbp), %ecx
ja 0x2083
movl %ebx, %r14d
movq -0x60(%rbp), %rax
movl (%rax,%r14,4), %edi
testl %edi, %edi
je 0x205b
movl %ecx, %ebx
movq %r15, %rsi
callq 0x131d
testl %eax, %eax
js 0x213b
cmpl $0xff, %ebx
movl %r12d, -0x2c(%rbp)
ja 0x2004
movl %ebx, %ebx
movq -0x48(%rbp), %rax
movl (%r15,%rbx,4), %edi
testl %edi, %edi
je 0x1fe9
callq 0x18c7
decl %r13d
xorl %edi, %edi
callq 0x1120
movl $0x0, (%r15,%rbx,4)
cmpl -0x30(%rbp), %r12d
jge 0x2008
leaq 0x1(%rbx), %rcx
incl %r12d
cmpq $0xff, %rbx
movq %rcx, %rbx
jb 0x1fca
jmp 0x2008
movq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq %r15, %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x10f0
movq -0x60(%rbp), %rbx
movl (%rbx,%r14,4), %edi
testl %eax, %eax
je 0x203c
movq %r15, %rsi
callq 0x12e5
testl %eax, %eax
movl -0x2c(%rbp), %r12d
jns 0x205b
jmp 0x2134
callq 0x18c7
movl $0x0, (%rbx,%r14,4)
decl %r13d
xorl %edi, %edi
callq 0x1120
movq %rax, -0x48(%rbp)
movl -0x2c(%rbp), %r12d
addl $0x100, %r12d           # imm = 0x100
xorl %ecx, %ecx
cmpl -0x30(%rbp), %r12d
jg 0x2083
leaq 0x1(%r14), %rax
cmpq $0xff, %r14
movq %rax, %r14
jb 0x1f96
jmp 0x2083
movl -0x34(%rbp), %ecx
movl %ecx, -0x34(%rbp)
movq %r15, %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x10f0
movq -0x50(%rbp), %rbx
movq -0x58(%rbp), %r14
movl (%rbx,%r14,4), %edi
testl %eax, %eax
je 0x20bd
movq %r14, %rbx
movq -0x60(%rbp), %r14
movq %r14, %rsi
callq 0x12e5
testl %eax, %eax
movq %rbx, %rcx
jns 0x20df
jmp 0x2134
callq 0x18c7
movl $0x0, (%rbx,%r14,4)
decl %r13d
xorl %edi, %edi
callq 0x1120
movq %rax, -0x48(%rbp)
movq %r14, %rcx
movq -0x60(%rbp), %r14
cmpl -0x30(%rbp), %r12d
jg 0x20fb
leaq 0x1(%rcx), %rax
xorl %ebx, %ebx
cmpq $0xff, %rcx
movq %rax, %rcx
jb 0x1f57
movl %r13d, -0xc8(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x50(%rbp), %r13
leaq -0x4f0(%rbp), %rsi
movq %r13, %rdi
callq 0x10f0
testl %eax, %eax
je 0x2146
movq -0x68(%rbp), %rdi
movq %r14, %rsi
callq 0x12e5
testl %eax, %eax
jns 0x216c
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
jmp 0x219c
movq -0x40(%rbp), %rax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
jmp 0x21a0
movl -0x6c(%rbp), %edi
callq 0x18c7
movl $0x0, -0x8c(%rbp)
decl -0xc8(%rbp)
xorl %edi, %edi
callq 0x1120
movq %rax, -0xd8(%rbp)
subq $0x80, %rsp
leaq -0xf0(%rbp), %rsi
movl $0x10, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movl -0x70(%rbp), %edi
callq 0x191c
addq $0x80, %rsp
movl %eax, %ecx
sarl $0x1f, %ecx
andl $-0x3, %ecx
movq -0x40(%rbp), %rax
movq %rax, %rsp
movl %ecx, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq