Tres funciones sirven para dar formato a discos, montarlos y desmontarlos. Para poder trabajar con un disco hay que montarlo con la función MontaSFB. Un disco montado ha de estar previamente formateado con FormateaSFB. El sistema se desmonta con DesmontaSFB.
Los servicios de este módulo sólo trabajarán con un único disco montado.
int FormateaSFB ( const char* nombre_fichero, const char* args[]);
Da formato a un disco virtual, especificado por nombre_fichero. El disco virtual ha de estar ya instalado con la función de bajo nivel FabricaDisco(). Los parámetros necesarios para el formateo vienen suministrados en args, que es un vector de cadenas de caracteres cuyo último elemento es un puntero nulo.
En la implementación de partida, se aceptan exactamente dos parámetros en args:
args[0]
|
Número
de ficheros (número de BFB)
|
args[1]
|
Tamaño
de bloque de datos (medido en bloques físicos)
|
En su nueva implementación, podrían modificar los parámetros pasados mediante args[].
Códigos de error
ERR_DISCO
Error
con el fichero UNIX
ERR_PARAMETRO
Parámetros
no válidos
ERR_FORMATO
Error
de formato del fichero
int MontaSFB ( const char* nombre_fichero, int nbloques_cache );
Esta función monta un sistema de ficheros ya formateado, que se encuentra en el fichero UNIX nombre_fichero. Para utilizar cualquier función que trabaje con ficheros básicos, hay que llamar previamente a esta función.
El parámetro nbloques_cache indica al nivel inferior el número de bloques deseado para la caché.
No se puede mantener más de un sistema de ficheros activo. Si se llama a MontaSFB mientras se tiene un SFB activo, se considera un error.
Códigos de error
ERR_NOEXISTE
Fichero
inexistente
ERR_FORMATO
Error
de formato del fichero
ERR_MONTADO
Ya
hay un SFB montado
int DesmontaSFB (void);
Esta función se invoca para desmontar el SFB actualmente montado.
Códigos de error
ERR_DISCO
Error
con operaciones de bajo nivel sobre el fichero UNIX
ERR_INACTIVO
No
hay un SFB montado
Información del sistema
WORD TamBloqueDatos(void);
Esta función devuelve el tamaño en bytes efectivo de un bloque de datos. Este número será menor o igual que el espacio ocupado en disco por un bloque de datos.
Si no hay un sistema montado, la función devolverá (WORD)-1 y la variable Error_SF adquirirá el valor ERR_INACTIVO.
DWORD EspacioLibre (void);
Esta función devuelve el espacio disponible para datos, medido en bytes.
Si no hay un sistema montado, la función devolverá (DWORD)-1 y la variable Error_SF adquirirá el valor ERR_INACTIVO.
WORD FicherosLibres (void);
Esta función devuelve la cantidad de ficheros disponibles. Si el sistema asigna BFB dinámicamente, se ha de garantizar que se devuelve un número mayor que cero siempre que haya espacio disponible para un nuevo fichero.
WORD LongitudFB ( IFB fichero );
int CambiaLongitudFB ( IFB fichero, WORD num_bloques );
int LeeBloqueFB ( IFB fichero, WORD num_bloque, void* bufer );
int EscribeBloqueFB ( IFB fichero, WORD num_bloque, const void* bufer );
Dos funciones, CreaFB() y DestruyeFB(), se encargan crear y destruir ficheros básicos.
IFB CreaFB ( const char* nombre, WORD num_bloques );
La función CreaFB ubica un bloque de fichero básico y le asigna num_bloques bloques de datos. El contenido de los bloques de datos es indefinido. El nombre del fichero es nombre.
Esta función devuelve un entero que corresponde con el fichero básico seleccionado. Este valor puede usarse en las operaciones de manipulación de ficheros básicos. En caso de que no pueda completar la operación, devuelve NINGUN_IFB. Si no se consiguen los num_bloques, no se crea el fichero.
Códigos de error
ERR_ESPACIO
|
No
hay BFB libres o bloques de datos suficientes
|
ERR_INACTIVO
|
No
hay un SFB montado
|
int DestruyeFB ( IFB fichero );
La función DestruyeFB desasigna todos los bloques de datos pertenecientes al fichero número fichero y libera el BFB correspondiente.
Códigos de error
ERR_RANGO
IFB
fuera de rango
ERR_OCUPADO
El
BFB ya estaba disponible
ERR_INACTIVO
No
hay un SFB montado
Control del tamaño del fichero
Existen tres funciones para: averiguar el tamaño de un fichero; añadir bloques al fichero; recortar el tamaño de un fichero. La unidad de datos del fichero básico es el bloque de datos: no se puede trabajar con bytes ni fracciones del tamaño efectivo de un bloque de datos.
WORD LongitudFB ( IFB fichero );
Devuelve el número de bloques de datos asignados al fichero.
Si hay alguna anomalía, se devuelve un ((unsigned)-1). Algunos valores de la variable Error_SF pueden ser:
ERR_RANGO
|
IFB
fuera de rango
|
ERR_LIBRE
|
IFB
no ocupado
|
ERR_INACTIVO
|
No
hay un SFB montado
|
int CambiaLongitudFB ( IFB fichero, WORD num_bloques );
Cambia el tamaño de fichero a num_bloques. Si el fichero aumenta de tamaño, los nuevos bloques se añaden por el final (apéndice). El contenido de los nuevos bloques es indefinido. El contenido de los bloques de datos ya asignados no ha de variar. Num_bloques puede valer cero.
Si el fichero encoge de tamaño, los bloques que se pierden son los del final. Los bloques perdidos deberían quedar disponibles para otros ficheros.
Si no hay espacio para satisfacer la petición, no se asigna ningún bloque y la función devuelve un -1.
En la implementación actual esta función no hace absolutamente nada.
Códigos de error
ERR_ESPACIO
Espacio
insuficiente: no se asignan los bloques pedidos
ERR_RANGO
IFB
fuera de rango
ERR_LIBRE
IFB
no ocupado
ERR_INACTIVO
No
hay un SFB montado
Lectura y escritura de bloques
int LeeBloqueFB ( IFB fichero, WORD num_bloque, void* bufer );
Esta función lee el bloque de datos num_bloque perteneciente a fichero y lo deposita en la zona de memoria apuntada por bufer.
El llamador de esta función es responsable de que bufer apunte a un lugar correcto y que tenga espacio suficiente para albergar un bloque de datos, según lo que retorne TamBloqueDatos()
Códigos de error
ERR_NOEXISTE
num_bloque
está fuera del rango del fichero
ERR_RANGO
IFB
fuera de rango
ERR_LIBRE
IFB
no ocupado
ERR_INACTIVO
No
hay un SFB montado
int EscribeBloqueFB ( IFB fichero, WORD num_bloque, const void* bufer );
La función EscribeBloqueFB copia la zona de memoria apuntada por bufer en el bloque de datos num_bloque perteneciente a fichero. Se copian exactamente los bytes que ocupa un bloque de datos del S.F.B. actualmente montado, según lo que retorne TamBloqueDatos()
El llamador de esta función es responsable de que bufer apunte a un lugar correcto en la memoria.
Códigos de error
ERR_NOEXISTE
num_bloque
está fuera del rango del fichero
ERR_RANGO
IFB
fuera de rango
ERR_LIBRE
IFB
no ocupado
ERR_INACTIVO
No
hay un SFB montado
Gestión de nombres y directorios
IFB BuscaFB ( const char* nombre );
La función BuscaFB trata de localizar el IFB correspondiente al fichero cuyo nombre sea nombre. Si lo encuentra, devuelve el IFB asociado. Si no lo encuentra, devuelve la constante NINGUN_IFB, definida en tipos.h
Códigos de error
ERR_PARAMETRO
nombre
es una cadena no válida (p.ej. vacía)
ERR_INACTIVO
No
hay un SFB montado
IFB EntradaDir ( int numero_de_orden, char* nombre );
Esta función busca dentro del directorio la entrada válida que haga el número numero_de_orden. Si se llega a tal entrada, se deposita en nombre el nombre del fichero encontrado, y se retorna el IFB correspondiente. Si no se llega a tal entrada, nombre se convierte en una cadena nula y se devuelve NINGUN_IFB.
El llamador de EntradaDir es responsable de que nombre apunte a una zona de memoria donde pueda caber un nombre de fichero.
En el fichero bfb.h se define una interfaz interna para trabajar con los BFB. La estructura inicial del BFB tiene estos campos:
BYTE estado
|
libre
u ocupado
|
char
nombre [LONG_NOMBRE]
|
nombre
del fichero
|
WORD
id
|
IFB
|
DWORD
bloque
|
bloque
de datos inicial
|
Las funciones elementales que se han implementado para tratar con BFB son las siguientes:
void BFB_empieza_sesion (void);
void BFB_termina_sesion (void);
Estas dos funciones son necesarias para inicializar un búfer interno sobre el que se cargan y descargan bloques físicos, para leer o escribir los BFB.
void BFB_recoge ( BFB* bfb, IFB fichero );
void BFB_guarda ( const BFB* bfb, IFB fichero );
Este par de funciones sirve, respectivamente, para leer un BFB del disco o para guardar en el disco virtual una estructura BFB. El parámetro fichero indica cuál es BFB dentro del disco sobre el que se realiza la transferencia.
Estas dos funciones se emplean con profusión a lo largo del código de sfbasico.c
void BFB_construye ( BFB* bfb, int numero );
void BFB_cambia_longitud ( BFB* bfb, WORD num_bloques );
La función BFB_construye da unos valores iniciales a una estructura BFB. El parámetro numero sirve para darle valor al campo id de la estructura. Esta función es invocada durante el formateo del sistema de ficheros.
La función BFB_cambia_longitud sirve como soporte a la función de cambio de tamaño de un BFB. Actualmente no está implementada, ya que no se trabaja con ficheros de tamaño variable.
int LeeSuperbloque ( struct DescriptorSFB* desc );
int EscribeSuperbloque ( const struct DescriptorSFB* desc );
Estas dos funciones sirven de interfaz para leer y escribir desde/hacia el disco los parámetros de configuración del SFB montado. Ambas funciones llevan como parámetro un puntero a una estructura DescriptorSFB, según se define en descr.h. La función LeeSuperbloque se emplea en el montaje de un SFB, para recoger los parámetros del SFB. La función EscribeSuperbloque()se invoca cada vez que se altera la información de estado del SFB. Por ejemplo, cuando se crea un fichero.
int FabricaDisco ( const char* nombre_fichero,
WORD tam_bloque, DWORD num_bloques );
Esta función crea un fichero de nombre nombre_fichero utilizable como disco virtual. El disco contendrá num_bloques bloques físicos, cada uno con un tamaño en bytes igual a tam_bloque. La función se encarga de depositar los valores adecuados en el bloque cero del disco virtual.
Códigos de error
ERR_DISCO
|
Error
al intentar crear el fichero UNIX
|
ERR_RANGO
|
Parámetros
fuera de rango
|
ERR_ESPACIO
|
No
había espacio suficiente en disco
|
int MontaDisco ( const char* nombre_fichero, int nbloques_cache );
Esta función monta el fichero nombre_fichero para su uso como Sistema de Bloques Físicos. nombre_fichero debió haber sido creado previamente con la función FabricaDisco(). Sólo puede haber un disco montado en cada momento.
El parámetro nbloques_cache indica cuántos bloques de desea que contenga la caché de bloques físicos. El sistema de caché intentará habilitar una caché de ese tamaño; si no es capaz se creará una caché con el máximo tamaño que sea posible. Para esta práctica, recomendamos poner un cero en este parámetro.
Códigos de error
ERR_NOEXISTE
El
fichero UNIX no existe
ERR_DISCO
Error
con el fichero UNIX
ERR_MONTADO
Ya
hay un disco montado
ERR_FORMATO
El
fichero no tiene formato de disco virtual
int DesmontaDisco (void);
Desmonta el disco actualmente en uso.
Códigos de error
ERR_DISCO
|
Error
con el fichero UNIX
|
ERR_INACTIVO
|
No
hay disco virtual montado
|
int LeeDatosDisco ( WORD* tam_bloque, DWORD* num_bloques );
Esta función lee el tamaño de bloque y el número de bloques del disco actualmente montado, depositándolos en *tam_bloque y *num_bloques, respectivamente.
Códigos de error
ERR_FORMATO
|
Error
de formato de disco virtual
|
ERR_INACTIVO
|
No
hay disco virtual montado
|
int LeeBloqueFisico ( DWORD nbloque, void* bufer );
int EscribeBloqueFisico ( DWORD nbloque, const void* bufer );
Estas dos funciones se encargan, respectivamente, de leer y de escribir bloques físicos pertenecientes al disco virtual montado actualmente. El número de bloque físico para transferir viene dado por nbloque. La transferencia se efectúa sobre la zona de memoria apuntada por bufer. El llamador es responsable de que bufer apunte a una zona con espacio suficiente para un bloque físico (mediante LeeDatosDisco() se puede obtener el tamaño de un bloque físico).
Códigos de error
ERR_INACTIVO
|
No
hay ningún SBF montado
|
ERR_RANGO
|
Bloque
físico fuera de rango
|