void mostrarIA(struct superbloque SB) { char atime[80], mtime[80],cttime[80],*tipo,perm[3]; struct inodo in; int ninodo; struct tm *ts; printf("\n\n \t*****Array de Inodos*****\n"); printf("#Tamaño Inodo: %d\n",TAM_INODO); for(ninodo=0; ninodo<SB.totInodos; ninodo++) { in = leer_inodo(ninodo); if(in.tipo!='l') { ts = localtime(&in.atime); strftime(atime, sizeof(atime), "%a %Y-%m-%d %H:%M:%S", ts); ts = localtime(&in.mtime); strftime(mtime, sizeof(mtime), "%a %Y-%m-%d %H:%M:%S", ts); ts = localtime(&in.ctime); strftime(cttime, sizeof(cttime), "%a %Y-%m-%d %H:%M:%S", ts); perm[0]= ((unsigned char)in.permisos&(unsigned char)1)==0 ?'-':'X'; perm[1]=((unsigned char)in.permisos&(unsigned char)2)==0?'-':'W'; perm[2]=((unsigned char)in.permisos&(unsigned char)4)==0?'-':'R'; tipo=in.tipo=='d'? "Directorio" : "Fichero"; printf("#ID: %d TIPO: %s PERMISOS: %c%c%c NLINKS: %d TAMAÑO: %d BLOQUES OCUPADOS: %d \n",ninodo,tipo,perm[0], perm[1], perm[2], in.nlinks,in.tamEnBytesLog,in.numBloquesOcupados); printf(" ATIME: %s MTIME: %s CTIME: %s\n\n",atime,mtime,cttime); } } }
int liberar_inodo(unsigned int ninodo) { struct superbloque sb; struct inodo inodoAux; unsigned int blogico = 0; if (bread(posSB, &sb) == -1) { printf("Error: ficheros_basico.c > liberar_inodo > al intentar leer el superbloque \n"); return -1; } inodoAux = leer_inodo(ninodo); liberar_bloques_inodo(ninodo, blogico); inodoAux.tipo = 'l'; inodoAux.ctime = time(NULL); // Enlazamos el primer inodo libre inodoAux.punterosDirectos[0] = sb.posPrimerInodoLibre; sb.posPrimerInodoLibre = ninodo; sb.cantInodosLibres++; if (escribir_inodo(inodoAux, ninodo) == -1) { printf("Error: ficheros_basico.c > liberar_inodo > al intentar liberar inodo \n"); return -1; } if (bwrite(posSB, &sb) == -1) { printf("Error: ficheros_basico.c > reservar_inodo > al intentar actualizar el superbloque \n"); return -1; } return ninodo; }
/*Trunca (corta) un fichero/directorio (ninodo) pasado por argumento a los bytes (nbytes) pasados por argumento, liberando los bloques que no hagan falta * si nbytes = 0 lo liberamos TODO */ int mi_truncar_f(unsigned int ninodo, unsigned int nbytes) { struct inodo inode; inode = leer_inodo(ninodo); if ((inode.permisos & 2) != 2) { //Si no tenemos permisos de lectura devolvemos un error return -1; } if (nbytes == 0) {//liberamos todo el inodo liberar_inodo(ninodo); } else { //liberamos a partir del bloque correspondiente del nbyte if (liberar_bloques_inodo(ninodo, nbytes) < 0) { printf("ERROR: ficheros_basic.c -> (metodo) -> descripcion error.\n"); return -1; } } //actualizamos el inodo inode.mtime = time(NULL); inode.ctime = time(NULL); inode.tamEnBytesLog = nbytes; escribir_inodo(inode, ninodo); //guardamos el inodo mi_signalSem(); return 0; }
int mi_chmod_f(unsigned int ninodo, unsigned char modo) { struct inodo inode; inode = leer_inodo(ninodo); inode.permisos = modo; inode.ctime = time(NULL); escribir_inodo(inode, ninodo); return 1; }
int mi_chmod_f(unsigned int ninodo, unsigned char modo) { // Creamos una estructura inodo. struct inodo Inodo; // Leemos el inodo indicado. Inodo = leer_inodo(ninodo); // Cambiamos los permisos del inodo. Inodo.permisos = modo; // Modificamos la variable ctime. Inodo.ctime = time(NULL); // Actualizamos el inodo. escribir_inodo(Inodo, ninodo); }
int mi_stat_f(unsigned int ninodo, struct STAT *p_stat) { struct inodo inode; inode = leer_inodo(ninodo); p_stat -> tipo = inode.tipo; //Tipo (libre, directorio o fichero) p_stat -> permisos = inode.permisos; //Permisos (lectura y/o escritura y/o ejecución) p_stat -> atime = inode.atime; //Fecha y hora del último acceso a datos: atime p_stat -> mtime = inode.mtime; //Fecha y hora de la última modificación de datos: mtime p_stat -> ctime = inode.ctime; //Fecha y hora de la última modificación del inodo: ctime p_stat -> nlinks = inode.nlinks; //Cantidad de enlaces de entradas en directorio p_stat -> tamEnBytesLog = inode.tamEnBytesLog; //Tamaño en bytes lógicos p_stat -> numBloquesOcupados = inode.numBloquesOcupados; //Cantidad de bloques ocupados en la zona de datos return 0; }
int mi_stat_f(unsigned int ninodo, struct STAT *p_stat) { // Creamos una estructura inodo. struct inodo Inodo; struct STAT stat; // Leemos el inodo indicado por parámetro. Inodo = leer_inodo(ninodo); // Asignamos información a la estructura STAT. stat.tipo = Inodo.tipo; stat.tamEnBytesLog = Inodo.tamEnBytesLog; stat.permisos = Inodo.permisos; stat.numBloquesOcupados = Inodo.numBloquesOcupados; stat.nlinks = Inodo.nlinks; stat.mtime = Inodo.mtime; stat.ctime = Inodo.ctime; stat.atime = Inodo.atime; *p_stat = stat; }
int main(int argc, char **argv){ if(argc<3){ printf("\nescribir: Error debe escribir: $ ./escribir <nombre_fichero> <offset> <inodo(opcinal)>\n"); printf("*Si no indica el inodo el sistema se encargará de reservar un inodo nuevo.\n"); return -1; } struct INODO inodo; int ninodo; char ruta[128]; long nbytes; long offset = atoi(argv[2]); printf("\nescribir: Escribe la ruta del fichero: "); scanf("%s",ruta); FILE *fichero = fopen(ruta,"r"); fseek(fichero, 0, SEEK_END); // Colocar el cursor al final del fichero nbytes = ftell(fichero); // Tamaño en bytes printf("\nescribir: El tamaño del fichero es: %ld\n",nbytes); char entrada[nbytes]; fseek(fichero,0,0); fscanf(fichero,"%s",entrada); fclose(fichero); //Montamos el dispositivo. printf("\nescribir: Montando el dispositivo...\n"); bmount(argv[1]);//nombre_fichero printf("\nescribir: El dispositivo se ha montado con éxito.\n"); //Si el inodo se pasa como argumento if(argc == 4){ ninodo = atoi(argv[3]); }else{ //Reservamos el inodo. ninodo = reservar_inodo('f',6); } inodo = leer_inodo(ninodo); //IMPRIMIR INODO printf("\nNº INODO %i:\n",ninodo); printf("Tipo: %c\n",inodo.tipo); printf("Permisos: %i\n",inodo.permisos); printf("Nº enlaces: %i\n",inodo.nlinks); printf("Bytes lógicos: %i\n",inodo.tamEnBytesLog); printf("Bloques ocupados: %i\n",inodo.numBloquesOcupados); //ESCRITURA if(mi_write_f(ninodo,entrada,offset,nbytes)!=nbytes){ printf("\nescribir: ERROR, no se ha escrito en el fichero correctamente.\n"); return -1; } //LECTURA printf("\nescribir:Se ha leído lo siguiente con el offset %ld:\n",offset); if(mi_read_f(ninodo,entrada,offset,nbytes)!=nbytes){ printf("\nescribir: ERROR, no se ha leído en el fichero correctamente.\n"); return -1; } write(1,entrada,nbytes); printf("\n\nInodo Actualizado:\n"); inodo = leer_inodo(ninodo); //IMPRIMIR INODO printf("\nNº INODO %i:\n",ninodo); printf("Tipo: %c\n",inodo.tipo); printf("Permisos: %i\n",inodo.permisos); printf("Nº enlaces: %i\n",inodo.nlinks); printf("Bytes lógicos: %i\n",inodo.tamEnBytesLog); printf("Bloques ocupados: %i\n",inodo.numBloquesOcupados); //Desmontamos el dispositivo. printf("\nescribir: Desmontando el dispositivo...\n\n"); bumount(); printf("\nescribir: Dispositivo desmontado con éxito.\n"); return 0; }
int traducir_bloque_inodo(unsigned int ninodo, unsigned int blogico, unsigned int *bfisico, char reservar) { int nPunterosDirectos = 12; int nPuntInd0 = BLOCKSIZE / 4; int nPuntInd1 = nPuntInd0 * nPuntInd0; int nPuntInd2 = nPuntInd0 * nPuntInd0 * nPuntInd0; int numPunt = BLOCKSIZE / 4; struct inodo inodoAux = leer_inodo(inodo); if (blogico < nPunterosDirectos) { //Si el puntero es directo if (reservar == '0') { if (inodoAux.punterosDirectos[blogico] == 0) { //si el bloque físico no existe return -1; } else { *bfisico = inodoAux.punterosDirectos[blogico]; //hallamos el bloque físico } } if (reservar == '1') { if (inodoAux.punterosDirectos[blogico] == 0) { //si el bloque físico no existe inodoAux.punterosDirectos[blogico] = reservar_bloque(); //reservamos el bloque //asignamos el bloque reservado al bloque físico *bfisico = inodoAux.punterosDirectos[blogico]; inodoAux.numBloquesOcupados++; escribir_inodo(inod, inodo); } *bfisico = inodoAux.punterosDirectos[blogico]; } } else if (blogico < nPunterosDirectos + nPuntInd0) { //puntero indirecto de nivel 0 if (reservar == '0') { if (inodoAux.punterosIndirectos[0] == 0) { return -1; } else { int array[nPuntInd0]; bread(inodoAux.punterosIndirectos[0], array); if (array[blogico - nPunterosDirectos] == 0) { //si el puntero leido no apunta a un bloque de datos return -1; } else { //si existe el bloque físico de datos *bfisico = array[blogico - nPunterosDirectos]; } } } if (reservar == '1') { if (inodoAux.punterosIndirectos[0] == 0) { //si el puntero indirecto de nivel 0 no apunta a nada int bufferPunt0[nPuntInd0]; memset(bufferPunt0, 0, BLOCKSIZE); inodoAux.punterosIndirectos[0] = reservar_bloque(); // reservamos el bloque de punteros indirectos bufferPunt0[blogico - nPunterosDirectos] = reservar_bloque(); //reservamos el bloque de datos inodoAux.numBloquesOcupados++; bwrite(inodoAux.punterosIndirectos[0], bufferPunt0); //escribimos el bloque reservado *bfisico = bufferPunt0[blogico - nPunterosDirectos]; escribir_inodo(inod, inodo); } else { int array[nPuntInd0]; bread(inodoAux.punterosIndirectos[0], array); //miramos si existe el bloque físico de datos // si no existe reservaremos el bloque if (array[blogico - nPunterosDirectos] == 0) { array[blogico - nPunterosDirectos] = reservar_bloque(); bwrite(inodoAux.punterosIndirectos[0], array); //escribimos el bloque para guardar los cambios inodoAux.numBloquesOcupados++; escribir_inodo(inod, inodo); } *bfisico = array[blogico - nPunterosDirectos]; } } // puntero indirecto nivel 1 } else if (blogico < nPunterosDirectos + nPuntInd0 + nPuntInd1) { int puntNiv0 = (blogico - (nPunterosDirectos + nPuntInd0)) % nPuntInd0; //puntero nivel 0 int puntNiv1 = (blogico - (nPunterosDirectos + nPuntInd0)) / nPuntInd0; //puntero nivel 1 if (reservar == '0') { if (inodoAux.punterosIndirectos[1] == 0) { return -1; } else { int array[numPunt]; bread(inodoAux.punterosIndirectos[1], array); if (array[puntNiv1] == 0) { return -1; } else { bread(array[puntNiv1], array); if (array[puntNiv0] == 0) { return -1; } else { *bfisico = array[puntNiv0]; } } } } if (reservar == '1') { int buffer[numPunt]; int bufferPunt1[numPunt]; int bufferPunt0[numPunt]; if (inodoAux.punterosIndirectos[1] == 0) { inodoAux.punterosIndirectos[1] = reservar_bloque(); memset(bufferPunt1, 0, BLOCKSIZE); bwrite(inodoAux.punterosIndirectos[1], bufferPunt1); } bread(inodoAux.punterosIndirectos[1], bufferPunt1); if (bufferPunt1[puntNiv1] == 0) { bufferPunt1[puntNiv1] = reservar_bloque(); memset(bufferPunt0, 0, BLOCKSIZE); bwrite(inodoAux.punterosIndirectos[1], bufferPunt1); bwrite(bufferPunt1[puntNiv1], bufferPunt0); } bread(bufferPunt1[puntNiv1], buffer); if (buffer[puntNiv0] == 0) { buffer[puntNiv0] = reservar_bloque(); inodoAux.numBloquesOcupados++; bwrite(bufferPunt1[puntNiv1], buffer); } escribir_inodo(inod, inodo); *bfisico = buffer[puntNiv0]; } //puntero indirecto nivel 2 } else if (blogico < nPunterosDirectos + nPuntInd0 + nPuntInd1 + nPuntInd2) { int puntNiv2 = (blogico - (nPunterosDirectos + nPuntInd0 + nPuntInd1)) / nPuntInd1; int puntNiv1 = ((blogico - (nPunterosDirectos + nPuntInd0 + nPuntInd1)) % nPuntInd1) / nPuntInd0; int puntNiv0 = ((blogico - (nPunterosDirectos + nPuntInd0 + nPuntInd1)) % nPuntInd1) % nPuntInd0; if (reservar == '0') { if (inodoAux.punterosIndirectos[2] == 0) { return -1; } else { int array[numPunt]; bread(inodoAux.punterosIndirectos[2], array); if (array[puntNiv2] == 0) { return -1; } else { bread(array[puntNiv2], array); if (array[puntNiv1] == 0) { return -1; } else { bread(array[puntNiv1], array); if (array[puntNiv0] == 0) { return -1; } else { *bfisico = array[puntNiv0]; } } } } } if (reservar == '1') { int buffer[numPunt]; int bufferPunt1[numPunt]; int bufferPunt2[numPunt]; if (inodoAux.punterosIndirectos[2] == 0) { inodoAux.punterosIndirectos[2] = reservar_bloque(); memset(bufferPunt2, 0, BLOCKSIZE); bwrite(inodoAux.punterosIndirectos[2], bufferPunt2); } bread(inodoAux.punterosIndirectos[2], bufferPunt2); if (bufferPunt2[puntNiv2] == 0) { bufferPunt2[puntNiv2] = reservar_bloque(); memset(bufferPunt1, 0, BLOCKSIZE); bwrite(inodoAux.punterosIndirectos[2], bufferPunt2); bwrite(bufferPunt2[puntNiv2], bufferPunt1); } bread(bufferPunt2[puntNiv2], bufferPunt1); if (bufferPunt1[puntNiv1] == 0) { bufferPunt1[puntNiv1] = reservar_bloque(); int bufPunt0[numPunt]; memset(bufPunt0, 0, BLOCKSIZE); bwrite(bufferPunt2[puntNiv2], bufferPunt1); bwrite(bufferPunt1[puntNiv1], bufPunt0); } bread(bufferPunt1[puntNiv1], buffer); if (buffer[puntNiv0] == 0) { buffer[puntNiv0] = reservar_bloque(); inodoAux.numBloquesOcupados++; escribir_inodo(inod, inodo); bwrite(bufferPunt1[puntNiv1], buffer); } *bfisico = buffer[puntNiv0]; } } return 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); }
int main (int argc,char **argv) { if (argc == 2) { signal(SIGCHLD,reaper); mount(argv[1]); struct inodo in; if (leer_inodo(&in, 0) < 0) { printf("ERROR (simulacion.c -> mi_stat(/)): Error al leer el estado\n"); } struct superbloque SB; if (bread(0, (char *)&SB) < 0) { printf("ERROR (simulacion.c -> error al leer el superbloque)\n"); } if (in.t_bytes > 0) { vaciar(); initSB(SB.n_bloques, argv[1]); initMB(SB.n_bloques); initAI(SB.n_bloques); } int i; for (i = 0; i < N_PROCESOS; i++) { int hilo = fork(); if (hilo == 0) { if (proceso(i) < 0) { printf("ERROR (simulacion.c): Error al crear el proceso %d.\n", i); return (-1); } exit(0); } else if (hilo < 0) { i--; printf("Llamamos al reaper, hilo = %d\n", hilo); reaper(); } sleep(1); } while (acabados < N_PROCESOS) { pause(); } unmount(argv[1]); } else { printf("ERROR (simulacion.c): Error, parámetros != de 2 (%d).\n", argc); return (-1); } return (0); }
/*Escribe el contenido de un buffer (buf_original dado por parámetro) en un fichero o directorio (inodo pasado por argumento) * offset: posicion inicial de escritura con respeccto al inodo (bytes) * nbytes: nº de bytes a escribir * devuelve la cantidad de bytes escritos (si es que ha escrito bytes) */ int mi_write_f(unsigned int ninodo, const void *buf_original, unsigned int offset, unsigned int nbytes) { struct superbloque sbloq; struct inodo inode; inode = leer_inodo(ninodo); unsigned int bfisico; //Para el uso de la función traducir_bloque_inodo unsigned int bytes_escritos; unsigned char buf_bloque[BLOCKSIZE]; memset(buf_bloque, 0, BLOCKSIZE); if ((inode.permisos & 2) != 2) { //Si no tenemos permisos de escritura devolvemos un error printf("ERROR: ficheros.c => mi_write => No se tienen permisos de escritura\n"); return -1; } else { //en caso contrario, escribimos el buffer en la posición indicada //primer bloque lógico a escribir int primerBlogico = offset / BLOCKSIZE; //último bloque lógico a escribir int ultimoBlogico = (offset + nbytes - 1) / BLOCKSIZE; //desplazamientos int desp1 = offset % BLOCKSIZE; //despl. en el primer bloque int desp2 = (offset + nbytes - 1) % BLOCKSIZE; //despl. en el último bloque //caso 1 if (primerBlogico == ultimoBlogico) { /* Hacemos un bread de este bloque (con ayuda de la función traducir_bloque_inodo) * y almacenamos el resultado en un buffer llamado buf_bloque. */ if (traducir_bloque_inodo(ninodo, primerBlogico, &bfisico, 1) == -1) { printf("ERROR: ficheros.c -> mi_write_f => Error al traducir el bloque lógico %d\n", primerBlogico); return -1; } if (bread(bfisico, buf_bloque) == -1) {//leemos el bloque en el que vamos a escribir printf("ERROR: ficheros.c -> mi_write_f => Error al leer el bloque físico %d\n", bfisico); if (bread(posSB, (char *) &sbloq) == -1) printf("\tficheros.c -> mi_write_f => Error al leer el superbloque \n"); else if (sbloq.totBloques < bfisico) printf("\tficheros.c -> mi_write_f => bfisico fuera de rango\n"); return -1; } //Escribimos el contenido de 'buf_original' en la posición correspondiente del buffer memcpy(buf_bloque + desp1, buf_original, nbytes); /*Hacemos un bwrite del buf_bloque (con los nuevos datos, preservando los que contenía), * en el bloque que nos devuelva la función y guardamos la cantidad de bytes escritos */ if (bwrite(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_write_f => (Caso 1) Error al escribir el bloque %d \n", bfisico); } bytes_escritos = nbytes; //devolvemos la cantidad de bytes escritos } else { //caso 2: primerByteLogico != ultimoByteLogico /////tratamiento del primer bloque lógico /* Hacemos un bread de este bloque (con ayuda de la función traducir_bloque_inodo) * y almacenamos el resultado en un buffer llamado buf_bloque. */ if (traducir_bloque_inodo(ninodo, primerBlogico, &bfisico, 1) == -1) { printf("ERROR: ficheros.c -> mi_write_f => Error al traducir el bloque lógico %d\n", primerBlogico); return -1; } if (bread(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_write_f => (Tratamiento PBL) Error al leer el bloque %d\n", bfisico); return -1; } memcpy(buf_bloque + desp1, buf_original, BLOCKSIZE - desp1); /*Hacemos un bwrite del buf_bloque (con los nuevos datos, preservando los que contenía), * en el bloque que nos devuelva la función */ bytes_escritos = BLOCKSIZE - desp1; //primeros bytes escritos if (bwrite(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_write_f => (Tratamiento PBL) Error al escribir el bloque %d \n", bfisico); } //tratamiento de los bloques intermedios int i; for (i = primerBlogico + 1; i < ultimoBlogico; i++) { if (traducir_bloque_inodo(ninodo, i, &bfisico, 1) == -1) { printf("ERROR: ficheros.c -> mi_write_f => Error al traducir el bloque lógico %d\n", i); return -1; } //buf_bloque = buf_original + (BLOCKSIZE - desp1) + (i - primerBlogico - 1) * BLOCKSIZE; int var = bwrite(bfisico, buf_original + (BLOCKSIZE - desp1) + (i - primerBlogico - 1) * BLOCKSIZE); //bytes escritos en el bloque intermedio actual if (var != BLOCKSIZE) {//comprobamos si se ha escrito el bloque al completo printf("ERROR: ficheros.c -> mi_write_f => (Tratamiento bloques intermedios) No se ha escrito el bloque %d al completo\n", bfisico); } bytes_escritos = bytes_escritos + var; //sumamos los bytes escritos en este bloque intermedio } //tratamiento del último bloque if (traducir_bloque_inodo(ninodo, ultimoBlogico, &bfisico, 1) == -1) { printf("ERROR: ficheros.c -> mi_write_f => Error al traducir el bloque lógico %d\n", ultimoBlogico); return -1; } if (bread(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_write_f => (Tratamiento UBL) Error al leer el bloque %d \n", bfisico); return -1; } memcpy(buf_bloque, buf_original + (nbytes - desp2 - 1), desp2 + 1); if (bwrite(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_write_f => (Tratamiento UBL) Error al escribir el bloque %d \n", bfisico); } bytes_escritos = bytes_escritos + desp2 + 1; } //Finalmente y en todo caso: //Leemos el inodo inode = leer_inodo(ninodo); //Actualizar el tamaño en bytes lógicos si hemos escrito más allá del final del fichero if (inode.tamEnBytesLog < offset + bytes_escritos) {//En el caso de que tengamos que aumentar el tamaño del fichero inode.tamEnBytesLog = offset + bytes_escritos; //actualizamos el tamaño de bytes lógicos de la metainformación } //actualizar mtime y el ctime inode.ctime = time(NULL); inode.mtime = time(NULL); //Escribir el inodo if (escribir_inodo(inode, ninodo) == -1) { printf("ERROR: ficheros.c -> mi_write_f => Error al escribir inodo %d \n", ninodo); return -1; } } return bytes_escritos; //si todo va bien bytes_escritos=nbytes }
int mi_read_f(unsigned int ninodo, void *buf_original, unsigned int offset, unsigned int nbytes) { struct inodo inode; inode = leer_inodo(ninodo); unsigned int bfisico; //Para el uso de la función traducir_bloque_inodo unsigned int bytes_leidos = 0; unsigned int desp_buffer = 0; //bytes_leidos sin contar los bloques vacíos unsigned char buf_bloque[BLOCKSIZE]; memset(buf_bloque, 0, BLOCKSIZE); if ((inode.permisos & 4) != 4) { //Si no tenemos permisos de lectura devolvemos un error printf("ERROR: ficheros.c => mi_read_f => No se tienen permisos de lectura\n"); return -1; } else { //en caso contrario, leemos el buffer en la posición indicada if (offset + nbytes >= inode.tamEnBytesLog) { nbytes = inode.tamEnBytesLog - offset; // leemos sólo los bytes que podemos desde el offset hasta el final de fichero } if (offset > inode.tamEnBytesLog) { nbytes = 0; return nbytes; //no leemos nada } int primerBlogico = offset / BLOCKSIZE; //primer byte lógico a leer int ultimoBlogico = (offset + nbytes - 1) / BLOCKSIZE; //último byte lógico a leer //desplazamientos int desp1 = offset % BLOCKSIZE; //despl. en el primer bloque int desp2 = (offset + nbytes - 1) % BLOCKSIZE; //despl. en el último bloque //caso 1 if (primerBlogico == ultimoBlogico) { int resultado_traducir = traducir_bloque_inodo(ninodo, primerBlogico, &bfisico, 0); if (resultado_traducir == -1) { printf("ERROR: ficheros.c -> mi_read_f => Error al traducir el bloque lógico %d\n", primerBlogico); return -1; } if (resultado_traducir == -2) {//bloque lógico vacío bytes_leidos = nbytes; //lo indicamos como leído pero no pasamos nada al buffer de salida } else {//sino leemos y pasamos el contenido al buffer if (bread(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_read_f => Error al leer el bloque %d\n", bfisico); return -1; } memcpy(buf_original, buf_bloque + desp1, nbytes); //copiamos el contenido en el buffer de salida bytes_leidos = nbytes; } } else { //caso 2 primerBloqueLogico != ultimoBloqueLogico //tratamiento del primer bloque lógico int resultado_traducir = traducir_bloque_inodo(ninodo, primerBlogico, &bfisico, 0); if (resultado_traducir == -1) { printf("ERROR: ficheros.c -> mi_read_f => Error al traducir el bloque lógico %d\n", primerBlogico); return -1; } if (resultado_traducir == -2) {//bloque lógico vacío bytes_leidos = BLOCKSIZE - desp1; //lo indicamos como leído pero no pasamos nada al buffer de salida ni desplazamos el puntero } else {//leemos el primer bloque if (bread(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_read_f => (Tratamiento PBL) Error al leer el bloque %d\n", bfisico); return -1; } memcpy(buf_original, buf_bloque + desp1, BLOCKSIZE - desp1); //guardamos los bytes leídos en el buffer de salida bytes_leidos = BLOCKSIZE - desp1; //guardamos la cantidad de bytes leidos desp_buffer = bytes_leidos; //posición del puntero de buf_original } //tratamiento de los bloques intermedios int i; for (i = primerBlogico + 1; i < ultimoBlogico; i++) { int resultado_traducir = traducir_bloque_inodo(ninodo, primerBlogico, &bfisico, 0); if (resultado_traducir == -1) { printf("ERROR: ficheros.c -> mi_read_f => Error al traducir el bloque lógico intermedio %d\n", i); return -1; } if (resultado_traducir == -2) {//bloque lógico vacío bytes_leidos = bytes_leidos + BLOCKSIZE; //lo indicamos como leído pero no pasamos nada al buffer de salida ni desplazamos el puntero } else {//leemos el bloque if (bread(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_read_f => (Tratamiento bloques intermedios) Error al leer el bloque %d\n", bfisico); return -1; } memcpy(buf_original + desp_buffer, buf_bloque, BLOCKSIZE); //guardamos los bytes leídos en el buffer de salida bytes_leidos = bytes_leidos + BLOCKSIZE; //guardamos la cantidad de bytes leidos desp_buffer = desp_buffer + BLOCKSIZE; //actualizamos la posición del puntero de buf_original } } //tratamiento del último bloque resultado_traducir = traducir_bloque_inodo(ninodo, ultimoBlogico, &bfisico, 0); if (resultado_traducir == -1) { printf("ERROR: ficheros.c -> mi_read_f => Error al traducir el bloque lógico %d\n", ultimoBlogico); return -1; } if (resultado_traducir == -2) {//bloque lógico vacío bytes_leidos = desp2 + 1; //lo indicamos como leído pero no pasamos nada al buffer de salida ni desplazamos el puntero } else {//leemos el primer bloque if (bread(bfisico, buf_bloque) == -1) { printf("ERROR: ficheros.c -> mi_read_f => (Tratamiento PBL) Error al leer el bloque %d\n", bfisico); return -1; } memcpy(buf_original, buf_bloque, desp2 + 1); //guardamos los bytes leídos en el buffer de salida bytes_leidos = bytes_leidos + desp2 + 1; //guardamos la cantidad de bytes leidos } } //Finalmente y en todo caso: //Leemos el inodo inode = leer_inodo(ninodo); //actualizar sellos de tiempo inode.ctime = time(NULL); inode.mtime = time(NULL); inode.atime = time(NULL); //Escribir el inodo if (escribir_inodo(inode, ninodo) == -1) { printf("ERROR: ficheros.c -> mi_read_f => Error al escribir inodo %d \n", ninodo); return -1; } } return bytes_leidos; }
int mi_read_f(unsigned int ninodo, void *buf, unsigned int offset, unsigned int nbytes){ struct inodo Inodo = leer_inodo(ninodo); if(!(Inodo.permisos & 4)){ printf("Error: no tiene los permisos necesarios\n"); return -1; } if(offset + nbytes > Inodo.tamEnBytesLog){ //si se quiere leer mas de lo que ocupa el fichero nbytes = Inodo.tamEnBytesLog - offset; } if(offset >= Inodo.tamEnBytesLog){ //Se quiere leer mas alla del final de fichero nbytes = 0; return nbytes; } int bFisico = 0; unsigned int primerLogico = offset/BLOCKSIZE; unsigned int ultimoLogico = (offset+nbytes-1)/BLOCKSIZE; unsigned char buffer[BLOCKSIZE]; memset(buffer, 0, sizeof(buffer)); int bytesleidos = 0; if(primerLogico == ultimoLogico){ //se lee un unico bloque bFisico = traducir_bloque_inodo(ninodo, primerLogico, 0); if(bread(bFisico, &buffer) < 0){ return -1; } int desp1 = offset % BLOCKSIZE; memcpy(buf, buffer+desp1, nbytes); bytesleidos += nbytes; }else{ // Hay que leer varios bloques // Primer bloque bFisico = traducir_bloque_inodo(ninodo, primerLogico, 0); if(bread(bFisico, &buffer) < 0){ return -1; } int desp1 = offset % BLOCKSIZE; memcpy(buf, buffer + desp1, BLOCKSIZE - desp1); bytesleidos += BLOCKSIZE - desp1; memset(buffer, 0, sizeof(buffer)); // Bloques intermedios int i; for(i = primerLogico + 1; i < ultimoLogico; i++){ bFisico = traducir_bloque_inodo(ninodo, i, 0); if(bread(bFisico, &buffer) < 0){ return -1; } memcpy(buf + bytesleidos, buffer, BLOCKSIZE); bytesleidos += BLOCKSIZE; memset(buffer, 0, sizeof(buffer)); } // Ultimo bloque int desp2 = (offset + nbytes - 1) % BLOCKSIZE; bFisico = traducir_bloque_inodo(ninodo, ultimoLogico, 0); if(bread(bFisico, &buffer) < 0){ return -1; } memcpy(buf + bytesleidos, buffer, desp2 + 1); bytesleidos += desp2 + 1; } Inodo = leer_inodo(ninodo); Inodo.atime = time(NULL); if(escribir_inodo(Inodo, ninodo) < 0){ return -1; } return bytesleidos; }
int mi_write_f(unsigned int ninodo, const void *buf_original, unsigned int offset, unsigned int nbytes){ struct inodo Inodo = leer_inodo(ninodo); int bytesEscritos = 0; unsigned int primerLogico = offset/BLOCKSIZE; unsigned int ultimoLogico = (offset+nbytes-1)/BLOCKSIZE; if ((Inodo.permisos & 2) != 2) { printf("No tienes permisos de escritura.\n"); return -1; } if(primerLogico == ultimoLogico){ // Un unico bloque modificado unsigned char bufBloque[BLOCKSIZE]; memset(bufBloque, 0, sizeof(bufBloque)); int desp1 = offset%BLOCKSIZE; int bFisico = traducir_bloque_inodo(ninodo, primerLogico, 1); //reserva del bloque fisico if(bread(bFisico, bufBloque) < 0){ return -1; } memcpy(bufBloque+desp1, buf_original, nbytes); int incremento; if((incremento = bwrite(bFisico, &bufBloque)) < 0){ return -1; } bytesEscritos += incremento; }else{ // Primer bloque int desp = 0; unsigned char bufBloque[BLOCKSIZE]; memset(bufBloque, 0, sizeof(bufBloque)); int desp1 = offset%BLOCKSIZE; int bFisico = traducir_bloque_inodo(ninodo, primerLogico, 1); //reserva del bloque fisico if(bFisico < 0) return bytesEscritos; if(bread(bFisico, bufBloque) < 0) return -1; memcpy(bufBloque+desp1, buf_original, BLOCKSIZE-desp1); int incremento; if((incremento = bwrite(bFisico, &bufBloque)) < 0){ return -1; } desp += desp1; bytesEscritos += incremento; // Bloques intermedios int i; for(i = primerLogico + 1; i < ultimoLogico; i++){ bFisico = traducir_bloque_inodo(ninodo, i, 1); if(bFisico < 0) return bytesEscritos; memcpy(bufBloque, buf_original + (BLOCKSIZE - desp1) + (i - primerLogico - 1) * BLOCKSIZE, BLOCKSIZE); int incremento; if((incremento = bwrite(bFisico, &bufBloque)) < 0){ return -1; } bytesEscritos += incremento; } // Último bloque int desp2 = (offset+nbytes-1)%BLOCKSIZE; bFisico = traducir_bloque_inodo(ninodo, ultimoLogico, 1); if(bFisico < 0) return bytesEscritos; if(bread(bFisico, &bufBloque) < 0){ return -1; } memcpy(bufBloque, buf_original + (nbytes - desp2 - 1), desp2 + 1); if((incremento = bwrite(bFisico, &bufBloque)) < 0){ return -1; } bytesEscritos += incremento; } // Actualizar informacion del inodo Inodo = leer_inodo(ninodo); if(offset+nbytes > Inodo.tamEnBytesLog){ Inodo.tamEnBytesLog = offset + nbytes; } Inodo.mtime = time(NULL); Inodo.ctime = time(NULL); if(escribir_inodo(Inodo, ninodo) < 0){ return -1; } return bytesEscritos; }
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; }