示例#1
0
int liberar_bloques_inodo(unsigned int ninodo, unsigned int blogico) {
    int numPdirectos = 12;
    int numPunt = BLOCKSIZE / 4;
    int nPunteros0 = numPunt;
    int nPunteros1 = numPunt * numPunt;
    int nPunteros2 = numPunt * numPunt * numPunt;

    struct inodo inodoAux = leer_inodo(ninodo); //leemos el inodo que nos indican por parámetro
    int ultimoBloqueOcupado = inodoAux.tamEnBytesLog / BLOCKSIZE; //nos interesa saber donde acaba
    int bufferAuxPunt[BLOCKSIZE / 4];
    memset(bufferAuxPunt, 0, BLOCKSIZE);

    int array2[numPunt];
    int array1[numPunt];
    int array[numPunt];
    int pCeros[numPunt];
    memset(pCeros, 0, BLOCKSIZE);
    int bloque;
    for (bloque = blogico; bloque <= ultimoBloqueOcupado; bloque++) {

        //Punteros Directos
        if (bloque < numPdirectos) {
            if (inodoAux.punterosDirectos[bloque] != 0) {
                liberar_bloque(bloque); //liberamos el bloque al cual apunta el inodo
                inodoAux.punterosDirectos[bloque] = 0; //quitamos el puntero que apunta al bloque que hemos liberado
            }

            //Punteros indirctos niv 0  
        } else if (bloque < numPdirectos + nPunteros0) {
            if (inodoAux.punterosIndirectos[0] != 0) {
                bread(inodoAux.punterosIndirectos[0], array); //leemos el bloque de punteros de nivel 0
                if (array[bloque - numPdirectos] != 0) { //si existe bloque de datos    
                    liberar_bloque(array[bloque - numPdirectos]); //liberamos el bloque al cual apunta el inodo
                    array[bloque - numPdirectos] = 0; //quitamos el puntero que apunta al bloque que hemos liberado

                    //miramos si quedan punteros que no esten libres en el bloque de los de nivel 0
                    //si ninguno apunta a nada liberamos el bloque de punteros indirectos
                    //y hacemos que el inodo de punteros indirectos de nivel 0 no apunte a nada
                    if (memcmp(array, pCeros, BLOCKSIZE) == 0) {
                        liberar_bloque(inodoAux.punterosIndirectos[0]);
                        inodoAux.punterosIndirectos[0] = 0;
                    } else {
                        bwrite(inodoAux.punterosIndirectos[0], array);
                    }
                }
            }
            //INDIRECTOS1
        } else if (bloque < numPdirectos + nPunteros0 + nPunteros1) {
            int puntNiv0 = (bloque - (numPdirectos + nPunteros0)) % nPunteros0;
            int puntNiv1 = (bloque - (numPdirectos + nPunteros0)) / nPunteros0;

            if (inodoAux.punterosIndirectos[1] != 0) {
                bread(inodoAux.punterosIndirectos[1], array1);
                if (array1[puntNiv1] != 0) {
                    bread(array1[puntNiv1], array);
                    if (array[puntNiv0] != 0) {
                        liberar_bloque(array[puntNiv0]);
                        array[puntNiv0] = 0;
                        if (memcmp(array, pCeros, BLOCKSIZE) == 0) {
                            liberar_bloque(array1[puntNiv1]);
                            array1[puntNiv1] = 0;
                            if (memcmp(array1, pCeros, BLOCKSIZE) == 0) {
                                liberar_bloque(inodoAux.punterosIndirectos[1]);
                                inodoAux.punterosIndirectos[1] = 0;
                            } else {
                                bwrite(inodoAux.punterosIndirectos[1], array1);
                            }
                        } else {
                            bwrite(array1[puntNiv1], array);
                        }
                    }
                }
            }
            //INDIRECTOS2
        } else if (bloque < numPdirectos + nPunteros0 + nPunteros1 + nPunteros2) {
            int puntNiv0 = ((bloque - (numPdirectos + nPunteros0 + nPunteros1)) % nPunteros1) % nPunteros0;
            int puntNiv1 = ((bloque - (numPdirectos + nPunteros0 + nPunteros1)) % nPunteros1) / nPunteros0;
            int puntNiv2 = (bloque - (numPdirectos + nPunteros0 + nPunteros1)) / nPunteros1;

            if (inodoAux.punterosIndirectos[2] != 0) {
                bread(inodoAux.punterosIndirectos[2], array2);
                if (array2[puntNiv2] != 0) {
                    bread(array2[puntNiv2], array1);
                    if (array1[puntNiv1] != 0) {
                        bread(array[puntNiv1], array);
                        if (array[puntNiv0] != 0) {
                            liberar_bloque(array[puntNiv0]);
                            array[puntNiv0] = 0;
                            if (memcmp(array, pCeros, BLOCKSIZE) == 0) {
                                liberar_bloque(array1[puntNiv1]);
                                array1[puntNiv1] = 0;
                                if (memcmp(array1, pCeros, BLOCKSIZE) == 0) {
                                    liberar_bloque(array2[puntNiv2]);
                                    array1[puntNiv2] = 0;
                                    if (memcmp(array2, pCeros, BLOCKSIZE) == 0) {
                                        liberar_bloque(inodoAux.punterosIndirectos[2]);
                                        inodoAux.punterosIndirectos[2] = 0;
                                    } else {
                                        bwrite(inodoAux.punterosIndirectos[1], array2);
                                    }
                                } else {
                                    bwrite(array2[puntNiv2], array1);
                                }
                            } else {
                                bwrite(array1[puntNiv1], array);
                            }
                        }
                    }
                }
            }
        }

    }
    escribir_inodo(inodoAux, ninodo);
}
示例#2
0
int mi_truncar_f(unsigned int ninodo, unsigned int nbytes) {
    // Creamos una estructura inodo.
	struct inodo Inodo;
    // Leemos el inodo indicado por parámetro.
	Inodo = leer_inodo(ninodo);

	if (nbytes > Inodo.tamEnBytesLog) {
		printf("ERROR -> No se ha podido truncar el fichero por sobrepasar su tamaño.\n");
		return -1;
	}

    // Si el número de bytes es 0, vaciamos el fichero.
	if (nbytes == 0) {
		liberar_inodo(ninodo);

		Inodo.tamEnBytesLog = nbytes;

		if (escribir_inodo(Inodo, ninodo) == -1) {
			return -1;
		}
    }// Si no...
    else if (nbytes > 0) {
        // Calculamos el último bloque a truncar.
    	int ultimoblogico = Inodo.tamEnBytesLog / BLOCKSIZE;

        // Si el tamaño en bytes lógicos del inodo es múltiplo del tamaño de bloque
        // decrementamos la variable ultimoblogico.
    	if ((Inodo.tamEnBytesLog % BLOCKSIZE) == 0) {
    		ultimoblogico--;
    	}

        // Calculamos el último bloque que conservamos.
    	int bloq_queda = nbytes / BLOCKSIZE;
        // Si el número de bytes es múltiplo de tamaño de bloque, decrementamos 
        // la variable bloq_queda.
    	if (nbytes % BLOCKSIZE == 0) {
    		bloq_queda--;
    	}

    	unsigned int bfisico;
    	int i = 0;
    	char reservar = '0';
        // Iteramos para todos los bloques que queremos liberar.
    	for (i = bloq_queda + 1; i <= ultimoblogico; i++) {
            // Obtenemos el bloque físico.
    		bfisico = traducir_bloque_inodo(ninodo, i, reservar);

            // Si no es el bloque raíz (SUPERBLOQUE)...
    		if (bfisico > 0) {
    			if (liberar_bloque(bfisico) == -1) {

    				printf("ERROR -> No se ha liberado el bloque.\n");
    				return -1;
    			}
                // Decrementamos los bloques ocupados.
    			Inodo.numBloquesOcupados--;
    		}

            // Si estamos en el último bloque y no ocupa el bloque entero...
    		if ((i == ultimoblogico) && (Inodo.tamEnBytesLog % BLOCKSIZE != 0)) {
                // Truncamos el trozo del bloque.
    			Inodo.tamEnBytesLog = Inodo.tamEnBytesLog - (Inodo.tamEnBytesLog % BLOCKSIZE);
    		} else {
                // Truncamos todo el bloque.
    			Inodo.tamEnBytesLog = Inodo.tamEnBytesLog - BLOCKSIZE;
    		}
    	}

    	Inodo.tamEnBytesLog = nbytes;

    	if (escribir_inodo(Inodo, ninodo) == -1) {
    		return -1;
    	}
    }
    return 0;
}