// File: /workspace/github_c_makefile_star2_O2/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 $0x4e8, %rsp            # imm = 0x4E8
movl %esi, %ebx
movl %edi, %r13d
leaq -0x108(%rbp), %r14
movq %r14, %rdi
movl %r13d, %esi
callq 0x194e
movl 0x24(%r14), %ecx
shrl $0xa, %ecx
xorl %eax, %eax
movq %rcx, -0x58(%rbp)
cmpl %ebx, %ecx
jb 0x214c
movq %rbx, %r12
movq %rsp, %r14
movq %rsp, %r15
addq $-0x400, %r15           # imm = 0xFC00
movq %r15, %rsp
movq %rsp, %rbx
addq $-0x400, %rbx           # imm = 0xFC00
movq %rbx, %rsp
movq %rsp, %rax
addq $-0x400, %rax           # imm = 0xFC00
movq %rax, -0x70(%rbp)
movq %rax, %rsp
leaq -0x510(%rbp), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x10b0
cmpl $0xb, %r12d
movq %rbx, -0x80(%rbp)
ja 0x1c75
movl -0xe0(%rbp), %ebx
movq -0xf0(%rbp), %rax
movl %r12d, %r12d
cmpq -0x58(%rbp), %r12
ja 0x1c8c
cmpq $0xb, %r12
ja 0x1c8c
movl -0xdc(%rbp,%r12,4), %edi
testl %edi, %edi
je 0x1c67
callq 0x188b
decl %ebx
xorl %edi, %edi
callq 0x1120
andl $0x0, -0xdc(%rbp,%r12,4)
incq %r12
jmp 0x1c41
cmpl $0x10b, %r12d           # imm = 0x10B
ja 0x1cab
addl $-0xc, %r12d
movq %r12, -0x50(%rbp)
xorl %eax, %eax
xorl %esi, %esi
jmp 0x1cee
movl %ebx, -0xe0(%rbp)
movq %rax, -0xf0(%rbp)
movq $0x0, -0x50(%rbp)
xorl %eax, %eax
xorl %esi, %esi
movq -0x80(%rbp), %rbx
jmp 0x1cee
cmpl $0x1010b, %r12d         # imm = 0x1010B
ja 0x1cc9
addl $0xfffffef4, %r12d      # imm = 0xFFFFFEF4
movl %r12d, %eax
movzbl %r12b, %ecx
shrl $0x8, %eax
xorl %esi, %esi
jmp 0x1cea
addl $0xfffefef4, %r12d      # imm = 0xFFFEFEF4
movl $0xff, %ecx
movl %r12d, %eax
movl %r12d, %esi
movl %r12d, %edx
andl %ecx, %edx
shrl $0x8, %eax
andl %ecx, %eax
shrl $0x10, %esi
movl %edx, %ecx
movq %rcx, -0x50(%rbp)
movl -0xa8(%rbp), %edi
movl %eax, %eax
movq %rax, -0x78(%rbp)
testl %edi, %edi
je 0x1e15
movq %rsi, -0x68(%rbp)
movq %rdi, -0x60(%rbp)
movq %rbx, %rsi
callq 0x1319
testl %eax, %eax
js 0x1ff9
movl %r13d, -0x3c(%rbp)
movq %r14, -0x38(%rbp)
movl -0xe0(%rbp), %r12d
movq -0xf0(%rbp), %r13
movl $0x10c, -0x2c(%rbp)     # imm = 0x10C
movq -0x78(%rbp), %rcx
movq -0x50(%rbp), %r14
movl -0x2c(%rbp), %eax
cmpl -0x58(%rbp), %eax
jg 0x2009
cmpq $0xff, %rcx
ja 0x2009
movl (%rbx,%rcx,4), %edi
testl %edi, %edi
je 0x1de7
movq %rcx, -0x48(%rbp)
movq %r15, %rsi
callq 0x1319
testl %eax, %eax
js 0x1ffd
movl %r14d, %ebx
movl -0x2c(%rbp), %r14d
cmpl -0x58(%rbp), %r14d
jg 0x1db4
cmpq $0xff, %rbx
ja 0x1db4
movl (%r15,%rbx,4), %edi
testl %edi, %edi
je 0x1dac
callq 0x188b
decl %r12d
xorl %edi, %edi
callq 0x1120
movq %rax, %r13
andl $0x0, (%r15,%rbx,4)
incq %rbx
incl %r14d
jmp 0x1d7e
movq %r15, %rdi
leaq -0x510(%rbp), %rsi
callq 0x10f0
movq -0x80(%rbp), %rbx
movq -0x48(%rbp), %r14
movl (%rbx,%r14,4), %edi
testl %eax, %eax
je 0x1df0
movq %r15, %rsi
callq 0x12e3
testl %eax, %eax
movq %r14, %rcx
jns 0x1e0a
jmp 0x205f
addl $0x100, -0x2c(%rbp)     # imm = 0x100
jmp 0x1e0a
callq 0x188b
andl $0x0, (%rbx,%r14,4)
decl %r12d
xorl %edi, %edi
callq 0x1120
movq %rax, %r13
movq %r14, %rcx
incq %rcx
xorl %r14d, %r14d
jmp 0x1d3f
movl $0x1010c, %edx          # imm = 0x1010C
xorl %ecx, %ecx
movl -0xa4(%rbp), %edi
testl %edi, %edi
je 0x211d
movl %edx, -0x2c(%rbp)
movq %rcx, -0x60(%rbp)
movq %rsi, %r12
movl %edi, -0x84(%rbp)
movq -0x70(%rbp), %rsi
callq 0x1319
testl %eax, %eax
js 0x1ff9
movl %r13d, -0x3c(%rbp)
movq %r14, -0x38(%rbp)
movl -0xe0(%rbp), %r13d
movq -0xf0(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x70(%rbp), %rax
movq %r12, %r14
movl -0x2c(%rbp), %r12d
cmpl -0x58(%rbp), %r12d
jg 0x20a9
cmpq $0xff, %r14
ja 0x20a9
movl (%rax,%r14,4), %edi
testl %edi, %edi
je 0x1fe9
movq %r14, -0x68(%rbp)
movq %rbx, %rsi
callq 0x1319
testl %eax, %eax
js 0x1ffd
movq -0x78(%rbp), %r14
movq -0x48(%rbp), %rax
cmpl -0x58(%rbp), %r12d
jg 0x1f8b
cmpq $0xff, %r14
ja 0x1f8b
movl (%rbx,%r14,4), %edi
testl %edi, %edi
je 0x1f74
movq %rax, -0x48(%rbp)
movq %r15, %rsi
callq 0x1319
testl %eax, %eax
js 0x1ffd
movl -0x50(%rbp), %ebx
movl %r12d, -0x2c(%rbp)
movq -0x48(%rbp), %rax
cmpl -0x58(%rbp), %r12d
jg 0x1f24
cmpq $0xff, %rbx
ja 0x1f24
movl (%r15,%rbx,4), %edi
testl %edi, %edi
je 0x1f1c
callq 0x188b
decl %r13d
xorl %edi, %edi
callq 0x1120
andl $0x0, (%r15,%rbx,4)
incq %rbx
incl %r12d
jmp 0x1ef1
movq %rax, -0x48(%rbp)
movq %r15, %rdi
leaq -0x510(%rbp), %rsi
callq 0x10f0
movq -0x80(%rbp), %rbx
movl (%rbx,%r14,4), %edi
testl %eax, %eax
je 0x1f5c
movq %r15, %rsi
callq 0x12e3
testl %eax, %eax
movl -0x2c(%rbp), %r12d
movq -0x48(%rbp), %rax
jns 0x1f74
jmp 0x205f
callq 0x188b
andl $0x0, (%rbx,%r14,4)
decl %r13d
xorl %edi, %edi
callq 0x1120
movl -0x2c(%rbp), %r12d
addl $0x100, %r12d           # imm = 0x100
incq %r14
movq $0x0, -0x50(%rbp)
jmp 0x1eaf
movq %rax, -0x48(%rbp)
movl %r12d, -0x2c(%rbp)
movq %r15, %rdi
leaq -0x510(%rbp), %rsi
callq 0x10f0
movq -0x70(%rbp), %r12
movq -0x68(%rbp), %r14
movl (%r12,%r14,4), %edi
testl %eax, %eax
je 0x1fca
movq %rbx, %rsi
callq 0x12e3
testl %eax, %eax
movq %r12, %rax
movl -0x2c(%rbp), %r12d
jns 0x1fe9
jmp 0x205f
callq 0x188b
andl $0x0, (%r12,%r14,4)
decl %r13d
xorl %edi, %edi
callq 0x1120
movq %rax, -0x48(%rbp)
movq %r12, %rax
movl -0x2c(%rbp), %r12d
incq %r14
movq $0x0, -0x78(%rbp)
jmp 0x1e70
pushq $-0x1
jmp 0x2065
pushq $-0x1
popq %rax
movq -0x38(%rbp), %r14
jmp 0x2149
movq %r14, -0x50(%rbp)
movl %r12d, -0xe0(%rbp)
movq %r13, -0xf0(%rbp)
leaq -0x510(%rbp), %rsi
movq %rbx, %rdi
callq 0x10f0
testl %eax, %eax
je 0x206b
movq -0x60(%rbp), %r14
movl %r14d, %edi
movq %rbx, %rsi
callq 0x12e3
movq %r14, %rcx
testl %eax, %eax
movq -0x38(%rbp), %r14
movl -0x3c(%rbp), %r13d
pushq $-0x2
popq %rax
movq -0x68(%rbp), %rsi
movl -0x2c(%rbp), %edx
jns 0x1e1c
jmp 0x2149
movq -0x38(%rbp), %r14
pushq $-0x2
popq %rax
jmp 0x2149
movq -0x60(%rbp), %rdi
callq 0x188b
andl $0x0, -0xa8(%rbp)
decl %r12d
movl %r12d, -0xe0(%rbp)
xorl %edi, %edi
callq 0x1120
xorl %ecx, %ecx
movq %rax, -0xf0(%rbp)
movq -0x38(%rbp), %r14
movl -0x3c(%rbp), %r13d
movq -0x68(%rbp), %rsi
movl -0x2c(%rbp), %edx
jmp 0x1e1c
movl %r13d, -0xe0(%rbp)
movq -0x48(%rbp), %rcx
movq %rcx, -0xf0(%rbp)
leaq -0x510(%rbp), %rsi
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
je 0x20eb
movq -0x60(%rbp), %rdi
movq %rbx, %rsi
callq 0x12e3
testl %eax, %eax
movq -0x38(%rbp), %r14
movl -0x3c(%rbp), %r13d
pushq $-0x2
popq %rax
jns 0x211d
jmp 0x2149
movl -0x84(%rbp), %edi
callq 0x188b
andl $0x0, -0xa4(%rbp)
decl %r13d
movl %r13d, -0xe0(%rbp)
xorl %edi, %edi
callq 0x1120
movq %rax, -0xf0(%rbp)
movq -0x38(%rbp), %r14
movl -0x3c(%rbp), %r13d
subq $0x80, %rsp
pushq $0x10
popq %rcx
leaq -0x108(%rbp), %rsi
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movl %r13d, %edi
callq 0x18d9
addq $0x80, %rsp
sarl $0x1f, %eax
andl $-0x3, %eax
movq %r14, %rsp
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq