IMPLEMENTACION DE UN SISTEMA DE ARCHIVOS


TEMARIO

  1. Tipos de archivos
  2. Estructura del sistema de archivos
  3. Lista de Nodos-i
  4. Estructura del Super-Bloque
  5. Implementación de Directorios
  6. Implementación de dispositivos
  7. Dispositivos de Bloques
  8. Dispositivos de caracteres
  9. Una lista de dispositivos importantes

 

1. Tipos de archivos

Desde el punto de vista del sistema operativo existen cuatro tipos básicos de archivos:

a) Archivos normales: Archivos que contienen datos. Incluyen archivos de datos propiamente dichos, ejecutables, texto, programas fuente, etc. UNIX no presupone estructura en los archivos: son, desde su punto de vista, arreglos unidimensionales de bytes.

b) Directorios: Contienen referencias a los archivos que se encuentran dentro de ellos.

c) Dispositivos de caracteres. Todo tipo de periféricos que intercambian datos un byte a la vez. Incluyen terminales, impresoras, lectores ópticos lineas de comunicación, etc.

d) Dispositivos de Bloques Periféricos que intercambian datos en bloques de varios bytes, normalmente 512. Incluyen discos duros, floppies, unidades de cinta, etc.

Los dos últimos tipos reciben el nombre genérico de archivos especiales. Generalmente se encuentran en el directorio /dev. Un "ls -1" permite observar el tipo de archivo particular.

2. Estructura del sistema de archivos

Todo archivo independientemente de su tipo, debe existir dentro del sistema de archivos. Un sistema UNIX permite tener varios sistemas de archivos, en diferentes dispositivos 1ooi~os. La oraanización v nombre de éstos dispositivos

a) Bloque

b) Super Bloque (bloque 1)

c) Lista de nodos-i (conocida como lista-i)

d) Posiblemente un área de swap

e) Bloques de datos

El bloque O no es usado por el sistema de archvivos, si existe un programa de boot en el dispositivo lógico, éste se encuentra en este bloque.

El super bloque contiene datos generales del sistema de archivos. Haremos una descripción detallada de estos datos después.

3. Lista de Nodos-i

La lista es propiamente lo que podríamos llamar el "directorio" del dispositivo, es decir el lugar en el que se encuentran las direcciones de los archivos. La lista-i consiste de registros llamados nodos-i. Un nodo-i a su vez tiene 64 bytes de largo y tiene las siguiente estructura:

di node . modo y tipo de archivo di nlink . número de ligas (links) del archivo di uid . identificación del usuario di gid identificación del grupo di size . longitud en bytes del archivo di addr lista de direcciones en disco di atime : fecha y hora del último acceso di mtime. fecha y hora de última modificación di ctime . fecha y hora de creación

El tipo de un archivo es la codificación de los cuatro tipos que discutíamos antes.

El modo es la codificación de los permisos de acceso.

Todo archivo tiene un usuario propietario y un grupo propietario; los permisos de acceso están referidos a éstos.

Asimismo, el nodo-i contiene, como se puede ver, información de acceso al archivo.

Las direcciones se refieren a los bloques, contenidos en la parte de bloques de datos, que contienen propiamente los datos del archivo. Estas direcciones se reparten como sigue:

l0 direcciones de acceso directo. Apuntan directamente al bloque de datos (5120 bytes>

1 dirección de acceso indirecto simple. Apunta a un bloque en el área de datos (bloque de indirección). (70656 bytes)

1 dirección de acceso indirecto doble. Apunta a su vez a un bloque de indirección que a su vez apunta a 128 bloques de indirección. (8,459,264 bytes)

1 dirección de acceso indirecto triple (1,082,201,088 bytes)

Finalmente, el número de ligas es la cantidad de referencias lógicas al mismo archivo físico (comando ln). Cuando decrece a cero, el nodo-i es liberado, así como los bloques a los que apuntaba.

La posición que ocupa un nodo-i desde el principio de la lista-i comenzando en 1, es conocida como su número i.

No existe ningún archivo asociado al número-i 1. En algunas implementaciones, se emplea éste para ligar los bloques dañados de un disco. El número-i 2 es la raíz de todo el sistema de archivos.

4. Estructura del Super-Bloque

Podemos dar ahora una ojeada a la estructura del super-bloque:

s_ isize Tamaño en bloques de la lista-i

s_fsize Tamaño en bloques del sistema de archivos

s_nfree Número de direcciones en s_free

s_free Arreglo (lista) de bloques libres

s_ninode Número de direcciones en s_inode

s_inode Lista de nodos-i libres

s_fblock Bandera de lock para manipulación de lista libre

s_ilock Bandera de lock para manipulación de lista de nodos-i libres

s_fmod Bandera de modificación de superbloque

s_rdonly Bandera de mount sólo para lectura

s_time Ultima fecha de modificación del superbloque

s_dinfo Información sobre el dispositivo:

s_m factor módulo en superbloque (interleave) s_n tamaño en bloques del cilindro del dispositivo

s_bsize Tamaño en bloques del cilindro del dispositivo

s_tfree Número tltal de bloques libres

s_tinode Número total de nodos-i libres

s_fname Nombre del sistema de archivos (etiqueta)

s_f pack Nombre del pack

s_fill Filler para llegar a 512 bytes

s_swaplo Comienzo del área de swap

s_nswap Longitud del área de swap

s_magic Número mágico para el sistema de archivos

s_type Tipo de sistema de archivos

Al iniciar el sistema, el superbloque es copiado a memoria, y sus cambios en operación no son actualizados directamente a disco. Algunos de los campos anteriores son claros pero el manejo de la lista de bloques libres merece una mención especial. El sistema mantiene una lista inmediata de bloques libres, para que su ubicación sea rápida; conforme se usa ésta lista el parámetro s_nfree va decreciendo; al llegar a 0, se copia una nueva lista a s_nfree. Como s_free tiene un tamaño limitado, no puede contener todos los bloques libres; éstos se mantienen en una lista ligada, con el último (o primero, s_nfree se recorre en sentido inverso) bloque de s_nfree apuntando al inicio de la lista ligada.

La misma filosofía se emplea para la ubicación de nodos-i en s_ninode.

Las banderas de lock sirven para bloquear el acceso al super-bloque en memoria, cuando se está actualizando alguna de las listas.

La bandera s_fmod en memoria indica que el super bloque ha sido modificado, y que debería escribirse a disco, esta bandera indica si el sistema de archivos es coherente o debería ser verificado. (fsck)

5. Implementación de Directorios

También los directorios son archivos desde el punto de vista de UNIX, es decir, tienen un nodo-i asociado. La única diferencia con un archivo normal es que el sistema lo tiene registrado como directorio en la información del nodo-i correspondiente. Asimismo, el directorio, visto como archivo, contiene datos. Podemos ver esos datos como registros que contienen la siguiente información:

a) Un número-i

b) Un nombre de archivo

Cada registro representa un archivo que se encuentra en el directorio, y el número-i asociado, que es el verdadero "nombre" del archivo para el sistema. Así, cuando se específica un nombre de archivo, UNIX lo transforma en un nodo-i para poder localizarlo en disco.

Por ejemplo, para abrir el archivo /a/b/c, el sistema va al directorio root, cuyo número-i es conocido (es 2 ), abre el archivo 2 y lee los registros secuencialmente, hasta encontrar el nombre a. Una vez encontrado, toma el número-i asociado, abre el archivo respectivo y lee buscando el nombre b, etc.

6. Implementación de dispositivos

Como queda dicho, UNIX tiene dos tipos de dispositivos: de bloques y de caracteres. También éstos son archivos, es decir, tienen un número-i, pero no contienen datos. En lugar de las direcciones a bloques, tienen dos números:

a) el número mayor

b) el número menor

El número mayor es un índice a la tabla de manejadores (drivers) del kernel, que le indica a éste que manejador emplear para manipular el dispositivo en cuestión. Estos manejadores son rutinas dentro del propio kernel, pero en ciertas implementaciones son modificables por el usuario.

El número menor se le pasa como parámetro al manejador, y su significado varía; pero generalmente sirve para discriminar entre varios dispositivos idénticos. Por ejemplo, el mismo manejador puede servir para tener acceso a dos discos duros distintos, ó a diez terminales, etc.

7. Dispositivos de Bloques

Los dispositivos de bloques son aquellos en los que la entrada/salida sucede siempre en bloques de tamaño fijo, generalmente de 512 bytes. Dispositivos de bloques típicos son: discos duros, diskettes, cintas magnéticas, etc.

Toda la entrada y salida funcionan a través de un "pool" de "buffers" cada unode los cuales está asociado a un dispositivo de bloque (por ejemplo, el disco duro #l), y a una dirección en ese dispositivo (por ejemplo, el bloque 1234 de la cabeza 2 de la pista 56 ). Al leer por primera vez el contenido de ese bloque, se busca un lugar libre en el "pool" y se asocia al bloque en cuestión. Toda la información del bloque se copia al buffer, desde donde el usuario puede irla leyendo por pedazos. Lo mismo sucede al escribir a disco: realmente se escribe al buf fer. Si el "pool" de buffers se llena y se requiere otro buffer, el sistema borra el buf fer más viejo, no sin antes escribirlo a disco si el usuario le hizo alguna modificación.

Como se ve, la entrada/salida es asincrónica, minimizando I/O físico, pero evitando la seguridad de que un cambio es actualizado de inmediato; sin embargo, cualquier usuario puede forzar que todos los buffers "sucios", es decir, que han sido modificados, a ser escritos. La utilería que causa este efecto se llama "sync". Por otro lado, el mismo sistema, operativo escribe a intervalos regulares (30 segundos a 1 minuto) los buf fers sucios. Al mismo tiempo, la imagen en memoria del super bloque es actualizada en disco.

Generalmente, todo dispositivo de bloques puede accesarse también como dispositivo de caracteres. Por ejemplo, /dev/hd0, el disco duro, es un dispositiv de bloques; pero existe también /dev/rhdO, que es el mismo disco duro, pero manejado como dispositivo de caracteres.

8. Dispositivos de caracteres

Estos incluyen terminales, impresoras, etc.

Un manejador para dispositivos de caracteres, específicamente para terminales, administra normalmente tres colas.

a) Cola de salida

b) Cola de entrada en bruto (raw)

c) Cola de entrada procesada (cooked)

Al escribir un proceso al dispositivo, el sistema va llenando la cola de salida, hasta que ésta se llena; en ese momento, el proceso espera a que el sistema vacíe la cola, mandando la información al dispositivo físico. Sin embargo, no es necesario que la cola se llene para que el sistema vaya escribiendo. Si el dispositivo es una terminal, cierto tipo de procesamiento de la salida puede ocurrir (ver stty).

La cola de entrada en bruto recibe textualmente los caracteres que el dispositivo manda; al detectar el fin de línea (line-feed>, escribe los caracteres a la cola procesada. El proceso que está leyendo el dispositivo lee normalmente de esta última cola. La copia de una cola a otra no es textual, ya que ocurre cierta edición en la línea de acuerdo a ciertos caracteres especiales; por ejemplo, si el usuario teclea desde la terminal un caracter de retroceso (backspace>, el sistema borra el caracter anterior; si el usuario teclea un control-d, el sistema lo interpreta como un final de archivo; finalmente, DEL y control-\ son interpretados como señales que normalmente terminan los procesos.

El usuario, por otro lado, tiene una gran libertad para configurar el manejo de estas colas (ver stty): puede mapear los caracteres a otros distintos, prescindir de la cola procesada, prescindir de caracteres especiales, configurar la velocidad del puerto, etc.

9. Una lista de dispositivos importantes