Skip to content

Commit

Permalink
Project4 out
Browse files Browse the repository at this point in the history
  • Loading branch information
hestati63 committed Jun 15, 2020
1 parent 5c26081 commit 9d0ff70
Show file tree
Hide file tree
Showing 35 changed files with 777 additions and 49 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ all::
@echo "Run 'make' in subdirectories: $(BUILD_SUBDIRS)."
@echo "This top-level make has only 'clean' targets."

CLEAN_SUBDIRS = threads userprog vm
CLEAN_SUBDIRS = $(BUILD_SUBDIRS)

clean::
for d in $(CLEAN_SUBDIRS); do $(MAKE) -C $$d $@; done
Expand All @@ -15,7 +15,7 @@ clean::
distclean:: clean
find . -name '*~' -exec rm '{}' \;

TAGS_SUBDIRS = $(BUILD_SUBDIRS) devices lib
TAGS_SUBDIRS = $(BUILD_SUBDIRS) devices lib include
TAGS_SOURCES = find $(TAGS_SUBDIRS) -name \*.[chS] -print

TAGS::
Expand Down
14 changes: 7 additions & 7 deletions filesys/Make.vars
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# -*- makefile -*-

os.dsk: DEFINES = -DUSERPROG -DFILESYS
os.dsk: DEFINES = -DUSERPROG -DFILESYS -DEFILESYS
KERNEL_SUBDIRS = threads devices lib lib/kernel userprog filesys
TEST_SUBDIRS = tests/userprog tests/filesys/base tests/filesys/extended
KERNEL_SUBDIRS += tests/threads tests/threads/mlfqs
TEST_SUBDIRS = tests/threads tests/userprog tests/filesys/base tests/filesys/extended
GRADING_FILE = $(SRCDIR)/tests/filesys/Grading.no-vm
SIMULATOR = --qemu

# Uncomment the lines below to enable VM.
#os.dsk: DEFINES += -DVM
#KERNEL_SUBDIRS += vm
#TEST_SUBDIRS += tests/vm
#GRADING_FILE = $(SRCDIR)/tests/filesys/Grading.with-vm
# os.dsk: DEFINES += -DVM
# KERNEL_SUBDIRS += vm
# TEST_SUBDIRS += tests/vm
# GRADING_FILE = $(SRCDIR)/tests/filesys/Grading.with-vm
3 changes: 1 addition & 2 deletions filesys/Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
all grade check:
@echo "project 4 is not ready. Wait for the announcement."
include ../Makefile.kernel
193 changes: 193 additions & 0 deletions filesys/fat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#include "filesys/fat.h"
#include "devices/disk.h"
#include "filesys/filesys.h"
#include "threads/malloc.h"
#include "threads/synch.h"
#include <stdio.h>
#include <string.h>

/* Should be less than DISK_SECTOR_SIZE */
struct fat_boot {
unsigned int magic;
unsigned int sectors_per_cluster; /* Fixed to 1 */
unsigned int total_sectors;
unsigned int fat_start;
unsigned int fat_sectors; /* Size of FAT in sectors. */
unsigned int root_dir_cluster;
};

/* FAT FS */
struct fat_fs {
struct fat_boot bs;
unsigned int *fat;
unsigned int fat_length;
disk_sector_t data_start;
cluster_t last_clst;
struct lock write_lock;
};

static struct fat_fs *fat_fs;

void fat_boot_create (void);
void fat_fs_init (void);

void
fat_init (void) {
fat_fs = calloc (1, sizeof (struct fat_fs));
if (fat_fs == NULL)
PANIC ("FAT init failed");

// Read boot sector from the disk
unsigned int *bounce = malloc (DISK_SECTOR_SIZE);
if (bounce == NULL)
PANIC ("FAT init failed");
disk_read (filesys_disk, FAT_BOOT_SECTOR, bounce);
memcpy (&fat_fs->bs, bounce, sizeof (fat_fs->bs));
free (bounce);

// Extract FAT info
if (fat_fs->bs.magic != FAT_MAGIC)
fat_boot_create ();
fat_fs_init ();
}

void
fat_open (void) {
fat_fs->fat = calloc (fat_fs->fat_length, sizeof (cluster_t));
if (fat_fs->fat == NULL)
PANIC ("FAT load failed");

// Load FAT directly from the disk
uint8_t *buffer = (uint8_t *) fat_fs->fat;
off_t bytes_read = 0;
off_t bytes_left = sizeof (fat_fs->fat);
const off_t fat_size_in_bytes = fat_fs->fat_length * sizeof (cluster_t);
for (unsigned i = 0; i < fat_fs->bs.fat_sectors; i++) {
bytes_left = fat_size_in_bytes - bytes_read;
if (bytes_left >= DISK_SECTOR_SIZE) {
disk_read (filesys_disk, fat_fs->bs.fat_start + i,
buffer + bytes_read);
bytes_read += DISK_SECTOR_SIZE;
} else {
uint8_t *bounce = malloc (DISK_SECTOR_SIZE);
if (bounce == NULL)
PANIC ("FAT load failed");
disk_read (filesys_disk, fat_fs->bs.fat_start + i, bounce);
memcpy (buffer + bytes_read, bounce, bytes_left);
bytes_read += bytes_left;
free (bounce);
}
}
}

void
fat_close (void) {
// Write FAT boot sector
uint8_t *bounce = calloc (1, DISK_SECTOR_SIZE);
if (bounce == NULL)
PANIC ("FAT close failed");
memcpy (bounce, &fat_fs->bs, sizeof (fat_fs->bs));
disk_write (filesys_disk, FAT_BOOT_SECTOR, bounce);
free (bounce);

// Write FAT directly to the disk
uint8_t *buffer = (uint8_t *) fat_fs->fat;
off_t bytes_wrote = 0;
off_t bytes_left = sizeof (fat_fs->fat);
const off_t fat_size_in_bytes = fat_fs->fat_length * sizeof (cluster_t);
for (unsigned i = 0; i < fat_fs->bs.fat_sectors; i++) {
bytes_left = fat_size_in_bytes - bytes_wrote;
if (bytes_left >= DISK_SECTOR_SIZE) {
disk_write (filesys_disk, fat_fs->bs.fat_start + i,
buffer + bytes_wrote);
bytes_wrote += DISK_SECTOR_SIZE;
} else {
bounce = calloc (1, DISK_SECTOR_SIZE);
if (bounce == NULL)
PANIC ("FAT close failed");
memcpy (bounce, buffer + bytes_wrote, bytes_left);
disk_write (filesys_disk, fat_fs->bs.fat_start + i, bounce);
bytes_wrote += bytes_left;
free (bounce);
}
}
}

void
fat_create (void) {
// Create FAT boot
fat_boot_create ();
fat_fs_init ();

// Create FAT table
fat_fs->fat = calloc (fat_fs->fat_length, sizeof (cluster_t));
if (fat_fs->fat == NULL)
PANIC ("FAT creation failed");

// Set up ROOT_DIR_CLST
fat_put (ROOT_DIR_CLUSTER, EOChain);

// Fill up ROOT_DIR_CLUSTER region with 0
uint8_t *buf = calloc (1, DISK_SECTOR_SIZE);
if (buf == NULL)
PANIC ("FAT create failed due to OOM");
disk_write (filesys_disk, cluster_to_sector (ROOT_DIR_CLUSTER), buf);
free (buf);
}

void
fat_boot_create (void) {
unsigned int fat_sectors =
(disk_size (filesys_disk) - 1)
/ (DISK_SECTOR_SIZE / sizeof (cluster_t) * SECTORS_PER_CLUSTER + 1);
fat_fs->bs = (struct fat_boot){
.magic = FAT_MAGIC,
.sectors_per_cluster = SECTORS_PER_CLUSTER,
.total_sectors = disk_size (filesys_disk),
.fat_start = 1,
.fat_sectors = fat_sectors,
.root_dir_cluster = ROOT_DIR_CLUSTER,
};
}

void
fat_fs_init (void) {
/* TODO: Your code goes here. */
}

/*----------------------------------------------------------------------------*/
/* FAT handling */
/*----------------------------------------------------------------------------*/

/* Add a cluster to the chain.
* If CLST is 0, start a new chain.
* Returns 0 if fails to allocate a new cluster. */
cluster_t
fat_create_chain (cluster_t clst) {
/* TODO: Your code goes here. */
}

/* Remove the chain of clusters starting from CLST.
* If PCLST is 0, assume CLST as the start of the chain. */
void
fat_remove_chain (cluster_t clst, cluster_t pclst) {
/* TODO: Your code goes here. */
}

/* Update a value in the FAT table. */
void
fat_put (cluster_t clst, cluster_t val) {
/* TODO: Your code goes here. */
}

/* Fetch a value in the FAT table. */
cluster_t
fat_get (cluster_t clst) {
/* TODO: Your code goes here. */
}

/* Covert a cluster # to a sector number. */
disk_sector_t
cluster_to_sector (cluster_t clst) {
/* TODO: Your code goes here. */
}
3 changes: 2 additions & 1 deletion filesys/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ file_duplicate (struct file *file) {
struct file *nfile = file_open (inode_reopen (file->inode));
if (nfile) {
nfile->pos = file->pos;
nfile->deny_write = file->deny_write;
if (file->deny_write)
file_deny_write (nfile);
}
return nfile;
}
Expand Down
24 changes: 24 additions & 0 deletions filesys/filesys.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,35 @@ filesys_init (bool format) {
PANIC ("hd0:1 (hdb) not present, file system initialization failed");

inode_init ();

#ifdef EFILESYS
fat_init ();

if (format)
do_format ();

fat_open ();
#else
/* Original FS */
free_map_init ();

if (format)
do_format ();

free_map_open ();
#endif
}

/* Shuts down the file system module, writing any unwritten data
* to disk. */
void
filesys_done (void) {
/* Original FS */
#ifdef EFILSYS
fat_close ();
#else
free_map_close ();
#endif
}

/* Creates a file named NAME with the given INITIAL_SIZE.
Expand Down Expand Up @@ -90,9 +106,17 @@ filesys_remove (const char *name) {
static void
do_format (void) {
printf ("Formatting file system...");

#ifdef EFILSYS
/* Create FAT and save it to the disk. */
fat_create ();
fat_close ();
#else
free_map_create ();
if (!dir_create (ROOT_DIR_SECTOR, 16))
PANIC ("root directory creation failed");
free_map_close ();
#endif

printf ("done.\n");
}
50 changes: 50 additions & 0 deletions filesys/page_cache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* page_cache.c: Implementation of Page Cache (Buffer Cache). */

#include "vm/vm.h"
static bool page_cache_readahead (struct page *page, void *kva);
static bool page_cache_writeback (struct page *page);
static void page_cache_destroy (struct page *page);

/* DO NOT MODIFY this struct */
static const struct page_operations page_cache_op = {
.swap_in = page_cache_readahead,
.swap_out = page_cache_writeback,
.destroy = page_cache_destroy,
.type = VM_PAGE_CACHE,
};

tid_t page_cache_workerd;

/* The initializer of file vm */
void
pagecache_init (void) {
/* TODO: Create a worker daemon for page cache with page_cache_kworkerd */
}

/* Initialize the page cache */
bool
page_cache_initializer (struct page *page, enum vm_type type, void *kva) {
/* Set up the handler */
page->operations = &page_cache_op;

}

/* Utilze the Swap in mechanism to implement readhead */
static bool
page_cache_readahead (struct page *page, void *kva) {
}

/* Utilze the Swap out mechanism to implement writeback */
static bool
page_cache_writeback (struct page *page) {
}

/* Destory the page_cache. */
static void
page_cache_destroy (struct page *page) {
}

/* Worker thread for page cache */
static void
page_cache_kworkerd (void *aux) {
}
2 changes: 2 additions & 0 deletions filesys/targets.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
filesys_SRC = filesys/filesys.c # Filesystem core.
filesys_SRC += filesys/fat.c # FAT.
filesys_SRC += filesys/free-map.c # Free sector bitmap.
filesys_SRC += filesys/file.c # Files.
filesys_SRC += filesys/directory.c # Directories.
filesys_SRC += filesys/inode.c # File headers.
filesys_SRC += filesys/fsutil.c # Utilities.
filesys_SRC += filesys/page_cache.c # Page cache.
38 changes: 38 additions & 0 deletions include/filesys/fat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef FILESYS_FAT_H
#define FILESYS_FAT_H

#include "devices/disk.h"
#include "filesys/file.h"
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

typedef uint32_t cluster_t; /* Index of a cluster within FAT. */

#define FAT_MAGIC 0xEB3C9000 /* MAGIC string to identify FAT disk */
#define EOChain 0x0FFFFFFF /* End of cluster chain */

/* Sectors of FAT information. */
#define SECTORS_PER_CLUSTER 1 /* Number of sectors per cluster */
#define FAT_BOOT_SECTOR 0 /* FAT boot sector. */
#define ROOT_DIR_CLUSTER 1 /* Cluster for the root directory */

void fat_init (void);
void fat_open (void);
void fat_close (void);
void fat_create (void);
void fat_close (void);

cluster_t fat_create_chain (
cluster_t clst /* Cluster # to stretch, 0: Create a new chain */
);
void fat_remove_chain (
cluster_t clst, /* Cluster # to be removed */
cluster_t pclst /* Previous cluster of clst, 0: clst is the start of chain */
);
cluster_t fat_get (cluster_t clst);
void fat_put (cluster_t clst, cluster_t val);
disk_sector_t cluster_to_sector (cluster_t clst);

#endif /* filesys/fat.h */
Loading

0 comments on commit 9d0ff70

Please sign in to comment.