inode_read()

¿Los títulos están mal escritos o son intencionales...?

Un poco de explicación...

Bien, ahora que ya tuviste un acercamiento con un Indexed File System, te aseguro que las funciones que quedan pues, conceptualmente no te tardarás en enterderlos pero en la implementación si te lleves un poco de tiempo.

Como siempre, la sugerencia es que te encuentres en condiciones para trabajar. Encontrarás que la matemática es interminable en estas funciones.

Directo al grano, ahora después de haber creado el Inode y haber guardado los contenidos del archivo creado, ya puedes efectuar operaciones de lectura y escritura. La lectura es mucho más sencillo que la escritura, porque no tienes la tarea adicional de expandir o contraer el archivo; solamente leer contenidos.

Ahora bien, es necesario que consideres fuertemente los siguientes puntos:

  • Únicamente puedes leer los contenidos dentro del rango válido de bytes.

  • Si llegas al EOF, dejas de leer el archivo.

  • Si el punto de inicio de la lectura es pasado del EOF, simplemente no lees nada.

Trivialmente, estarás leyendo una estructura de un Inode, entonces deberás recorrer la cantidad de bloques (directo, indirecto o doble indirecto) necesarias. Harás un uso extensivo del Buffer Cache y de las operaciones malloc(), realloc() y free().

Implementación

Bien, empezaremos con un código base para que puedas empezar desde 0. A estas alturas, no creo que sea necesario explicarte qué significa cada parámetro de la firma de la función.

off_t
inode_read_at (struct inode *inode, void *buffer_, off_t size, off_t offset) 
{
  uint8_t * buffer = buffer_;
  off_t bytes_read = 0;

  while (size > 0) {
     /* Tu codiguito aqui :D */
  }
  return bytes_read;
}

Prácticamente, lo que tienes que hacer se resume en los siguientes pasos:

  1. Sanity Check

  2. Posicionarte en el byte inicial e ir leyendo 512 bytes o menos hasta que logres leer todos los bytes que se te solicitaron.

  3. Retornar la cantidad verdadera de bytes que has leído del archivo (¿recuerdas el EOF?)

Encontrando la posición inicial

Para empezar a leer el archivo, debes de colocarte en el byte correcto. Como sabes, el archivo está fragmentado en sectores que están esparcidos por todo el disco duro y la única manera que logras ubicar esos sectores es por medio del inode.

Entonces, como primer paso, debes de calcular en qué bloque se encuentra el byte inicial (ya sea en un directo, indirecto o doble indirecto).

Si es un bloque directo, simplemente lees del Buffer Cache el sector que es apuntado por ese bloque directo.

Si es un bloque indirecto, debes traer del disco al Buffer Cache el sector identificado por ese bloque indirecto y, si recuerdas qué guarda ese sector, debes de realizar todos los cálculos necesarios para obtener el identificador correcto de esos 128 identificadores guardados. Y por último lees el sector.

Si es un bloque doble indirecto, debes de calcular cuál de todos los bloques indirectos es el correcto, y luego calcular cuál de todos esos 128 identificadores es el correcto. Por último lees el sector.

¿Parece un proceso recursivo, no es así? La implementación queda a tu discreción.

Sería conveniente hacer una función que haga todo ese relajo, ¿no es así? Además, puede ser de mucha utilidad en la siguiente función que corresponde implementar: inode_write().

Leyendo los contenidos del archivo

Como te habrás dado cuenta, estarás leyendo de sector en sector, es decir, de 512 bytes en 512 bytes. Y cuando termines de leer el sector actual, deberás de leer del disco al Buffer Cache el siguiente sector que corresponde.

Otra vez... suena muy útil hacer una función que cargue el siguiente sector, ¿no es así? ¡Y puede ser reutilizado!

Prácticamente esta lectura de sector en sector se repite tantas veces hasta que lees la cantidad de bytes que es solicitado. Debes de tener mucha precaución, porque debes de implementar esa función considerando que barres todos los bloques.

La ventaja del diseño de la implementación que hicimos, empezamos leyendo los bloques directo, luego el bloque indirecto y por último el bloque doble indirecto. Los primeros resultan ser bastante fácil, pero se empieza a complicar con el bloque indirecto. Ahora bien, si haces bien la lectura de los sectores apuntados por el bloque indirecto, este código puede ser reutilizado para la lectura de los sectores relacionados con el bloque doble indirecto.

¡No te olvides del EOF ni de devolver la cantidad verdadera de bytes leídos!

FAQ

  • ¿Hay alguna función que me permita leer los contenidos del sector al buffer?

    Sí, memcpy()

  • ¿Hotel?

    Trivago

Last updated