Apellidos: Nombre: Sistemas Operativos Ingenierı́a Informática de Sistemas Examen Junio 2008 1. Dispositivo de bloques con buffer [2 puntos] Implementar las funciones int buffer block read(struct buffer dev ∗dev, void ∗buffer, int block number) y int buffer block write(struct buffer dev ∗dev, void ∗buffer, int block number), usando las funciones int block read(struct device *dev, void *buffer, int block number) y int block write(struct device *dev, void *buffer, int block number). Las funciones se diferencian de block read/write() en que guardan un buffer indexado por la función int hash(int block number) de tamaño NUM BUFFERS con las últimos bloques usados. Existe un campo int dirty, para indicar si el contenido es distinto del buffer en disco. La estructura buffer dev esta protegida por el mutex lock, cada uno de los buffers individuales esta protegido por lock buffer[i]. Hay que minimizar el tiempo usado con cada uno de los locks adquiridos. La lecturas/escrituras (tanto de disco como a memoria hay que realizarlas con el lock buffer correspondiente adquirido. #define BLOCK_SIZE ... #define NUM_BUFFERS ... struct buffer { char block[BLOCK_SIZE]; }; struct buffer_dev { mutex lock; struct device *dev; int block_num[NUM_BUFFERS]; int dirty[NUM_BUFFERS]; mutex lock_buffer[NUM_BUFFERS]; struct buffer buf[NUM_BUFFERS]; } 2. Algoritmo de segunda oportunidad [2 puntos] Implemente en C el algorı́mo de segunda oportunidad teniendo en cuenta: Dada la siguiente secuencia de acceso a páginas: P4, P3w, P1, P5, P4, P5w, P2 (donde los accessos marcados con una w son de escritura y el resto de lectura), simular que páginas estarı́an en memoria considerando: hay 4 frames. existe un bit de accesso (A) y un bit de modificación (M). No existe refresco periodico del bit de acceso, solo se modifica según la tabla. La tabla de modificaciones de los bits es: A viejo M viejo A nuevo M nuevo 0 0 1 w 0 1 0 0 1 0 0 1 1 0 El estado inicial de las frames es: 0 1 aclaración se usa esta entrada para la nueva página. Se inicia la escritura de la página. La escritura termina dos accesos más tarde Se marca la página como no accedido. Se marca la página como no accedida. Frame 0 1 2 3 Página P0 P1 P3 P4 Siguiente * A 1 0 0 1 M 0 1 0 1 3. Función namei dir() de un sistema de ficheros [2.5 puntos] Defina la función int namei dir(struct file system *fs, int parent, char *path component), para el sistema de ficheros mfs. Dado un componente del nombre del fichero, y el numero de inodo de su directorio padre, busca el inodo correspondiente a ese fichero. La función: comprueba que parent es un directorio, en caso contrario devuelve -ENOTDIR. comprueba que el componente no sea NULL, en caso contrario devuelve -EINVAL. si existe el componente, devuelve su número de inodo, en caso contrario devuelve -ENOENT. 4. Función namei() en un sistema de ficheros con subdirectorios [2.5 puntos] Defina la función int namei(struct file system *fs, char *pathname), que a partir de un nombre de fichero con path absoluto, devuelve el número de inodo que contiene ese fichero, en caso de que no exista la entrada, devuelve -ENOENT. Para definir esta función, usese la función definida en el ejercicio anterior. puede usarse la función char *get component(char *pathname, int level), que dado un path y un indice, devuelve un puntero al componente level del pathname, o NULL, en caso de que la cadena no contenga ese componente. Para los dos ejercicios anteriores pueden suponerse definidos las siguientes funciones y estructuras: struct super_block { int block_size; int num_inodes; int num_bitmap; int num_data_blocks; int root_inode; }; struct extent { int start; int size; } struct inode { int size; struct extent e; }; #define ENTRY_SIZE ... struct entry { char name[ENTRY_SIZE]; short inode; }; struct file { int num; int pos; struct inode ino; }; #define NUM_FILES ... struct file_system { struct device *dev; struct super_block sb; struct inode root; struct file file[NUM_FILES]; ... } *fs = NULL; int inode_read(struct device *dev, struct inode *ino, int num); int inode_write(struct device *dev, struct inode *ino, int num); int data_read(struct device *dev, void *block, int num); int data_write(struct device *dev, void *block, int num); Asumase que la variable fs esta inicializada correctamente.