// File: /workspace/github_c_makefile_star2_O1/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, %r13d
movl %edi, %r15d
leaq -0xf0(%rbp), %r14
movq %r14, %rdi
movl %r15d, %esi
callq 0x1991
movl 0x24(%r14), %edx
movl %edx, %ecx
shrl $0xa, %ecx
xorl %eax, %eax
movq %rcx, -0x48(%rbp)
cmpl %r13d, %ecx
jb 0x2231
movl %edx, -0x2c(%rbp)
movl %r15d, -0x6c(%rbp)
movq %rsp, %r14
movq %rsp, %r15
addq $-0x400, %r15           # imm = 0xFC00
movq %r15, %rsp
movq %rsp, %r12
addq $-0x400, %r12           # imm = 0xFC00
movq %r12, %rsp
movq %rsp, %rax
addq $-0x400, %rax           # imm = 0xFC00
movq %rax, -0x60(%rbp)
movq %rax, %rsp
leaq -0x4f0(%rbp), %rdi
xorl %ebx, %ebx
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x10b0
cmpl $0xb, %r13d
movq %r12, -0x68(%rbp)
ja 0x1cf5
movl $0x0, %ecx
movl $0x0, %eax
cmpl %r13d, -0x48(%rbp)
jl 0x1d4a
movq %r14, -0x38(%rbp)
movl -0xc8(%rbp), %r14d
movq -0xd8(%rbp), %rax
movl %r13d, %ebx
movq -0x48(%rbp), %rcx
cmpq $0xb, %rcx
movl $0xb, %r12d
cmovbq %rcx, %r12
decq %rbx
movl -0xc0(%rbp,%rbx,4), %edi
testl %edi, %edi
je 0x1cc4
callq 0x18c3
decl %r14d
xorl %edi, %edi
callq 0x1120
movl $0x0, -0xc0(%rbp,%rbx,4)
incq %rbx
cmpq %r12, %rbx
jb 0x1caa
movl %r14d, -0xc8(%rbp)
movq %rax, -0xd8(%rbp)
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %eax, %eax
movq -0x38(%rbp), %r14
movq -0x68(%rbp), %r12
jmp 0x1d4a
cmpl $0x10b, %r13d           # imm = 0x10B
ja 0x1d0b
addl $-0xc, %r13d
xorl %ecx, %ecx
movl %r13d, %ebx
xorl %eax, %eax
jmp 0x1d4a
cmpl $0x1010b, %r13d         # imm = 0x1010B
ja 0x1d2a
addl $0xfffffef4, %r13d      # imm = 0xFFFFFEF4
movzbl %r13b, %ebx
shrl $0x8, %r13d
xorl %eax, %eax
movl %r13d, %ecx
jmp 0x1d4a
addl $0xfffefef4, %r13d      # imm = 0xFFFEFEF4
movl $0xff, %eax
movl %r13d, %ebx
andl %eax, %ebx
movl %r13d, %ecx
shrl $0x8, %ecx
andl %eax, %ecx
shrl $0x10, %r13d
movl %r13d, %eax
movl %ecx, -0x50(%rbp)
movl -0x90(%rbp), %r13d
testl %r13d, %r13d
je 0x1ec8
movl %eax, -0x58(%rbp)
movl %r13d, %edi
movq %r12, %rsi
callq 0x131d
testl %eax, %eax
js 0x1ed1
cmpl $0x43000, -0x2c(%rbp)   # imm = 0x43000
setae %al
movl -0x50(%rbp), %edx
cmpl $0x100, %edx            # imm = 0x100
setb %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x1edb
movl %r13d, -0x4c(%rbp)
movq %r14, -0x38(%rbp)
movl -0xc8(%rbp), %r13d
movq -0xd8(%rbp), %rax
movq %rax, -0x40(%rbp)
movl %edx, %r14d
movl $0x10c, %ecx            # imm = 0x10C
movl (%r12,%r14,4), %edi
testl %edi, %edi
je 0x1e66
movl %ecx, %r12d
movq %r15, %rsi
callq 0x131d
testl %eax, %eax
js 0x2198
cmpl -0x48(%rbp), %r12d
setle %al
cmpl $0x100, %ebx            # imm = 0x100
setb %cl
andb %al, %cl
cmpb $0x1, %cl
movq -0x40(%rbp), %rax
movl %r12d, -0x2c(%rbp)
jne 0x1e33
movl %r12d, %edx
movl %ebx, %r12d
movl %edx, %ebx
movl (%r15,%r12,4), %edi
testl %edi, %edi
je 0x1e1b
callq 0x18c3
decl %r13d
xorl %edi, %edi
callq 0x1120
movl $0x0, (%r15,%r12,4)
cmpl -0x48(%rbp), %ebx
jge 0x1e33
leaq 0x1(%r12), %rcx
incl %ebx
cmpq $0xff, %r12
movq %rcx, %r12
jb 0x1dfc
movq %rax, -0x40(%rbp)
movq %r15, %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x10f0
movq -0x68(%rbp), %r12
movl (%r12,%r14,4), %edi
testl %eax, %eax
je 0x1e6e
movq %r15, %rsi
callq 0x12e5
testl %eax, %eax
movl -0x2c(%rbp), %ecx
jns 0x1e8c
jmp 0x21ff
addl $0x100, %ecx            # imm = 0x100
jmp 0x1e8c
callq 0x18c3
movl $0x0, (%r12,%r14,4)
decl %r13d
xorl %edi, %edi
callq 0x1120
movq %rax, -0x40(%rbp)
movl -0x2c(%rbp), %ecx
cmpl -0x48(%rbp), %ecx
jg 0x1ea7
leaq 0x1(%r14), %rax
xorl %ebx, %ebx
cmpq $0xff, %r14
movq %rax, %r14
jb 0x1db6
movl %ecx, -0x2c(%rbp)
movl %r13d, -0xc8(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0xd8(%rbp)
xorl %ebx, %ebx
movq -0x38(%rbp), %r14
movl -0x4c(%rbp), %r13d
jmp 0x1ee2
movl $0x1010c, %edx          # imm = 0x1010C
movl %ebx, %ecx
jmp 0x1f3c
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x222e
movl $0x10c, -0x2c(%rbp)     # imm = 0x10C
leaq -0x4f0(%rbp), %rsi
movq %r12, %rdi
callq 0x10f0
movl %r13d, %edi
testl %eax, %eax
je 0x1f11
movq %r12, %rsi
callq 0x12e5
testl %eax, %eax
movl -0x58(%rbp), %eax
movl %ebx, %ecx
movl -0x2c(%rbp), %edx
jns 0x1f3c
jmp 0x2184
callq 0x18c3
movl $0x0, -0x90(%rbp)
decl -0xc8(%rbp)
xorl %edi, %edi
callq 0x1120
movq %rax, -0xd8(%rbp)
movl -0x58(%rbp), %eax
movl %ebx, %ecx
movl -0x2c(%rbp), %edx
movl -0x8c(%rbp), %ebx
testl %ebx, %ebx
je 0x21cf
movl %edx, %r13d
movl %ecx, -0x40(%rbp)
movq %r14, -0x38(%rbp)
movl %eax, %r14d
movl %ebx, %edi
movq -0x60(%rbp), %rsi
callq 0x131d
testl %eax, %eax
js 0x218e
cmpl -0x48(%rbp), %r13d
setle %al
cmpl $0x100, %r14d           # imm = 0x100
setb %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x215a
movl %ebx, -0x4c(%rbp)
movl %r13d, -0x2c(%rbp)
movl -0xc8(%rbp), %ebx
movq -0xd8(%rbp), %rcx
movl %r14d, %edx
movq -0x38(%rbp), %r14
movq -0x60(%rbp), %rax
movl (%rax,%rdx,4), %edi
testl %edi, %edi
je 0x2127
movq %rdx, -0x58(%rbp)
movq %rcx, %r13
movq %r12, %rsi
callq 0x131d
testl %eax, %eax
js 0x2240
movl -0x2c(%rbp), %eax
cmpl -0x48(%rbp), %eax
jg 0x20c2
movl -0x50(%rbp), %eax
cmpl $0xff, %eax
movl -0x40(%rbp), %edx
ja 0x20c5
movl %eax, %r14d
movl (%r12,%r14,4), %edi
testl %edi, %edi
je 0x2099
movl %edx, %r12d
movq %r15, %rsi
callq 0x131d
testl %eax, %eax
js 0x219f
cmpl $0xff, %r12d
movq %r13, %rax
ja 0x2051
movl %r12d, %r12d
movl -0x2c(%rbp), %r13d
movl (%r15,%r12,4), %edi
testl %edi, %edi
je 0x2037
callq 0x18c3
decl %ebx
xorl %edi, %edi
callq 0x1120
movl $0x0, (%r15,%r12,4)
cmpl -0x48(%rbp), %r13d
jge 0x2051
leaq 0x1(%r12), %rcx
incl %r13d
cmpq $0xff, %r12
movq %rcx, %r12
jb 0x2019
movq %rax, %r13
movq %r15, %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x10f0
movq -0x68(%rbp), %r12
movl (%r12,%r14,4), %edi
testl %eax, %eax
je 0x2080
movq %r15, %rsi
callq 0x12e5
testl %eax, %eax
jns 0x2099
jmp 0x2218
callq 0x18c3
movl $0x0, (%r12,%r14,4)
decl %ebx
xorl %edi, %edi
callq 0x1120
movq %rax, %r13
movl -0x2c(%rbp), %ecx
addl $0x100, %ecx            # imm = 0x100
xorl %edx, %edx
movl %ecx, -0x2c(%rbp)
cmpl -0x48(%rbp), %ecx
jg 0x20c5
leaq 0x1(%r14), %rax
cmpq $0xff, %r14
movq %rax, %r14
jb 0x1fe7
jmp 0x20c5
movl -0x40(%rbp), %edx
movl %edx, -0x40(%rbp)
movq %r15, %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x10f0
movq -0x60(%rbp), %r14
movq -0x58(%rbp), %rcx
movl (%r14,%rcx,4), %edi
testl %eax, %eax
je 0x2104
movq %r12, %rsi
callq 0x12e5
testl %eax, %eax
movq -0x38(%rbp), %r14
js 0x2247
movq %r13, %rcx
movq -0x58(%rbp), %rdx
jmp 0x2127
movq %rcx, %r13
callq 0x18c3
movl $0x0, (%r14,%r13,4)
decl %ebx
xorl %edi, %edi
callq 0x1120
movq %rax, %rcx
movq -0x38(%rbp), %r14
movq %r13, %rdx
movl -0x2c(%rbp), %eax
cmpl -0x48(%rbp), %eax
jg 0x214a
leaq 0x1(%rdx), %rax
movl $0x0, -0x50(%rbp)
cmpq $0xff, %rdx
movq %rax, %rdx
jb 0x1fa1
movl %ebx, -0xc8(%rbp)
movq %rcx, -0xd8(%rbp)
movl -0x4c(%rbp), %ebx
leaq -0x4f0(%rbp), %rsi
movq -0x60(%rbp), %rdi
callq 0x10f0
testl %eax, %eax
je 0x21a6
movl -0x90(%rbp), %edi
movq %r12, %rsi
callq 0x12e5
testl %eax, %eax
movq -0x38(%rbp), %r14
jns 0x21cf
movl $0xfffffffe, %eax       # imm = 0xFFFFFFFE
jmp 0x222e
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x222a
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x2204
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x221d
movl %ebx, %edi
callq 0x18c3
movl $0x0, -0x8c(%rbp)
decl -0xc8(%rbp)
xorl %edi, %edi
callq 0x1120
movq %rax, -0xd8(%rbp)
movq -0x38(%rbp), %r14
subq $0x80, %rsp
leaq -0xf0(%rbp), %rsi
movl $0x10, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movl -0x6c(%rbp), %edi
callq 0x1918
addq $0x80, %rsp
sarl $0x1f, %eax
andl $-0x3, %eax
jmp 0x222e
movl $0xfffffffe, %eax       # imm = 0xFFFFFFFE
movq -0x40(%rbp), %rcx
movl %r13d, -0xc8(%rbp)
movq %rcx, -0xd8(%rbp)
jmp 0x222a
movl $0xfffffffe, %eax       # imm = 0xFFFFFFFE
movl %ebx, -0xc8(%rbp)
movq %r13, -0xd8(%rbp)
movq -0x38(%rbp), %r14
movq %r14, %rsp
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x224c
movl $0xfffffffe, %eax       # imm = 0xFFFFFFFE
movl %ebx, -0xc8(%rbp)
movq %r13, -0xd8(%rbp)
jmp 0x222e