Nello sviluppo del software le funzioni sono state divise in modo da avere alcune funzioni di base che facevano i compiti più comuni e una serie di funzioni di più "alto livello" che invece assolvono all'esecuzione dei vari comandi (cp, ln, mkdir, ecc).
Le funzioni di base create sono state quindi:
- int create_vfs(int num_files): si occupa di creare il file al cui interno sarà contenuto l'intero VFS, riceve quindi come parametro il numero di files (minimo 3) e prosegue inserendo nel file FLI, FLB e quindi creando i vari i-nodes vuoti collegati tra loro e la lista dei blocchi.
Inoltre predispone già un i-node e un blocco per la root del VFS, cosicché dopo la sua esecuzione le altre funzioni trovano il VFS inizializzato.
Questa funzione viene lanciata dal server prima di andare in background e quindi eventuali errori vengono segnalati direttamente tramite perror.
- int allocate_block(I_TYPE itype, I_NODE *inode): si occupa di collegare il primo blocco libero al primo i-node libero, per poter inserire un nuovo elemento nel VFS. Nello specifico richiede come parametro il tipo di elemento da allocare (regular file o directory) e restituisce, tramite passaggio per indirizzo, l'i-node creato e tramite la return il suo offset.
Per fare tutto questo sfrutta la gestione a lista degli i-node e dei blocchi: legge quindi il contenuto di FLI e FLB e collega l'i-node con il blocco, naturalmente poi aggiorna FLI e FLB per puntare ai successivi elementi della lista.
Questa funzione si occupa inoltre di inizializzare i campi type e timedate dell'i-node, in questo modo anche l'orario di creazione è già pronto.
- int deallocate_block(I_NODE *inode, unsigned int i_node_offset): si occupa di scollegare un blocco da un'i-node e renderli entrambi liberi. Viene quindi utilizzata solamente dalla funzione purge. Procede quindi nel modo più semplice: esegue un inserimento in testa del blocco e dell'i-node collegandoli agli attuali valori di FLI e FLB e aggiornando poi gli stessi per puntare ai nuovi elementi.
Richiede come parametro l'i-node da liberare e l'offset allo stesso, restituisce quindi al chiamante un exit status dell'operazione.
- int get_i_node(char *path, I_NODE *inode): questa è una delle funzioni di base più importante, tutti i comandi infatti la utilizzano. Richiede come parametro un path e restituisce l'i-node che lo rappresenta e il suo offset. Opera dividendo in token il path in ingresso e poi, partendo dalla root (di cui si conosce l'offset), si sposta fino al path più interno, verificandone anche la validità (ad es. solo l'ultimo token può essere un file) e quindi restituendo i dati trovati.
Lorenzo Baloci, Daniele Turato, Alessio Zennaro
- Settembre 2006