/************************************************************************/ /* */ /* DESCR.C */ /* ======= */ /* */ /* Implementación de un sistema de ficheros muy simple, */ /* para realizar prácticas de diseño de sistemas operativos. */ /* */ /* Este módulo se encarga de las transferencias del superbloque */ /* al/del disco. En el superbloque se almacena la información */ /* descriptora del sistema de ficheros: tamaños de bloques y */ /* áreas, orígenes de áreas de BFBs y datos, etc. */ /* */ /************************************************************************/ #include "descr.h" #include "sffisico.h" #include "errores.h" #include "bfb.h" /* Constante TAM_BFB */ #include #include #include /* Descriptor del sistema de ficheros */ struct DescriptorSFB DESC = { 0,0,0,0,0,0,0,0,0,0,0,0 }; /* Datos del SFB guardados en disco */ /* Estructura que se almacena en el disco */ struct Descripcion_en_disco { WORD tam_bloque_datos; WORD num_BFB; DWORD org_BFB; DWORD org_datos; DWORD primer_bloque_libre; DWORD ultimo_bloque_datos; char magicoSFB[8]; }; #define MAGICO_SFB "CORRECTO" /* Función LeeSuperbloque (&DESC) */ /* */ /* Lee desde el disco la descripción del sistema */ /* de ficheros y la guarda en DESC. Algunos campos */ /* se calculan a partir de la información en disco. */ int LeeSuperbloque ( struct DescriptorSFB* DESC ) { struct Descripcion_en_disco* desc; char* bufer; WORD tam_bloque; DWORD num_bloques; /* Lee datos del disco (tam. de bloque y número de bloques) */ LeeDatosDisco( &tam_bloque, &num_bloques ); assert (sizeof(struct Descripcion_en_disco) <= tam_bloque ); bufer = malloc(tam_bloque); assert (bufer!=0); DESC->tam_bloque_fisico = tam_bloque; DESC->num_bloques_fisicos = num_bloques; /* Lee el superbloque */ LeeBloqueFisico(0,bufer); if (HAY_ERROR) return -1; /* Recoge del disco los campos propios del SFB */ desc = (struct Descripcion_en_disco*)(bufer+TAM_SUPERBLOQUE); if ( strncmp(desc->magicoSFB,MAGICO_SFB,8) ) { Error_SF=ERR_FORMATO; free(bufer); return -1; } DESC->tam_bloque_datos = desc->tam_bloque_datos; DESC->num_BFB = desc->num_BFB; DESC->org_BFB = desc->org_BFB; DESC->org_datos = desc->org_datos; DESC->primer_bloque_libre = desc->primer_bloque_libre; DESC->ultimo_bloque_datos = desc->ultimo_bloque_datos; /* Calcula los campos no presentes en disco */ DESC->BFBs_por_BF = DESC->tam_bloque_fisico / TAM_BFB; DESC->nbloques_BFB = DESC->num_BFB / DESC->BFBs_por_BF; DESC->nbloques_datos = (DESC->num_bloques_fisicos-DESC->org_datos) / DESC->tam_bloque_datos; /* Todo esto deberia ser cierto */ assert(DESC->tam_bloque_fisico>=TAM_BFB); assert(DESC->num_BFB>0); assert(DESC->org_BFB==1); assert(DESC->org_datos>DESC->org_BFB); assert(DESC->primer_bloque_libreultimo_bloque_datos); assert(DESC->nbloques_datos>0); /* Retorna */ free(bufer); return 0; } /* LeeSuperbloque() */ /* Función EscribeSuperbloque (&DESC) */ /* */ /* Escribe en el disco la descripción del sistema */ /* de ficheros almacenada en DESC. Algunos campos */ /* no se guardan, ya que se pueden reconstruir. */ int EscribeSuperbloque ( const struct DescriptorSFB* DESC ) { struct Descripcion_en_disco* desc; char* bufer; assert (sizeof(struct Descripcion_en_disco) <= DESC->tam_bloque_fisico); bufer = malloc(DESC->tam_bloque_fisico); assert (bufer!=0); /* Lee el superbloque */ LeeBloqueFisico(0,bufer); /* Rellena los campos del SFB */ desc = (struct Descripcion_en_disco*)(bufer+TAM_SUPERBLOQUE); strncpy(desc->magicoSFB,MAGICO_SFB,8); desc->tam_bloque_datos = DESC->tam_bloque_datos; desc->num_BFB = DESC->num_BFB; desc->org_BFB = DESC->org_BFB; desc->org_datos = DESC->org_datos; desc->primer_bloque_libre = DESC->primer_bloque_libre; desc->ultimo_bloque_datos = DESC->ultimo_bloque_datos; /* Guarda el bloque modificado en disco */ EscribeBloqueFisico(0,bufer); free(bufer); return 0; } /* EscribeSuperbloque() */