-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
35 changed files
with
777 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 */ |
Oops, something went wrong.