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); }
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; }