filesys : open & create
This commit is contained in:
parent
6ac67efe2d
commit
58e866cb2f
@ -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)
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user