CS3210 Design Operating Systems

Taesoo Kim





Filesystem/Fat32

Taesoo Kim

Administrivia

Storage trend

Why do we need file systems?

Why do we need file systems?

Why interesting?

Common API example (in UNIX-like OSes)

fd = open("x/y", 1);
write(fd, "abc", 3);
link("x/y", "x/z");
unlink("x/y");

High-level API choices

Thinking of interfaces

Disk Layout

Introducing MBR

Partition

DEMO

Fat32 Overview: Disk Layout

DEMO

About FAT

Example FAT

Root directory

File entry

Ref. Fat structs

DEMO

Interfaces for filesystem: Traits

pub trait FileSystem: Sized {
    /// The type of files in this file system.
    type File: File;

    /// The type of directories in this file system.
    type Dir: Dir<Entry = Self::Entry>;

    /// The type of directory entries in this file system.
    type Entry: Entry<File = Self::File, Dir = Self::Dir>;

    /// Opens the entry at `path`. `path` must be absolute.
    fn open<P: AsRef<Path>>(self, path: P) -> io::Result<Self::Entry>;
}

Trait: File

pub trait File: io::Read + io::Write + io::Seek + Sized {
    /// Writes any buffered data to disk.
    fn sync(&mut self) -> io::Result<()>;

    /// Returns the size of the file in bytes.
    fn size(&self) -> u64;
}

Trait: Dir

/// Trait implemented by directories in a file system.
pub trait Dir: Sized {
    /// The type of entry stored in this directory.
    type Entry: Entry;

    /// An type that is an iterator over the entries in this directory.
    type Iter: Iterator<Item = Self::Entry>;

    /// Returns an interator over the entries in this directory.
    fn entries(&self) -> io::Result<Self::Iter>;
}

Trait: Entry

/// An entry is either a `File` or a `Directory`
pub trait Entry: Sized {
    type File: File; type Dir: Dir; type Metadata: Metadata;

    /// The name of the file or directory corresponding to this entry.
    fn name(&self) -> &str;

    /// The metadata associated with the entry.
    fn metadata(&self) -> &Self::Metadata;

    /// If `self` is a file, returns `Some` of the file. Otherwise returns
    /// `None`.
    fn into_file(self) -> Option<Self::File>;

    /// If `self` is a directory, returns `Some` of the directory. Otherwise
    /// returns `None`.
    fn into_dir(self) -> Option<Self::Dir>;
}

Trait: BlockDevice

/// Trait implemented by devices that can be read/written in sector
/// granularities.
pub trait BlockDevice: Send {
    /// Read sector number `n` into `buf`.
    fn read_sector(&mut self, n: u64, buf: &mut [u8]) -> io::Result<usize>;

    /// Overwrites sector `n` with the contents of `buf`.
    fn write_sector(&mut self, n: u64, buf: &[u8]) -> io::Result<usize>;
}

References