Apellidos: Nombre: Sistemas Operativos Ingenierı́a Informática de Sistemas Examen Junio 2009 1. Dispositivo de bloques con buffer [3 puntos] Implementar las funciones buffer block read() y buffer block write(). 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 NUMBUFFERS con los últimos bloques usados. Existe un campo dirty, para indicar si el contenido es distinto del buffer en disco. Cada bloque en la estructura buffer dev esta protegida por el mutex lock, cada uno de los buffers individuales esta protegido por un mutex. Ese mutex protege actualizaciones concurrentes de estos buffers. Las lecturas/escrituras (tanto de disco como a memoria) hay que realizarlas con el lock buffer correspondiente adquirido. #define BLOCKSIZE . . . #define NUMBUFFERS . . . struct buffer { char block[BLOCKSIZE] ; int block number; int dirty ; mutex m; }; struct buffer dev { struct device ∗dev; struct buffer buf[NUMBUFFERS] ; }; int block read(struct device ∗dev, void ∗buffer , int block number)} int block write(struct device ∗dev, void ∗buffer , int block number)} void mutex lock(mutex m); void mutex unlock(mutex m); 2. Algoritmo de segunda oportunidad [2 puntos] Implemente en C el algoritmo de segunda oportunidad: int second chance(struct frames *frames) que dado un array de frames, busca la primera que puede usarse para una página nueva. La función devolvera cual es el frame sobre el que se puede usar para la página nueva. Tengase en cuenta: Si el mutex está ocupado, pasar a la siguiente página. El mutex se bloquea antes de comenzar una escritura de una página. La función page write devuelve el control despues de iniciar la escritura. Cuando la escritura termina, el controlador desbloquea el lock (es decir, no tenemos que hacer nada en una página que tiene el mutex bloqueado) 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 0 1 1 0 1 #define NUMFRAMES struct frame { int num page; bool access ; bool modify; mutex busy; }; aclaración se usa esta entrada para la nueva página. Se inicia la escritura de la página. Se marca la página como no accedido. Se marca la página como no accedida. /∗ Num of page stored here ∗/ /∗ Acces bit ∗/ /∗ Modify bit ∗/ /∗ La pagina se esta ocupada ∗/ struct frames { int next; struct frame[NUMFRAMES] ; }; int page write(int page, int frame); int mutex trylock(mutex ∗m); /∗ 1 −> ocupado, 0 −> libre ∗/ 3. mfs readdir() [2 puntos] Defina la función struct dirent *mfs readdir(MFS DIR *dir). La función tiene que contemplar los siguientes casos: Funcionar con la función mfs opendir() que se da como ejemplo. Funcionar correctamente en el caso de que se hayan borrado ficheros. struct mfs dir { int siguiente ; struct disk inode d; struct dirent e; }; MFSDIR ∗mfs opendir(const char ∗name) { int inodo = namei(fs , &fs−>root , name); if (inodo == −1) return NULLT; MFSDIR ∗dir = malloc(sizeof(MFSDIR)); inode read(fs , &dir−>d, inodo); dir−>siguiente =0; return dir ; } int walk directory(struct file system ∗fs , struct disk inode ∗d, int (∗update)(struct entry ∗e fs , struct entry ∗e arg) , struct entry ∗arg) 4. file read/write() en mfs[3 puntos] Implemente las función int file read/write(struct file system *fs, struct disk inode *ino, void *buf, int block) con extents (solo existen los extents apuntados por el inodo). Tiene que detectar que el numbero de bloque que se pasa es correcto. Pueden usarse las siguientes funciones: siguientes funciones y definiciones: #define NUMEXTENTS . . . struct extent { int start ; /∗ extent start block ∗/ int size ; /∗ extent size in blocks ∗/ }; struct disk inode { int block size ; /∗ file size in blocks ∗/ struct extent e[NUMEXTENTS] ; }; int data read(struct file system ∗fs , void ∗buffer , int block num); int add one block(struct file system ∗fs , struct indoe ∗ino); /∗ Add one block to the end of one inode. 0 −> error, 1−> success ∗/