Exemple #1
0
/*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;
}
Exemple #2
0
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;
}
Exemple #3
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);
}
Exemple #5
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;
}
Exemple #6
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);
}
Exemple #7
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
}
Exemple #8
0
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;
}
Exemple #10
0
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;
}
Exemple #11
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;
}