Gestión de Ficheros.
Transcripción
Gestión de Ficheros.
6LVWHPDVGH)LFKHURV El sistema de ficheros es uno de los aspectos más visibles del sistema operativo, pues proporciona el mecanismo para el almacenamiento masivo de programas y datos, tanto del propio sistema operativo como de todos los usuarios del ordenador. El sistema de ficheros está formado por dos partes esenciales: una colección de ILFKHURV, conteniendo cada uno de ellos datos relacionados, y una HVWUXFWXUD GH GLUHFWRULRV que organiza y proporciona información de todos los ficheros del sistema. En este capítulo trataremos aspectos sobre los ficheros y directorios, el compartimiento entre varios procesos y la protección necesaria en entornos con múltiples usuarios. También abordaremos cuestiones concernientes al almacenamiento y acceso de ficheros en el más común de los dispositivos de memoria secundaria: el disco. Examinaremos distintos modos de asignación y recuperación de espacio en el disco, y veremos también cómo se puede llevar la cuenta del espacio que ocupan los ficheros en el disco. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV ,QWURGXFFLyQ Todos los programas necesitan almacenar y recuperar la información. Mientras un proceso se ejecuta, puede guardar una cierta cantidad de información en su propio espacio de direcciones, es decir, la memoria principal; pero la capacidad de ésta está limitada, como mucho, al tamaño de la memoria virtual. Para algunos programas, esta cantidad de espacio es suficiente, pero para otros, como por ejemplo reservas aéreas o aplicaciones bancarias, resulta pequeña. Otro problema que se tiene al guardar la información en la memoria principal es que cuando el proceso termina la información se pierde y, claro, para muchas aplicaciones, como las bases de datos, la información debe retenerse durante semanas, meses, o incluso para siempre. Frecuentemente resulta necesario que múltiples procesos accedan a cierta información al mismo tiempo. Por ejemplo, si se mantiene una guía telefónica en el espacio de memoria de un proceso, solamente ese proceso puede acceder a la información, por lo que únicamente se puede buscar un número de teléfono a la vez, dando lugar a que los procesos que desean obtener un número deben ir accediendo a la guía de uno en uno. La manera de resolver este problema es haciendo que la información sea independiente del espacio de direcciones de los procesos. Así, tenemos tres requisitos esenciales para el almacenamiento de memoria a largo plazo: 1. Se debe poder almacenar una cantidad de información muy grande. 2. La información debe permanecer después de la terminación de los procesos que la utilizan. 3. Múltiples procesos deben poder acceder a la información concurrentemente. La solución a todos estos problemas es almacenar la información en discos u otros dispositivos externos de almacenamiento masivo, en unidades llamadas ILFKHURV. Los procesos pueden leer, escribir o crear ficheros nuevos. La información almacenada en los ficheros es persistente, es decir, no se ve afectada por la creación o terminación de los procesos. Un fichero sólo desaparece cuando su propietario lo borra explícitamente. Los ficheros se manejan a través del sistema operativo. La parte del sistema operativo que se encarga de la gestión de ficheros recibe el nombre de VLVWHPDGH ILFKHURV. Para guardar y gestionar la información, el sistema de ficheros utiliza dos objetos importantes: los ficheros y los directorios. Como ya dijimos, los ficheros constituyen, desde el punto de vista del usuario, la unidad de almacenamiento de la información, mientras que los directorios contienen las listas de los ficheros junto con la información necesaria para su gestión: nombre, atributos y permisos de acceso, ubicación en el disco, etc. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV ,QWURGXFFLyQ 6LVWHPDGH)LFKHURV 7RGDODLQIRUPDFLyQTXHPDQHMDXQSURFHVRSXHGHHVWDUHQ PHPRULDSULQFLSDOSHURSXHGHTXH 31HFHVLWHPXFKRPiVHVSDFLR 31RGHEDVHUYROiWLO 31RVHSXHGDFRPSDUWLUODLQIRUPDFLyQHQ03 /DLQIRUPDFLyQGHEHVHULQGHSHQGLHQWH GHORVSURFHVRV 6HQHFHVLWDXQPHGLRGHDOPDFHQDPLHQWR GHODLQIRUPDFLyQWDOTXH +'HEHSRGHUDOPDFHQDUJUDQFDQWLGDGGHLQIRUPDFLyQ +/DLQIRUPDFLyQGHEHFRQWLQXDUH[LVWLHQGRGHVSXpVGHO ILQGHOSURFHVRTXHODXWLOL]D +0~OWLSOHVSURFHVRVGHEHQSRGHUDFFHGHU FRQFXUUHQWHPHQWHDODLQIRUPDFLyQ /DLQIRUPDFLyQVHDOPDFHQDHQGLVFRVXRWURVGLVSRVLWLYRV HQXQLGDGHVOODPDGDV),&+(526 (OVLVWHPDRSHUDWLYRVHHQFDUJDGHODJHVWLyQGHORV ILFKHURVPHGLDQWHHO6LVWHPDGH)LFKHURV )LFKHURV 6LVWHPDV2SHUDWLYRV, $SXQWHVGH62, 'LUHFWRULRV 6LVWHPDVGH)LFKHURV 6LVWHPDVGH)LFKHURV )LFKHURV Un fichero es una colección, con nombre, de información relacionada que se graba y mantiene, normalmente, en memoria secundaria. Desde el punto de vista del usuario, un fichero es la unidad lógica más pequeña de memoria secundaria, es decir, que no se pueden escribir datos en memoria secundaria a menos que sea dentro de un fichero. Normalmente, los ficheros contienen programas (tanto en formato fuente como objeto) y datos. Los ficheros de datos pueden ser de cualquier tipo: numérico, alfabético, alfanumérico o binario; y pueden tener un formato libre, como los ficheros de texto; o una estructura rígida en la que todos los registros componentes tienen un mismo patrón, como un fichero de empleados o de nóminas. En general, un fichero contiene simplemente información estructurada de la forma más conveniente en cada caso. Esta estructura puede ser una secuencia de bits, bytes, líneas o registros cuyo significado lo conocen los programas o personas que los crean y los utilizan. Un fichero también puede verse como un tipo abstracto de datos, es decir, un objeto con unos atributos y unas operaciones asociadas. Veamos en primer lugar estos atributos y operaciones, y posteriormente pasaremos a comentar la estructura interna que pueden tener los datos de los ficheros y los métodos para acceder a los registros que lo componen. $WULEXWRV Los atributos de un fichero varían de un sistema operativo a otro, pero típicamente suelen ser los siguientes: • 1RPEUH. Los ficheros son un mecanismo de abstracción que proporcionan el modo de almacenar información y poder recuperarla posteriormente, y que esconden los detalles de cómo y cuándo se almacena la información. La característica más importante de la abstracción es el modo en el que los objetos o ficheros se manejan y se nombran. Cuando un proceso crea un fichero, le asigna un nombre; cuando el proceso finaliza, el fichero continúa existiendo, por lo que otros procesos pueden acceder a su contenido mediante su nombre. Éste consta, normalmente, de una serie de caracteres alfanuméricos. Los caracteres especiales permitidos o la distinción entre mayúsculas o minúsculas depende de cada sistema operativo. • 7LSR. Si el sistema operativo es capaz de reconocer el tipo de un fichero, entonces puede operar con él de forma razonable. Por ejemplo, si se intenta imprimir un fichero objeto (en binario), normalmente produce un listado irreconocible, lo cual podría haberse prevenido si el sistema operativo detecta el tipo del fichero e impide la impresión al tiempo que avisa del error. Una técnica común para indicar el tipo de fichero consiste en incluir el identificador de tipo como parte del nombre. Para ello, el nombre se divide en dos partes: el nombre propiamente dicho y la extensión, normalmente separados por un punto. De esta forma, tanto el sistema operativo como el usuario pueden deducir el contenido del fichero simplemente a partir de la extensión del nombre. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV • 8ELFDFLyQ. Indica la dirección (cilindro o pista y sector) del comienzo del fichero en el disco. • 7DPDxR. Expresa el tamaño actual del fichero, expresado en bytes o bloques de datos. También puede indicar el máximo tamaño permitido para el archivo. • 3URWHFFLyQ. Indica los permisos de acceso para los usuarios del sistema. • )HFKD \ +RUD. Contiene el momento de creación, modificación y/o último acceso al fichero. 2SHUDFLRQHV En la gestión de ficheros hay ciertas operaciones que son básicas, así que el sistema operativo debe proporcionar operaciones para: crear, escribir, leer, posicionar, borrar, etc.; mientras que otras se pueden implementar a partir de las básicas, como por ejemplo: cambiar el nombre, copiar, añadir, ... • &UHDFLyQ. Antes de trabajar con un fichero hay que crearlo y para ello se requieren dos pasos principales: asignarle espacio en el disco y darle una entrada en el directorio correspondiente indicando, al menos, su nombre y ubicación. (Si el tamaño varía dinámicamente, no se asigna espacio inicialmente). • (VFULWXUD. Para escribir en un fichero hay que realizar una llamada al sistema indicando el nombre y la información que se desea escribir. El sistema operativo mantiene un puntero que indica la posición de lectura o escritura en el fichero, para que sucesivas operaciones de escritura, añadan los datos de forma consecutiva. El sistema operativo se encarga de encontrar la posición del fichero en el disco a partir del nombre. • /HFWXUD. El usuario debe indicar el nombre del fichero a leer y la dirección de un buffer de memoria local para depositar el contenido de la lectura solicitada. Al igual que en la operación de escritura, después de cada operación de lectura se actualiza la posición del puntero de L/E. • 3RVLFLRQDPLHQWR. Esta operación permite establecer el valor del puntero de L/E del fichero. • %RUUDGR. Para borrar un fichero simplemente hay que indicar su nombre. El sistema operativo busca el nombre en el directorio y libera el espacio que ocupa en el disco y la propia entrada en el directorio. La mayoría de estas operaciones requieren buscar en el directorio la entrada correspondiente al nombre del fichero, y puesto que éste se encuentra en disco, da lugar a que los tiempos de respuesta en las operaciones de L/E consuman un tiempo muy significativo. Para evitar esta búsqueda constante, la mayoría de los sistemas disponen de la operación DEULUILFKHUR. Esta operación DEULU ILFKHUR debe realizarse antes que cualquier otra instrucción sobre un fichero. Su cometido es copiar la entrada del directorio (en el disco) a la $SXQWHVGH62, 6LVWHPDVGH)LFKHURV )LFKHURV 6LVWHPDGH)LFKHURV 8Q)LFKHURHVXQDFROHFFLyQFRQQRPEUHGHLQIRUPDFLyQ UHODFLRQDGDJUDEDGDHQPHPRULDVHFXQGDULD 3DUDHOXVXDULRHVOD XQLGDGOyJLFDGLUHFFLRQDEOH PiVSHTXHxDGHPHPRULD VHFXQGDULD 3XHGHWHQHUFXDOTXLHUWLSR GHLQIRUPDFLyQ HVWUXFWXUDGDGHODPDQHUD PiVFRQYHQLHQWH (VXQWLSRDEVWUDFWRGHGDWRV $WULEXWRV 2SHUDFLRQHV 1RPEUH 7LSR 8ELFDFLyQ 7DPDxR 3URWHFFLyQ )HFKD\KRUD FUHDFLyQDFFHVR &UHDFLyQ (VFULWXUD /HFWXUD 3RVLFLRQDPLHQWR $xDGLU %RUUDU 5HQRPEUDU &RSLDU %~VTXHGDHQHO 'LUHFWRULR $%5,5 7DEODGH )LFKHURV$ELHUWRV GHOSURFHVR 7DEODGH )LFKHURV$ELHUWRV GHOVLVWHPD 3XQWHURGH3RVLFLyQ$FWXDO &RQWDGRUGH$SHUWXUDV 'LUHFFLyQHQHO'LVFR 6LVWHPDV2SHUDWLYRV, &(55$5 6LVWHPDVGH)LFKHURV $SXQWHVGH62, 6LVWHPDVGH)LFKHURV WDEODGHILFKHURVDELHUWRV que se mantiene en memoria principal. De esta manera, a partir de ese momento, cada operación con ese fichero ya no implica un acceso al disco para obtener la información del directorio, sino que se obtiene directamente de la tabla de ficheros abiertos, cuyo acceso es mucho más rápido. La operación de apertura del fichero devuelve un GHVFULSWRUGHILFKHUR, el cual se debe suministrar, en lugar del nombre, como un parámetro más en las llamadas a las posteriores operaciones con ese fichero. El descriptor suele ser el índice de acceso a la tabla de ficheros abiertos, con lo que la entrada del fichero se obtiene de forma inmediata. Cuando un fichero no se va a utilizar más de forma activa, debe procederse a FHUUDU HOILFKHUR, lo cual elimina o libera la entrada correspondiente de la tabla de ficheros abiertos. La implementación de las operaciones de abrir y cerrar ficheros se complica un poco en el caso de sistemas multiusuarios, en los que varios usuarios pueden realizar accesos concurrentes a un mismo fichero. En este caso, el sistema operativo mantiene dos niveles de tablas de ficheros abiertos. La WDEOD ORFDO GHO SURFHVR mantiene la información relativa al fichero según el uso del proceso, y suele consistir en el puntero de posición de lectura/escritura, más un puntero a una entrada de la WDEOD GHO VLVWHPD, la cual contiene información independiente de los procesos, como por ejemplo: la dirección del fichero en el disco, fechas de acceso, tamaño, etc. Una vez que se abre un fichero, las sucesivas aperturas por otros procesos simplemente añaden una entrada en la tabla local con el correspondiente puntero a su entrada en la tabla del sistema. Normalmente, la tabla de ficheros abiertos del sistema contiene un contador de aperturas en la entrada de cada fichero, indicando, en cada momento, el número de procesos que lo tienen abierto. Cada operación de cierre del fichero borra la entrada de la tabla local de ficheros abiertos y decrementa el contador de aperturas, de tal forma que cuando alcanza el valor cero se borra la entrada del la tabla del sistema, puesto que ya no lo utiliza ningún proceso. (VWUXFWXUDGHORV)LFKHURV Algunos sistemas operativos (de DEC e IBM) imponen la estructura interna de los ficheros dependiendo del tipo de estos, y utilizan un método de acceso distinto para cada una de las estructuras prefijadas que gestionan. No obstante, hoy día la estructura de los ficheros suele ser independiente del sistema operativo, concerniéndole únicamente al programa que lo crea o lo utiliza. Este es el caso de Unix o MS-DOS, que consideran cada fichero como una secuencia de bytes y no realizan ninguna interpretación de su contenido, por lo que tampoco ofrecen ningún soporte para el tratamiento de los distintos tipos de ficheros. Por esto, cada programa debe disponer de su propio código para interpretar la estructura de los ficheros que maneja. Sin embargo, todos los sistemas operativos deben soportar al menos la estructura de un tipo de ficheros: los programas ejecutables, es decir, deben saber que un $SXQWHVGH62, 6LVWHPDVGH)LFKHURV programa ejecutable está compuesto por una secuencia de registros de carga que contienen código máquina, instrucciones de reserva de espacio, constantes, etc. Esta estructura debe conocerla el cargador de programas para saber las necesidades de memoria del programa a cargar y la información a ubicar en memoria. También pueden contener lo que se conoce como UHFXUVRV y GDWRV. Para entender lo que son recursos y datos, pensemos, por ejemplo, en un moderno procesador de texto de tipo WYSIWYG (ZKDW \RX VHH LV ZKDW \RX JHW) en el que se dispone de menús y ayuda en el idioma español (aunque el procesador esté diseñado en otro país). El conjunto de texto de interfaz que tiene un programa, que es configurable para cada país, puede estar en registros especiales del fichero ejecutable, formando los GDWRV. También puede haber ciertos dibujos o imágenes que se muestran como parte de la interfaz a modo de ERWRQHV o ayudas para utilización con el ratón, formando lo que se conoce como UHFXUVRV. 0pWRGRVGH$FFHVR Los ficheros almacenan información, y cuando se utilizan se debe acceder a esta información para leerla y llevarla a la memoria principal. Hay varios métodos para acceder a la información de los archivos. Algunos sistemas operativos ofrecen un único método de acceso, mientras que otros, como los de IBM, soportan diferentes métodos. La elección del más apropiado en cada caso es una cuestión de diseño a tener muy en cuenta. A continuación veremos los dos principales métodos de acceso: acceso secuencial y acceso directo. No obstante, a partir del acceso directo pueden construirse algunas variantes, como son el DFFHVRLQGH[DGR y el VHFXHQFLDOLQGH[DGR. $FFHVR6HFXHQFLDO En este modo de acceso (el más simple y común) la información se procesa en orden secuencial, es decir, un registro detrás de otro. La mayor parte de las operaciones de acceso a un fichero son lecturas y escrituras. Una lectura consiste en leer la siguiente porción de texto y avanzar el puntero del fichero que indica el punto actual de lectura/escritura. De forma similar, una escritura añade información al final del fichero y avanza el puntero hasta el final de los datos recién escritos, o sea, hasta el nuevo fin del fichero. También se puede realizar una operación de “rebobinado” o retroceso hasta el principio del fichero, que pone el puntero de L/E apuntando al comienzo de éste. Algunos sistemas también disponen de operaciones para saltar registros hacia adelante y hacia atrás. El modo de acceso secuencial está basado en el modelo de la cinta magnética, pero puede utilizarse tanto en dispositivos de acceso secuencial (cintas) como en los de acceso directo (discos). $SXQWHVGH62, 6LVWHPDVGH)LFKHURV $FFHVR'LUHFWR Los ficheros de acceso directo están compuestos por registros de longitud fija, de tal forma que se permite que los programas puedan leer o escribir registros en cualquier posición sin ningún orden concreto. Un ejemplo clásico de ficheros que requieren este modo de acceso son los de bases de datos. Para poder realizar un acceso directo a un fichero, se requiere que el dispositivo que lo soporta sea de acceso directo, como el disco magnético, que permite acceder a cualquier punto de su superficie sin recorrer todos los anteriores. Un fichero de acceso directo se ve como una secuencia numerada de registros en la que se permite leer o escribir cualquiera de ellos, indicando simplemente su número de orden. Por esto, las operaciones de L/E deben especificar, como un parámetro más, el número del registro al que desean acceder, o bien realizar en primer lugar una operación de posicionamiento y a continuación una operación de lectura o escritura convencional (sin número de registro). El número de orden suele ser un número relativo al comienzo del fichero, y dado que los registros son de longitud fija y se conoce la dirección de comienzo del fichero, resulta inmediato el cálculo de la posición de cualquier registro. Algunos sistemas que disponen de ambos tipos de acceso (secuencial y directo) indican en el momento de creación del fichero el tipo de acceso permitido, de tal forma que si se declara como de acceso directo luego no se puede tratar secuencialmente; pero no obstante, con acceso directo siempre se puede simular fácilmente un acceso secuencial. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV )LFKHURV 6LVWHPDGH)LFKHURV (6758&785$'(/26),&+(526 1RUPDOPHQWHODHVWUXFWXUDLQWHUQDGHORVILFKHURVHV LQGHSHQGLHQWHGHO62\OHFRQFLHUQHVRODPHQWHDO SURJUDPDGHDSOLFDFLyQTXHORFUHD\ORXWLOL]D (O62LPSRQHODHVWUXFWXUDGHORVGLUHFWRULRV\ GHORVSURJUDPDVHMHFXWDEOHV 6HFXHQFLDGHUHJLVWURV GHFDUJD 5HFXUVRV\'DWRV 0e72'26'($&&(62 +$FFHVR6HFXHQFLDO 3 /DLQIRUPDFLyQGHOILFKHURVHSURFHVDHQRUGHQSRVLFLRQDO 8QUHJLVWURGHWUiVGHRWUR 3ULQFLSLR 3RVLFLyQ$FWXDO 5HERELQDU 3 6HXWLOL]DHQGLVSRVLWLYRV )LQ /HHU(VFULELU 6HFXHQFLDOHV 'H$FFHVR'LUHFWR +$FFHVR'LUHFWR 3 (OILFKHURHVWiIRUPDGRSRUUHJLVWURVGHORQJLWXGILMD\ ORVSURJUDPDVSXHGHQDFFHGHUUiSLGDPHQWHDFXDOTXLHU UHJLVWURVLQQLQJ~QRUGHQSDUWLFXODUHMEDVHVGHGDWRV 3 /DVRSHUDFLRQHVGH/(LQFOX\HQHOQGHUHJLVWUR RVHUHTXLHUHXQDLQVWUXFFLyQGHSRVLFLRQDPLHQWR 3 (QXQVLVWHPDGHDFFHVRGLUHFWRHVIiFLOVLPXODUHODFFHVR VHFXHQFLDO 6LVWHPDV2SHUDWLYRV, 6LVWHPDVGH)LFKHURV $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 'LUHFWRULRV Los sistemas de ficheros pueden ser muy extensos, por lo que se requiere alguna organización. Normalmente esta organización se realiza en dos niveles: particiones y directorios (Figura 5). En primer lugar, el sistema de ficheros se divide en SDUWLFLRQHV o volúmenes, de tal forma que cada disco contiene una o más particiones. En algunas ocasiones las particiones se utilizan para proporcionar áreas separadas de disco, tal que se tratan como dispositivos diferentes, mientras que otras veces se tienen particiones que ocupan más de un dispositivo, agrupando varios discos en una única estructura lógica, abstrayéndole al usuario de la representación física de la estructura de ficheros. Cada partición debe incluir información o atributos sobre los ficheros que contiene. Estos atributos se guardan en el GLUHFWRULR. Los atributos de un fichero son datos como el nombre, tamaño, tipo, dirección en el disco, etc. De hecho, el directorio es una tabla que asocia cada nombre de fichero con sus atributos. Las operaciones que se pueden realizar con un directorio están referidas a la gestión de ficheros (no al contenido de los ficheros). Así, tenemos operaciones como las siguientes: • &UHDU XQ ILFKHUR. Al crear un fichero se debe añadir una entrada en el directorio. • %RUUDUXQILFKHUR. Cuando ya no se necesitan los datos de un archivo, se debe borrar la entrada correspondiente del directorio. • &DPELDU HO QRPEUH GH XQ DUFKLYR. Si cambia el contenido o el uso de un fichero, se debe poder cambiar su nombre. • %XVFDU XQ ILFKHUR. Para realizar cualquiera de las acciones anteriores, la gestión de un directorio debe ofrecer un mecanismo de búsqueda rápida de la entrada del directorio correspondiente a cada fichero. • /LVWDUXQGLUHFWRULR. Se debe poder obtener la lista de todos los ficheros de un directorio, con sus atributos correspondientes. • 5HFRUUHU WRGR HO VLVWHPD GH ILFKHURV. A veces se realizan operaciones que abarcan a todos los ficheros de un directorio, como por ejemplo cuando se realiza una copia de seguridad de todo un sistema de ficheros. (VWUXFWXUDVGH'LUHFWRULRV Por lo que hemos visto hasta ahora, en un disco puede haber una o varias particiones, dentro de cada cual se encuentra una serie de ficheros, cuyos nombres y atributos están contenidos en un único directorio. Pero es muy posible que el número de los ficheros que comprende una partición sea muy elevado, y seguramente con contenidos muy heterogéneos, por lo que el trabajo con una lista $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 'LUHFWRULRV 6LVWHPDGH)LFKHURV /RVVLVWHPDVGHILFKHURVSXHGHQVHUPX\H[WHQVRV +D\TXHRUJDQL]DUORVILFKHURV 'LUHFWRULR 'LUHFWRULR 3DUWLFLyQ% 3DUWLFLyQ$ )LFKHURV )LFKHURV 'LUHFWRULR 3DUWLFLyQ& ',6&2 )LFKHURV ',6&2 (O'LUHFWRULRFRQWLHQHHOQRPEUHWLSRGLUHFFLyQWDPDxRHWF GHORVILFKHURVGHODSDUWLFLyQ MXHJRV FRUUHR OLEUR WUDEDMR DWULEXWRV DWULEXWRV DWULEXWRV DWULEXWRV MXHJRV FRUUHR OLEUR WUDEDMR DWULEXWRV DWULEXWRV DWULEXWRV DWULEXWRV 2SHUDFLRQHVFRQ'LUHFWRULRV %XVFDU)LFKHUR &UHDUXQ)LFKHUR %RUUDUXQ)LFKHUR /LVWDU'LUHFWRULR &DPELDU1RPEUHGH)LFKHUR 5HFRUUHUHO6LVWHPDGH)LFKHURV 6LVWHPDV2SHUDWLYRV, 6LVWHPDVGH)LFKHURV $SXQWHVGH62, 6LVWHPDVGH)LFKHURV muy grande de ficheros puede resultar engorroso. Por ello, puede ser conveniente organizar los ficheros en jerarquías, según su contenido o con cualquier otro criterio. Esto quiere decir que se necesitan estructuras de directorios dentro de cada partición. Veamos a continuación las más usuales. 'LUHFWRULRGHXQ1LYHO La estructura más simple es, desde luego, la que consta de un único directorio por partición. Ya que todos los ficheros están en el mismo directorio, resulta fácil de implementar y mantener. Los problemas con los directorios de un solo nivel aparecen cuando se comparte entre varios usuarios, pues ya que todos los ficheros están en el mismo directorio deben tener nombres distintos para poder distinguirlos, lo cual resulta problemático cuando dos usuarios quieren llamar WHVW a su fichero de pruebas. Incluso con un único usuario, a medida que aumenta el empieza a resultar difícil asignarles nombres únicos, pues, sistemas la longitud de los nombres está bastante limitada caracteres); otros sistemas, como Unix, permiten hasta caracteres. número de ficheros, además, en algunos (MS-DOS permite 11 un máximo de 255 'LUHFWRULRGH'RV1LYHOHV El principal problema que presentan los directorios de un solo nivel es la colisión de nombres de ficheros de distintos usuarios. La solución obvia es crear directorios separados para cada usuario. En la estructura de directorios de dos niveles, hay un Directorio Maestro y múltiples Directorios de Usuario (DU). Todos los DU’s tienen la misma estructura, pero cada uno de ellos contiene los nombres de fichero de un único usuario. Cuando un usuario se conecta al sistema, se busca en el Directorio Maestro, indexando en éste por el nombre o su número de cuenta, obteniendo una entrada que apunta a su DU. Cuando un usuario se refiere a un cierto fichero, solamente se busca en su directorio de usuario, por lo que diferentes usuarios pueden tener ficheros con el mismo nombre con tal de que todos los nombres dentro de cada directorio de usuario sean únicos. La estructura de dos niveles resuelve el conflicto de la colisión de nombres de distintos usuarios, pero todavía tiene algunos inconvenientes. Como hemos visto, con dos niveles de directorios se aísla a los usuarios entre sí, lo cual es una ventaja cuando los usuarios son completamente independientes, pero puede suponer ciertas trabas cuando un grupo de usuarios quieren cooperar en alguna tarea y necesitan acceder a ciertos ficheros con datos comunes. En algunos sistemas no se permite acceder a ficheros que no sean del propio directorio de usuario, otros sí lo toleran. En este último caso, para referenciar un directorio hay que indicar su $SXQWHVGH62, 6LVWHPDVGH)LFKHURV (VWUXFWXUDVGH'LUHFWRULRV 'LUHFWRULRV 'LUHFWRULR correo protocol pruebas bin libro proyecto )LFKHURV 'LUHFWRULRGHXQ1LYHO 'LUHFWRULR 0DHVWUR antonio 'LUHFWRULR datos bin libro test GH8VXDULRV paco pilar so1 carmen hex abc datos bin lec (VWUXFWXUDGH'LUHFWRULRVGH'RV1LYHOHV sistema datos prog p1 usr lib p2 v1 cont antonio datos bin libro cap1 cap2 cap3 paco pilar so1 hex abc p3 v2 notas trans (VWUXFWXUDGH'LUHFWRULRVHQÉUERO 6LVWHPDV2SHUDWLYRV, 6LVWHPDVGH)LFKHURV $SXQWHVGH62, 6LVWHPDVGH)LFKHURV FDPLQR completo desde la raíz del sistema, es decir, hay que hacer constar el nombre del usuario propietario del fichero seguido del nombre del fichero. La sintaxis para expresar el camino completo de acceso a un fichero varía con cada sistema. Un caso especial del problema de la compartimiento de ficheros se produce con los ficheros del sistema, o sea, aquellos programas que se proporcionan como parte del sistema operativo (cargadores, ensambladores, bibliotecas de programas, etc.), programas que normalmente se ofrecen en la forma de ficheros ejecutables. Cuando se teclea un comando, el intérprete de comandos del sistema operativo trata el nombre del comando como el nombre de un fichero, procediendo a continuación a cargarlo y ejecutarlo; pero claro, lo busca en el directorio del usuario actual, por lo que habría que copiar a cada usuario todos los ficheros del sistema para poder ejecutar los comandos. Parece obvio que la copia de todos los ficheros del sistema a todos los usuarios sería un enorme desperdicio de espacio. La solución a este problema es complicar ligeramente el mecanismo de búsqueda de ficheros. Se tiene un directorio de usuario especial que contiene los ficheros del sistema (por ejemplo, el usuario 0). Siempre que se escribe un comando en el teclado, el sistema operativo busca el nombre de fichero correspondiente en el directorio del usuario y si no lo encuentra procede a buscarlo en el directorio del usuario 0. A la secuencia de directorios en los que se realiza la búsqueda de un fichero se le conoce con el nombre de FDPLQR GH E~VTXHGD. Esta idea se puede ampliar, para que el camino de búsqueda contenga una lista de directorios a ser explorados en la búsqueda cuando se escribe un comando en el terminal. Este método lo utilizan sistemas como Unix y MS-DOS. 'LUHFWRULRVHQÉUERO Una vez que hemos representado los directorios de dos niveles como un árbol de dos niveles, la generalización natural es extender la estructura de directorios a un árbol de profundidad arbitraria. Esta generalización permite a los usuarios crear sus propios directorios, para organizar sus ficheros con cualquier estructura deseada. El árbol de directorios tiene un GLUHFWRULR UDt], el cual puede contener ficheros y subdirectorios. (Estrictamente hablando, “directorio” es el que se encuentra en la raíz del sistema de ficheros, mientras que los “subdirectorios” son los directorios de los demás niveles. No obstante, aquí nos referiremos a ambos de forma indistinta). Un directorio es simplemente otro fichero, pero con una estructura interna conocida por el sistema operativo, el cual lo trata de forma especial. Para saber si un fichero contiene datos o es un directorio, un campo de la correspondiente entrada del directorio que lo contiene indica el tipo de fichero (datos/directorio). $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 1RPEUHGH&DPLQR\'LUHFWRULRGH7UDEDMR En la estructura de árbol de directorios, cada fichero tiene un único nombre completo o QRPEUHGHFDPLQR. El nombre de camino suele estar formado por tres partes (Figura 7): - Partición - Directorio - Nombre de fichero Donde 'LUHFWRULR es la secuencia de directorios por los que hay que atravesar, desde la raíz, para llegar al subdirectorio que lo contiene. Como se puede ver en la Figura 7, los tres componentes del camino suelen formar una ristra de caracteres sin blancos y separados por algún carácter especial. El propio nombre del fichero figura como último componente del nombre completo. El inconveniente que se le puede presentar a un usuario es que el acceso a ciertos ficheros muy utilizados puede resultar muy engorroso, por tener que estar suministrando continuamente nombres de camino absolutos (desde la raíz). En un momento determinado, se dice que cada usuario está trabajando con los ficheros de su GLUHFWRULRGHWUDEDMR (en uno de los subdirectorios de su estructura). Esto quiere decir que si se hace referencia a un fichero únicamente por su nombre, el sistema busca el fichero en el directorio de trabajo actual, y no hay necesidad de estar utilizando el nombre completo (camino desde la raíz). Para esto, los sistemas operativos ofrecen comandos (cd en Unix y MS-DOS) para poder establecer el directorio de trabajo más apropiado a las necesidades de cada momento. Otra forma de referenciar ficheros es utilizando caminos relativos, es decir, el camino que hay desde el directorio de trabajo (no desde la raíz) hasta el fichero en cuestión. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 'LUHFWRULRV 6LVWHPDGH)LFKHURV ¢&yPR5HIHUHQFLDUXQ)LFKHURGHOÉUERO" ,QGLFDQGRVX&DPLQR$EVROXWR /bin/juegos/aviones/topgun c:\bin\juegos\aviones\topgun )LFKHUR 'LUHFWRULR 3DUWLFLyQ (ODFFHVRDEVROXWRDILFKHURVPX\XWLOL]DGRVHVWHGLRVR SRUHOFDPLQRGHE~VTXHGD 'LUHFWRULRGH7UDEDMR&DPLQR5HODWLYR cd /bin/juegos/aviones topgun doom . . . . . . cp topgun /copias/juegos 6LVWHPDV2SHUDWLYRV, $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 6LVWHPDVGH)LFKHURV 0HFDQLVPRVGH3URWHFFLyQ La información de los ficheros que se mantienen en memoria secundaria debe protegerse tanto de los daños físicos como de un acceso indebido. Para que un dispositivo de memoria secundaria tenga protegidos sus datos frente a daños físicos, debe tener ILDELOLGDG; mientras que para evitar un acceso indebido a los datos, debe ofrecer mecanismos de SURWHFFLyQ. Los ficheros pueden deteriorarse por problemas del hardware (como errores de lectura o escritura), fallos de alimentación, polvo, temperaturas extremas, etc., incluso pueden borrarse accidental o malintencionadamente. La fiabilidad del sistema ante estas situaciones normalmente viene dada mediante la duplicación de la información. Las salvaguardas pueden realizarse manualmente o automáticamente. En este último caso el sistema realiza las copias de seguridad a intervalos regulares de tiempo sin intervención alguna del operador. Aquí vamos a centrarnos, principalmente, en los mecanismos de protección que deben ofrecerse en entornos multiusuario. La necesidad de proteger los ficheros es consecuencia directa de la posibilidad de acceso a los mismos. En los sistemas que no permiten acceder a ficheros de otros usuarios, la protección no es necesaria. Este es un extremo, es decir, proporcionar protección completa prohibiendo el acceso de otros usuarios. El otro extremo es ofrecer un acceso libre sin ningún tipo de protección. Estos dos enfoques son demasiado radicales, obviamente lo que se requiere es un DFFHVRFRQWURODGR. Los mecanismos de protección controlan el acceso a los ficheros limitando los tipos de acceso que se pueden realizar. Algunas de las operaciones básicas que se pueden realizar con los ficheros son: • • • • /HHU de un fichero. (VFULELU o sobreescribir en un fichero. (MHFXWDU un fichero. O sea, cargarlo en memoria y ejecutarlo. /LVWDU el nombre y otros atributos de un fichero. Pueden encontrarse diversos sistemas de protección, donde cada uno tiene ventajas e inconvenientes, y se debe seleccionar uno dependiendo del número de usuarios y el tipo de aplicaciones. Veamos a continuación los dos más utilizados. /LVWDVGH$FFHVR\*UXSRV La solución más común al problema de la protección suele consistir en hacer que el permiso de acceso dependa de la identidad del usuario, puesto que distintos usuarios pueden necesitar distintos permisos de acceso a un mismo fichero. Así, una cosa que se puede hacer es asociar una OLVWD GH DFFHVR a cada fichero o directorio, indicando en ella el nombre de cada usuario autorizado con sus respectivos permisos de acceso (lectura, escritura, ejecución). $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 3URWHFFLyQ 6LVWHPDGH)LFKHURV /DLQIRUPDFLyQHQPHPRULDVHFXQGDULD VHGHEHSURWHJHUGHO 'DxR)tVLFR $FFHVR,QGHELGR )LDELOLGDG 3URWHFFLyQ %DFNXS 62/8&,21(6 /LEUH $FFHVR 3URKLELUHODFFHVR DRWURVXVXDULRV $FFHVR &RQWURODGR /RVPHFDQLVPRVGHSURWHFFLyQFRQWURODQ HODFFHVRDORVILFKHURV OLPLWDQGRORVWLSRVGHRSHUDFLRQHVTXHVHSXHGHQUHDOL]DU /((5 (-(&87$5 (6&5,%,5 %255$5 $f$',5 /,67$5$75,%8726 6LVWHPDV2SHUDWLYRV, $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 6LVWHPDVGH)LFKHURV Cuando un usuario solicita el acceso a un fichero, el sistema operativo comprueba la lista de acceso asociada al fichero. Si el usuario figura en la lista con el permiso oportuno, se le concede el acceso; en caso contrario, se le deniega. Este sistema de protección lo utiliza el sistema operativo VMS de Digital y Windows-NT. El principal problema de las listas de acceso se debe a su tamaño. Si se quiere permitir que todo el mundo pueda leer un fichero, se deben enumerar todos los usuarios con su correspondiente permiso, lo cual genera dos desafortunadas consecuencias: • La construcción de la lista puede ser una labor tediosa, sobre todo si no se conoce con antelación la relación de todos los usuarios del sistema. Además, cada vez que se da de alta un nuevo usuario, hay que actualizar las listas de acceso de todos los ficheros públicos del sistema. • Las entradas del directorio, tienen que ser de tamaño variable, con lo que su gestión resulta más complicada. Estos problemas pueden resolverse si se utiliza una versión condensada de la lista de acceso, es decir, clasificar a todos los usuarios del sistema en tres grupos: • 3URSLHWDULR: el usuario que creó el fichero. • *UXSR: el conjunto de usuarios que comparten el fichero y requieren permisos similares. • 8QLYHUVR: el resto de los usuarios del sistema A cada uno de estos conjuntos de usuarios se les puede definir permisos de lectura, escritura y ejecución, por lo que se requieren tan solo 9 bits para indicar los permisos de acceso de cada fichero para todos los usuarios del sistema. Este tipo de protección, utilizado en Unix, implica que se debe poder crear grupos de trabajo, lo cual es tarea del administrador del sistema. La asignación de los permisos a cada una de estas tres categorías de usuarios es responsabilidad del propietario del fichero. Windows NT también dispone de grupos de usuarios, para evitar el problema de las altas y actualizaciones de usuarios en grupos de trabajo. No debemos olvidar que los directorios también son ficheros, pero los permisos que se les puede asignar difieren de aquellos de los ficheros de datos. A un directorio se le puede poner permisos de acceso, entre otras cosas, para: • Poder crear y borrar directorios. • Poder listar su contenido (nombres de fichero y sus atributos). • Poder pasar a través de él para acceder a ficheros de subdirectorios suyos. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 3URWHFFLyQ 6LVWHPDGH)LFKHURV /RVSHUPLVRVGHDFFHVR GHSHQGHQGHODLGHQWLGDGGHOXVXDULR &DGDILFKHURRGLUHFWRULRSXHGHWHQHUDVRFLDGD XQDOLVWDGHDFFHVRFRQORVQRPEUHV\SHUPLVRV GHORVXVXDULRVDXWRUL]DGRV ,1&219(1,(17(6 &RQVWUXFFLyQWHGLRVDSDUD GDUSHUPLVRDWRGRVORV XVXDULRV (QWUDGDVGHOGLUHFWRULR GHOORQJLWXGYDULDEOH *HVWLyQGHOHVSDFLR PiVFRPSOLFDGD £62/8&,Ð1 &RQGHQVDUOD/LVWDGH$FFHVR HQ1LYHOHV + 3523,(7$5,2 *5832 5(672'(868$5,26 UZ[ UZ[ UZ[ Ã (OSURSLHWDULRGHOILFKHURHVWDEOHFHORVSHUPLVRV Ã (ODGPLQLVWUDGRUGHOVLVWHPDJHVWLRQDORVPLHPEURVGHOJUXSR /RVGLUHFWRULRVWDPELpQGHEHQWHQHUSHUPLVRVGHDFFHVR 3&UHDFLyQ\ERUUDGRGHGLUHFWRULRV 3/LVWDGRGHGLUHFWRULRVILFKHURV\VXVDWULEXWRV 6LVWHPDV2SHUDWLYRV, $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 6LVWHPDVGH)LFKHURV ,PSOHPHQWDFLyQGHO6LVWHPDGH)LFKHURV Habiendo visto en los apartados anteriores las características que ofrece el sistema de ficheros, pasaremos a abordar ciertas cuestiones relativas a su implementación sobre el dispositivo más común de memoria secundaria: el disco magnético. Trataremos diversos modos de asignación del espacio de disco y de su recuperación cuando se libere. También veremos mecanismos para llevar la cuenta del espacio de disco libre y ocupado. (VWUXFWXUDGHO6LVWHPDGH)LFKHURV En esencia, en cuanto a la gestión de ficheros, el sistema operativo debe encargarse de las siguientes funciones: 1. Traducción y representación de nombres de fichero a direcciones en el dispositivo de memoria secundaria. 2. Administración del espacio del disco. Encargándose tanto de la asignación/recuperación del espacio como de llevar la cuenta del espacio libre. 3. Organización de la estructura de directorios. Para llevar a cabo estas funciones, el sistema de ficheros está compuesto por una estructura de varios niveles, donde cada uno tiene su propio cometido y se apoya en el nivel inferior. Veamos algunas características de estos niveles que se indican en la Figura 10-inferior. • 'LVSRVLWLYRV. Los discos magnéticos se suelen utilizar como dispositivos de memoria secundaria sobre los que se mantienen los sistemas de ficheros. Para mejorar la eficiencia en el acceso, las transferencias de datos entre la memoria principal y el disco se realizan en unidades denominadas EORTXHV, donde cada uno de los cuales está compuesto de uno o más sectores. El tamaño de los sectores varía de 32 a 4096 bytes, y normalmente suele ser de 512 ó 1024 bytes. Los discos tienen ciertas características que los convierten en un medio adecuado para el almacenamiento de múltiples ficheros: − Puede contener una gran cantidad de datos permanentemente. − Se puede acceder directamente a cualquier bloque de información. − Es fácil modificar la información, es decir, resulta muy sencillo leer un bloque de disco, modificarlo y volver a escribirlo en la misma dirección que ocupaba. • &RQWURO de (6. Este nivel, muy dependiente del hardware, lo componen los GULYHUV de dispositivo y las rutinas de tratamiento de sus interrupciones. Un GULYHU de dispositivo es el programa que sabe traducir órdenes de alto nivel a los comandos correspondientes del hardware propio del disco utilizado, es decir, $SXQWHVGH62, 6LVWHPDVGH)LFKHURV comandos dirigidos a los registros o puertos del controlador del disco, para $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 6LVWHPDGH)LFKHURV ,PSOHPHQWDFLyQ +(O6LVWHPDGH)LFKHURVUHVLGHHQPHPRULDVHFXQGDULDSRUTXH 3 3XHGHFRQWHQHUJUDQFDQWLGDGGHGDWRVSHUPDQHQWHPHQWH 3 6HSXHGHDFFHGHUGLUHFWDPHQWHDFXDOTXLHUEORTXHGH LQIRUPDFLyQ 3 (VIiFLOPRGLILFDUODLQIRUPDFLyQ +(O6LVWHPD2SHUDWLYRGHEHSUHRFXSDUVHGH 3 7UDGXFFLyQ\UHSUHVHQWDFLyQGHQRPEUHV $VLJQDFLyQ5HFXSHUDFLyQ GHOHVSDFLRGHOGLVFR 3 *HVWLyQGHOHVSDFLR *HVWLyQGHOHVSDFLROLEUH 3 /DHVWUXFWXUDGHORVGLUHFWRULRV 3URJUDPDVGH$SOLFDFLyQ 6LVWHPD/yJLFRGH)LFKHURV 0yGXORGH2UJDQL]DFLyQGH)LFKHURV 6LVWHPD%iVLFRGH)LFKHURV &RQWUROGH(6 (VWUXFWXUDGHXQ 6LVWHPDGH)LFKHURV 6LVWHPDV2SHUDWLYRV, 'LVSRVLWLYRV 6LVWHPDVGH)LFKHURV $SXQWHVGH62, 6LVWHPDVGH)LFKHURV realizar posicionamiento de cabezas sobre pistas, búsqueda de sectores, formateo de pistas, comprobación de códigos de detección de errores, etc. • 6LVWHPD EiVLFR GH ILFKHURV. Aquí se realiza la traducción de las ordenes de lectura/escritura de bloques en comandos genéricos de acceso en los que se traducen los números de bloque a direcciones de disco del tipo “disco 1, cilindro 27, pista 12, sector 4”. • 0yGXOR GH RUJDQL]DFLyQ GH ILFKHURV. La función de este módulo es la traducción de bloques lógicos en bloques físicos, así como de la gestión del espacio libre del disco (métodos de asignación de espacio y administración del espacio libre). • 6LVWHPD OyJLFR GH ILFKHURV. Este nivel se encarga, por último, de la estructura de directorios, incluyendo los mecanismos de protección y seguridad vistos anteriormente. $VLJQDFLyQGHO(VSDFLR/LEUH En un disco magnético, por su gran capacidad, se almacenan una gran cantidad de ficheros. El principal problema que se presenta es cómo asignar espacio a estos ficheros de tal forma que el espacio del disco se utilice eficientemente (sin desperdiciarlo) y sin perjuicio de la velocidad de acceso a todos los datos componentes de cada fichero. Veamos a continuación los tres métodos de asignación de espacio más utilizado: asignación contigua, encadenada e indexada. $VLJQDFLyQ&RQWLJXD Con este método se requiere que cada fichero ocupe una serie de bloques contiguos en el disco. Ya que los bloques están adyacentes, no se requieren movimientos de la cabeza lectora para pasar de un bloque a otro, excepto en el cambio a la pista siguiente en cuyo caso el movimiento es mínimo. Esto quiere decir que el tiempo de posicionamiento no es significativo. Puesto que los bloques ocupados por un archivo son consecutivos, en las entradas del directorio solamente se necesita indicar el bloque de comienzo y la longitud del fichero (Figura 11). Con este sistema de asignación de espacio se soporta bien cualquier método de acceso. Para realizar un acceso secuencial, simplemente se requiere que el sistema operativo lleve la cuenta del último bloque accedido, para pasar al siguiente en la próxima operación de lectura/escritura. En cuanto al acceso directo, también es inmediato; ya que el tamaño de los bloques es fijo, solamente es necesaria una multiplicación para calcular la dirección de cualquier bloque de un fichero. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV $VLJQDFLyQGH(VSDFLR ,PSOHPHQWDFLyQGHO6) 0pWRGRVGH$VLJQDFLyQ GH(VSDFLR +D\TXHSUHRFXSDUVHGH 8WLOL]DFLyQ(IHFWLYD $FFHVR5iSLGR 3$VLJQDFLyQ&RQWLJXD 3/LVWD(QFDGHQDGD 3$VLJQDFLyQ,QGH[DGD +$VLJQDFLyQ&RQWLJXD &DGDILFKHURVHDOPDFHQDHQEORTXHV FRQWLJXRVGHGDWRVHQHOGLVFR 0 carta 1 2 4 5 6 8 9 10 12 13 16 20 17 18 libro 21 22 24 25 28 29 9(17$-$6 ),&+(52 3 fi 7 carta fi prog libro lista 11 prog 14 15 19 23 ',5 /21* 0 6 14 19 28 2 2 3 6 4 26 27 lista 30 31 )iFLOGHLPSOHPHQWDU %XHQDVSUHVWDFLRQHV ,1&219(1,(17(6 Ã $FFHVRGLUHFWR Ã $FFHVRVHFXHQFLDO ¢&XiOVHUiHOWDPDxRPi[LPRGHOILFKHUR" )UDJPHQWDFLyQ([WHUQD 5HTXLHUH&RPSDFWDFLyQ 6LVWHPDV2SHUDWLYRV, 6LVWHPDVGH)LFKHURV $SXQWHVGH62, 6LVWHPDVGH)LFKHURV Los problemas que presenta esta asignación contigua aparecen a la hora de encontrar espacio en el disco para un nuevo fichero. El problema de la asignación del espacio de disco es similar al de la gestión de memoria principal, en el que hay que satisfacer una petición de tamaño Q a partir de una lista de huecos libres. Así, HO SULPHUR TXH VLUYD o HO TXH PHMRU VH DGDSWH son los algoritmos más comúnmente utilizados. El inconveniente que presentan estos algoritmos es la fragmentación externa, pues a medida que se crean y borran ficheros el espacio libre del disco se va descomponiendo en huecos cada vez más pequeños (no aprovechables). La única solución a este problema es la compactación, pero por su alto coste en tiempo, raramente se suele realizar. Otro gran problema de esta asignación contigua es cómo determinar cuánto espacio se va a necesitar para un fichero, es decir, cómo saber en el momento de la creación de un fichero cuál va a ser su tamaño máximo. Cuando el fichero va a ser la copia de otro existente, no es ningún problema, pero cuando se trata de la creación del fichero de salida de una aplicación, puede resultar difícil hacer una estimación. Si se le asigna poco espacio, pronto nos podemos encontrar con que el fichero no se puede ampliar, en cuyo caso habría que volver a realizar el proceso de creación desde del principio, eligiendo un área inicial mayor; o mover o copiar el fichero a otra área del disco con un mayor tamaño, lo cual puede consumir un tiempo considerable. Incluso aunque se conozca por adelantado el tamaño final de un archivo, obsérvese que si el tamaño final es muy grande pero crece muy despacio, va a haber durante mucho tiempo un área de disco asignada a un fichero e inutilizada (hasta que el fichero crezca y la llene), o lo que es lo mismo, se va a producir fragmentación interna. /LVWD(QFDGHQDGD Como se puede ver en la Figura 12, con este método de asignación, cada fichero está compuesto por una lista de bloques encadenados, de tal forma que ahora cada bloque puede estar situado en cualquier lugar del disco. Por ejemplo, un fichero puede comenzar en el bloque número 7, continuar en el 24, después el 12, y por último terminar en el 5. Cada bloque debe contener un puntero al siguiente bloque de la lista. Obviamente, estos punteros no están accesibles al usuario, pero si cada bloque es de 512 bytes, por ejemplo, y cada puntero requiere 4 bytes, el área de datos de cada bloque queda reducida a 508 bytes. De esta manera, en las entradas del directorio solamente hay que indicar cuál es el primero y el último bloque de cada fichero. Con la asignación mediante lista encadenada, ya no se produce fragmentación externa, y cualquier bloque libre puede aprovecharse para satisfacer una petición de espacio. Nótese también que ahora no es necesario indicar el tamaño en la creación de un fichero; a medida que va creciendo se van añadiendo bloques a su lista encadenada y, desde luego, nunca se requiere una compactación. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV $VLJQDFLyQGH(VSDFLR ,PSOHPHQWDFLyQGHO6) +/LVWD(QFDGHQDGD (OILFKHURVHJXDUGDHQXQDOLVWD HQFDGHQDGDGHEORTXHVGHGLVFR 'LUHFWRULR ),&+(52 &20,(1=2 ),1 9 25 pipo 9(17$-$6 0 1 10 2 3 36LQSUREOHPDVGHFUHFLPLHQWR 4 5 7 31RKD\IUDJPHQWDFLyQH[WHUQD 8 9 16 10 25 11 12 6 ,1&219(1,(17(6 13 14 15 16 1 17 18 19 3,QHILFLHQWHSDUDDFFHVRGLUHFWR 20 21 22 23 3(VSDFLRSDUDORVSXQWHURV 24 25 -1 26 27 28 29 31 30 &OXVWHUV J0HQRVHVSDFLRSDUDSXQWHURV J0HMRUDHO7DFFHVR L0D\RUIUDJPHQWDFLyQ 30HQRV)LDEOH /D)$76ROXFLRQDHO3UREOHPDGHO$FFHVR'LUHFWR (QWUDGDGHO 'LUHFWRULR test nombre 217 comienzo J0HQRVPRYLPLHQWRVGHFDEH]DV QLO J/D)$7SXHGHFDUJDUVHHQ5$0 6LVWHPDV2SHUDWLYRV, ... 6LVWHPDVGH)LFKHURV $SXQWHVGH62, 6LVWHPDVGH)LFKHURV No obstante, también presenta ciertos inconvenientes. El principal es que solamente se puede utilizar eficientemente para acceso secuencial, pues para acceder al enésimo bloque de un fichero, es necesario empezar por el primer bloque e ir recorriéndolos uno por uno hasta llegar el bloque Q, y teniendo en cuenta que los bloques están dispersos en el espacio de direcciones, cada acceso a un bloque para leer el puntero al siguiente puede consumir un tiempo muy significativo. Además, aunque es un mal menor, se debe tener en cuenta que los punteros consumen espacio, así, en un bloque de 512 bytes, si el puntero ocupa 4 bytes, se requiere un 0,78% del disco dedicado a espacio para punteros. Este problema suele solventarse utilizando FOXVWHUV como unidades de asignación. Un FOXVWHU es un grupo de Q bloques, de tal forma que en cada FOXVWHU hay un puntero indicando la dirección del siguiente FOXVWHU de datos. Claramente, el espacio dedicado a punteros queda dividido por Q. Además de esto, se mejora el tiempo dedicado a posicionamiento, ya que en cada FOXVWHU los Q bloques están consecutivos; y también disminuye el tamaño de la lista de bloques libres, pues están agrupados de Q en Q. El problema de los FOXVWHUV es que generan fragmentación interna. No obstante, se suelen utilizar en la mayoría de los sistemas operativos. Un último problema que presenta la lista encadenada es la fiabilidad. Ya que los bloques de datos de un fichero están formados por una lista de punteros dispersos por el disco, la pérdida o daño de uno de ellos ocasiona también la pérdida de la información del fichero contenida en los restantes bloques de la lista. Hay algunas soluciones parciales, como la utilización de listas de doble enlace, pero también generan una mayor sobrecarga en el tiempo de gestión de la lista. Una importante variación de este método de asignación es la utilización de la 7DEOD GH $VLJQDFLyQ GH )LFKHURV (FAT). Este sistema, utilizado por MS-DOS y OS/2, consiste en tener una tabla al comienzo de cada partición del disco, la cual contiene una entrada por cada bloque del disco, y están ordenadas por número de bloque. Si nos fijamos en la parte inferior de la Figura 12 podemos ver que la entrada de la tabla correspondiente al primer bloque de un fichero contiene el número del siguiente bloque; la entrada de ese siguiente bloque contiene a su vez la dirección del siguiente, y así sucesivamente hasta llegar a una entrada cuyo contenido es QLO, indicando el fin de la lista encadenada. Los bloques no utilizados para ningún fichero aparecen con un 0 en la FAT, indicando que están libres. Un beneficio inmediato de la FAT es que mejora significativamente el tiempo de acceso directo, pues las búsquedas se realizan sobre la tabla, no sobre los bloques del disco. Para mejorar las prestaciones de este sistema, conviene tener cargada la FAT en memoria principal o caché, para evitar así acceder al disco en la gestión de la tabla. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV $VLJQDFLyQ,QGH[DGD La asignación indexada trata de solventar los problemas de la lista encadenada con el acceso directo. Para ello, lo que hace es reunir todos los punteros correspondientes a los bloques de un fichero en un único lugar: el EORTXH GH tQGLFHV (Figura 13). Cada fichero tiene su propio bloque de índices, que consiste en un vector ordenado de los números de bloque del fichero, de tal forma que la enésima entrada del vector contiene el número del enésimo bloque del fichero. Como se puede apreciar, este esquema es similar al de la paginación de memoria principal, en el que nos servíamos de una tabla de páginas. Cuando se crea el fichero, todas las entradas del bloque de índices contienen el valor QLO; a medida que el fichero crece y se van añadiendo bloques, se van anotando sus números sucesivamente en el bloque de índices. En el directorio simplemente hay que hacer constar la dirección del bloque de índices de cada fichero. Ahora sí se soporta bien el acceso directo sin sufrir fragmentación externa, pues al igual que en la lista encadenada, cualquier bloque libre del disco sirve para satisfacer una petición de espacio. El problema que presenta este sistema es el desperdicio de espacio, pues el tamaño del bloque de índices normalmente es mayor que el requerido para los punteros en la lista encadenada. Si consideramos el caso de un fichero pequeño (uno o dos bloques de datos), se requiere un bloque de índices entero aunque solamente se utilicen una o dos entradas. Como siempre, se plantea el dilema: si el bloque de índices es grande, se desaprovecha mucho espacio; si es pequeño, puede que no quepan todos los índices de un fichero extenso. Una buena solución a este problema es el utilizado por Unix (Figura 14). Unix mantiene unos cuantos punteros a bloques de datos en el I-nodo (punteros directos), pero en caso de que se llenen estos bloques, entonces utiliza otro puntero (puntero indirecto) que indica la dirección de un bloque de índices, el cual contiene punteros a bloques de datos. Si también se utilizan todos esos bloques, en el I-nodo se dispone de punteros con doble y triple indirección a bloques de datos. Al igual que con la FAT, para mejorar los tiempos de acceso, se pueden cargar los bloques de índices en memoria principal, aunque nunca se evita el tiempo de posicionamiento, ya que los bloques de datos se encuentran desperdigados por el disco. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV $VLJQDFLyQGH(VSDFLR ,PSOHPHQWDFLyQGHO6) +$VLJQDFLyQ,QGH[DGD 6ROXFLRQDHOSUREOHPDGHODFFHVRGLUHFWROOHYDQGRWRGRVORV tQGLFHVGHFDGDILFKHURDXQ%ORTXHGHÌQGLFHV 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ),&+(52 %/248('(Ì1',&(6 pipo 19 352%/(0$¢7DPDxRGHO%ORTXHGHÌQGLFHV" 6,(6*5$1'( 6,(63(48(f2 &RQILFKHURVSHTXHxRV VHGHVDSURYHFKDHO HVSDFLRGHOEORTXH 3XHGHTXHQRTXHSDQ WRGRVORVtQGLFHVGHXQ ILFKHURJUDQGH 62/8&,21(6 6LVWHPDV2SHUDWLYRV, $SXQWHVGH62, 3%ORTXHVGHtQGLFHVHQOD]DGRV 3,1RGRVGH8QL[ 6LVWHPDVGH)LFKHURV 6LVWHPDVGH)LFKHURV $VLJQDFLyQ,QGH[DGD $VLJQDFLyQGH(VSDFLR ,1RGRGH8QL[ 3HUPLVRV 'DWRV 3URSLHWDULR 'DWRV )HFKDV 'DWRV 7DPDxR 1EORTXHV %ORTXHV 'LUHFWRV 'DWRV 6LPSOHLQGLUHFWR 'REOHLQGLUHFWR 'DWRV 'DWRV 'DWRV 7ULSOHLQGLUHFWR ,1RGR 6LVWHPDV2SHUDWLYRV, 'DWRV 'DWRV 'DWRV 6LVWHPDVGH)LFKHURV *HVWLyQGHO(VSDFLR/LEUH Ya que el espacio del disco no es infinito, es necesario reutilizar el espacio de los ficheros borrados para ficheros nuevos. Si partimos de la base de que la unidad de asignación de espacio es el EORTXH, para saber en cada momento el espacio libre del disco, es necesario mantener una lista de los bloques libres, es decir aquellos que no están asignados a ningún fichero o directorio. Para crear un fichero se busca en la lista de bloque libres el número de bloques necesarios para satisfacer el espacio requerido para el nuevo fichero. Entonces, los bloques seleccionados se borran de la lista de bloques libres. Cuando se borra un fichero, los bloques que lo componen se añaden a la lista de bloques libres. Antes de ver dos mecanismos distintos para llevar la cuenta del espacio libre (mapa de bits y lista encadenada), se debe establecer cuál va a ser el tamaño del bloque. 7DPDxRGHO%ORTXH Dado el modo en el que están organizados los discos, parece que los candidatos a ser unidad de asignación son: el sector, la pista y el cilindro. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV ,PSOHPHQWDFLyQGHO6) *HVWLyQGHO(VSDFLR/LEUH /DXQLGDGGHHVSDFLRGHGLVFRDVLJQDEOHHVHOEORTXH ¢7DPDxRGHOEORTXH" *5$1'( L 3(48(f2 )UDJPHQWDFLyQ ,QWHUQD $FFHVR L ,QHILFLHQWH 7LHPSRGH/HFWXUDGHXQ%ORTXHGH.E\WHV 3LVWDGH E\WHV 7URWDFLyQ PV 7SRVLFLRQDPLHQWR PV .E\WHVV .[ $SURYHFKDPLHQWR GHOGLVFR Utilización del espacio de disco Vtransferencia . . 7DPDxRGHOEORTXH . . 3DUD)LFKHURVGH.E\WH 7DPDxR1RUPDO GHO%ORTXH 6LVWHPDV2SHUDWLYRV, $SXQWHVGH62, .E 6LVWHPDVGH)LFKHURV 6LVWHPDVGH)LFKHURV Volvemos a la eterna disyuntiva. Si elegimos al cilindro como bloque de asignación, entonces todos los ficheros, incluso los de un solo byte, tendrán al menos un cilindro asignado. Algunos estudios han mostrado que el tamaño medio de los ficheros de entornos Unix está alrededor de 1 Kbyte, por lo que la utilización de cilindros de 32 K como unidad de asignación significaría un desaprovechamiento de 31/32, o lo que es lo mismo, el 97% del espacio del disco. Por otra parte, la utilización de pequeñas unidades de asignación implica que cada fichero estará formado por muchos bloques. Ya que la lectura de cada bloque requiere un tiempo de posicionamiento y un retardo rotacional, la lectura de un fichero formado por muchos bloques pequeños será lenta. (Véase el ejemplo de la Figura 15, en el que se muestra el tiempo de lectura de un bloque de K bytes). Las curvas de la Figura 15-inferior nos muestran la velocidad de transferencia y el aprovechamiento del espacio del disco en función del tamaño del bloque, supuesto que el tamaño de los ficheros es de 1 Kbyte. La línea continua muestra la velocidad de transferencia; a medida que aumenta el tamaño del bloque, vemos que la escala de la parte izquierda indica una mayor velocidad de transferencia. Sin embargo, la línea de trazos pone de manifiesto cómo se empobrece el aprovechamiento del espacio del disco (en la escala de la parte derecha) a medida que aumenta el tamaño del bloque. Como siempre, la eficiencia en tiempo de respuesta y aprovechamiento del espacio están en conflicto. El compromiso suele llevar a un tamaño de bloque de 512 bytes a 2 Kbytes. Si se elige un bloque de 1 K para un disco con sectores de 512 bytes, entonces siempre se leerán 2 sectores consecutivos y se les tratará como una unidad indivisible. 0DSDGH%LWV Este método de administración de los bloques libres es similar al visto anteriormente en la gestión de la memoria principal. Consiste en tener un mapa de bits en el que cada bloque del disco está representado por un bit. Así, si el bloque está libre, su bit correspondiente tendrá un 1. Si, por el contrario, está ocupado, el bit tendrá un 0. La principal ventaja de este sistema es su simplicidad y eficiencia, pues normalmente resulta fácil encontrar el primer bloque libre, o los Q bloques libres consecutivos, especialmente ahora que los procesadores suelen disponer de instrucciones especiales para la búsqueda de series de bits en memoria. Esto implica que el mapa de bits debe copiarse a la memoria principal para realizar la gestión, y ocasionalmente copiarlo a disco para mantenerlo coherente. Mantener el mapa de bits en memoria principal no presenta ningún inconveniente en los discos pequeños, pero con discos de gran capacidad (del orden de gigabytes) el mapa de bits para bloques de 512 bytes puede llegar a ser considerable (más de 300 Kbytes). La técnica de los FOXVWHUV puede ayudar a disminuir el tamaño del mapa de bits. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV *HVWLyQGHO(VSDFLR/LEUH ,PSOHPHQWDFLyQGHO6) /RV%ORTXHVGH'LVFR 6HSLGHQ\VHDVLJQDQDXQILFKHUR $OERUUDUHOILFKHURVHGHYXHOYHQ +D\TXHOOHYDUODFXHQWDGHORVEORTXHVOLEUHV /LVWDGH%ORTXHV/LEUHV &DEHFHUDGHOLVWD GHOHVSDFLROLEUH 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 £ ,QHILFLHQWHSDUD UHFRUUHUODOLVWD %ORTXHGH ÌQGLFHV/LEUHV 2WUDSRVLELOLGDG0DSDGH%LWV %ORTXHV/LEUHV 0DSDGH%LWV 3(VVLPSOH\HILFLHQWH 36HGHEHPDQWHQHUHQ5$0 3£2MRFRQORVGLVFRVJUDQGHV 6LVWHPDV2SHUDWLYRV, $SXQWHVGH62, 6LVWHPDVGH)LFKHURV 6LVWHPDVGH)LFKHURV /LVWD(QFDGHQDGD Al igual que sucedía con la gestión de la memoria principal, otra opción para llevar la cuenta del espacio libre de disco consiste en mantener una lista de los bloques libres. En una dirección prefijada del disco se guarda el puntero al primer bloque libre; este primer bloque contiene un puntero al siguiente bloque libre; y así sucesivamente hasta llegar al último bloque libre, cuyo puntero tendrá un valor QLO (Ver Figura 16). El problema de esta solución es su ineficiencia, pues para ir recorriendo la lista hay que ir leyendo cada uno de los bloques, que por estar dispersos por el disco conlleva un tiempo substancial. Afortunadamente, no es habitual tener que recorrer la lista, ya que normalmente sólo se requiere un único bloque libre (el primero), pues la asignación de espacio libre a los ficheros se suele ir realizando poco a poco, a medida que el fichero va creciendo. Recordando en qué consistía la FAT, vemos que constaba de un mapa de bloques encadenados en el que las entradas correspondientes a bloques libres tenían un cero. Como se puede apreciar, utilizando este método de asignación de espacio no se requieren listas adicionales para llevar la cuenta de los bloques libres. ,PSOHPHQWDFLyQGHORV'LUHFWRULRV Un directorio es un fichero más, con la particularidad de que los datos que contiene son precisamente la información sobre los ficheros que contienen los datos de usuario. Esta información suele consistir, básicamente, en una lista de los ficheros de usuario junto con sus atributos correspondientes o la dirección del bloque de atributos. La estructura del directorio es conocida por el sistema operativo, que está encargado de la gestión del Sistema de Ficheros. Sobre la implementación del directorio, la principal consideración que hay que tener es sobre la organización y algoritmos de acceso a sus entradas. Hay dos algoritmos básicos para organizar y gestionar las entradas de un directorio: la lista lineal y la tabla KDVK. Veámoslos en detalle. • /LVWD/LQHDO. El método más simple para implementar un directorio consiste en utilizar una lista lineal de nombres de ficheros con sus correspondientes atributos y punteros a los bloques de datos. Aunque este método resulta muy fácil de implementar, con una lista lineal de entradas de directorio se requiere una búsqueda igualmente lineal para encontrar una entrada concreta, lo que consume un tiempo importante. Este tiempo puede resultar molesto, sobre todo si tenemos en cuenta que es necesario buscar en el directorio la entrada correspondiente de un fichero para crearlo, leer o escribir en él, borrarlo, etc. El tiempo de respuesta puede verse muy mejorado si se mantiene la imagen del directorio en una memoria caché. Una lista ordenada permitiría realizar búsquedas binarias, reduciendo el tiempo de búsqueda, sin embargo el mantenimiento de la lista $SXQWHVGH62, 6LVWHPDVGH)LFKHURV ordenada también genera una sobrecarga significativa a la hora de crear y borrar ficheros. Quizás un árbol binario pueda resultar más conveniente. • 7DEOD+DVK. Este sistema consiste en añadir una tabla o algoritmo KDVK a la lista lineal de las entradas del directorio. La función KDVK toma como entrada el nombre de un fichero y devuelve como valor de salida la dirección de su entrada en la lista lineal del directorio. Así, obviamente decrece en gran medida el tiempo de búsqueda. Como para cualquier algoritmo KDVK, se deben tomar medidas para el tratamiento de las FROLVLRQHV, es decir, las situaciones en las que para dos nombres distintos de ficheros se obtiene la misma dirección en el directorio. El problema que se puede presentar es que los algoritmos KDVK se realizan para un número fijo de entradas de directorio (por ejemplo, de 0 a 127), pero si el directorio se llena y se requiere una ampliación (hasta 255), habría que modificar el algoritmo KDVK para cambiar el rango de direcciones que genera. Esto obligaría a tener que rehacer todo el directorio utilizando la nueva función KDVK. $SXQWHVGH62, 6LVWHPDVGH)LFKHURV /RV'LUHFWRULRV ,PSOHPHQWDFLyQGHO6) ¢&yPR2UJDQL]DUODV(QWUDGDVGHO'LUHFWRULR" +/LVWD/LQHDO J (VVLPSOHGHLPSOHPHQWDU ¢&yPRERUUDUXQILFKHUR 1RPEUHHQEODQFR %LWGHHQWUDGDOLEUH L (VOHQWREXVFDQGRXQILFKHUR SDUDFUHDUOR SDUDDFFHGHU SDUDERUUDU £ %~VTXHGD /LQHDO 0HMRUDFRQOD %~VTXHGD%LQDULD PDQWHQLPLHQWRFRVWRVR +7DEOD+DVK /LVWDOLQHDO$OJRULWPRKDVK 1RPEUH )LFKHUR $OJRULWPR +DVK ÌQGLFHHQOD WDEODOLQHDO 3UREOHPDV L 7DPDxRILMR GHODWDEOD L&ROLVLRQHV 6LVHDPSOtD 1XHYDIXQFLyQKDVK 6LVWHPDV2SHUDWLYRV, £5HRUJDQL]DUWRGRHOGLUHFWRULR 6LVWHPDVGH)LFKHURV $SXQWHVGH62,