filesys : open & create

This commit is contained in:
Baptiste 2023-03-29 15:10:11 +02:00
parent 6ac67efe2d
commit 58e866cb2f

View File

@ -1,11 +1,11 @@
use crate::simulator::disk;
use crate::{simulator::disk, utility::bitmap, kernel::mgerror::ErrorCode};
const ERROR : i32 = -1;
const FREE_MAP_SECTOR : i32 = 0;
const DIRECTORY_SECTOR : i32 = 1;
pub struct Filesys {
pub free_map_file : Open_File, //Bit map of free disk blocks, represented as a file
pub free_map_file : Open_file, //Bit map of free disk blocks, represented as a file
pub directory_file : Open_file //"Root" directory -- list of file names, represented as a file
}
@ -56,17 +56,17 @@ impl Filesys {
}
}
/// create a file in the Nachos file system (similar to UNIX create).
/// Create a file in the BurritOS file system (similar to UNIX create).
/// Since we can't increase the size of files dynamically, we have
/// to give Create the initial size of the file.
//
/// The steps to create a file are:
/// Make sure the file doesn't already exist
/// Allocate a sector for the file header
/// Allocate space on disk for the data blocks for the file
/// Add the name to the directory
/// Store the new file header on disk
/// Flush the changes to the bitmap and the directory back to disk
/// Make sure the file doesn't already exist
/// Allocate a sector for the file header
/// Allocate space on disk for the data blocks for the file
/// Add the name to the directory
/// Store the new file header on disk
/// Flush the changes to the bitmap and the directory back to disk
///
/// Create fails if:
/// file is already in directory
@ -81,9 +81,97 @@ impl Filesys {
///
/// -**name** is the name of file to be created (NOT MODIFIED)
/// -**initialSize** is the size of file to be created
/// \return NO_ERROR if everything goes ok, otherwise, return an error
// code as define in msgerror.h
pub fn create(name : String, initial_size : i32) -> i32 {
pub fn create(&mut self, name : String, initial_size : i32) -> Result<(), ErrorCode> {
lock.acquire();
let dir_sector = find_dir(name);
if dir_sector == ERROR {
lock.release();
return Err(ErrorCode::InexistFileError);
}
let dir_file = openfile::init_open_file(dir_sector);
let directory = directory::init_directory(num_dir_entries);
directory.fetch_from(&dir_file);
if directory.find(name) != ERROR {
lock.release();
return Err(ErrorCode::AlreadyInDirectory);
}
// Get the freemap from the disk
let free_map = bitmap::init_bitmap(disk::NUM_SECTORS);
free_map.fetch_from(self.free_map_file);
// Find a sector to hold the file header
let sector = free_map.find();
if sector == ERROR {
lock.release();
return Err(ErrorCode::OutOfDisk);
}
// Add the file in the directory
let add_result = directory.add(name, sector);
match add_result {
Err(e) => {
lock.release();
return Err(e);
}
_ => {}
}
// Indicate that this is a file, not a directory
let hdr = file_header::init_file_header();
hdr.set_file();
if !hdr.allocate(&free_map, initial_size) {
lock.release();
return Err(ErrorCode::OutOfDisk);
}
// everthing worked, flush all changes back to disk
hdr.write_back(sector);
directory.write_back(&dir_file);
free_map.write_back(self.free_map_file);
lock.release();
Ok(())
}
/// Open a file for reading and writing.
/// To open a file:
/// Find the location of the file's header, using the directory
/// Bring the header into memory
///
/// ### parameters
///
/// -**name** the text name of the file to be opened (NOT MODIFIED)
pub fn open(name : String) -> Option<Open_file> {
let open_file : Open_file;
// Find the directory containing the file
let dir_sector = find_dir(name);
if dir_sector == ERROR {
return None;
}
// Read the directory from disk
let dir_file = open_file::init_open_file(dir_sector);
let directory = directory::init_directory(num_dir_entries);
directory.fetch_from(&directory);
// Find the file in the directory
let sector = directory.find(name);
if sector >= 0 {
open_file = openfile::init_open_file(sector);
open_file.set_name(name);
if open_file.is_dir() {
return None;
}
}
Some(open_file)
}
}