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 FREE_MAP_SECTOR : i32 = 0;
|
||||||
const DIRECTORY_SECTOR : i32 = 1;
|
const DIRECTORY_SECTOR : i32 = 1;
|
||||||
|
|
||||||
pub struct Filesys {
|
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
|
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
|
/// Since we can't increase the size of files dynamically, we have
|
||||||
/// to give Create the initial size of the file.
|
/// to give Create the initial size of the file.
|
||||||
//
|
//
|
||||||
/// The steps to create a file are:
|
/// The steps to create a file are:
|
||||||
/// Make sure the file doesn't already exist
|
/// Make sure the file doesn't already exist
|
||||||
/// Allocate a sector for the file header
|
/// Allocate a sector for the file header
|
||||||
/// Allocate space on disk for the data blocks for the file
|
/// Allocate space on disk for the data blocks for the file
|
||||||
/// Add the name to the directory
|
/// Add the name to the directory
|
||||||
/// Store the new file header on disk
|
/// Store the new file header on disk
|
||||||
/// Flush the changes to the bitmap and the directory back to disk
|
/// Flush the changes to the bitmap and the directory back to disk
|
||||||
///
|
///
|
||||||
/// Create fails if:
|
/// Create fails if:
|
||||||
/// file is already in directory
|
/// file is already in directory
|
||||||
@ -81,9 +81,97 @@ impl Filesys {
|
|||||||
///
|
///
|
||||||
/// -**name** is the name of file to be created (NOT MODIFIED)
|
/// -**name** is the name of file to be created (NOT MODIFIED)
|
||||||
/// -**initialSize** is the size of file to be created
|
/// -**initialSize** is the size of file to be created
|
||||||
/// \return NO_ERROR if everything goes ok, otherwise, return an error
|
pub fn create(&mut self, name : String, initial_size : i32) -> Result<(), ErrorCode> {
|
||||||
// code as define in msgerror.h
|
|
||||||
pub fn create(name : String, initial_size : i32) -> i32 {
|
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