Skip to content

Commit

Permalink
Fix a bunch of bugs and write some comments
Browse files Browse the repository at this point in the history
  • Loading branch information
asmeurer committed Apr 26, 2012
1 parent 041f2ad commit cb36749
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 28 deletions.
15 changes: 9 additions & 6 deletions filesystem/definitions.h
Expand Up @@ -49,7 +49,10 @@ typedef unsigned char byte;
#define ERROR_ADDR_OUT_OF_BOUNDS -27 #define ERROR_ADDR_OUT_OF_BOUNDS -27
#define ERROR_BLOCK_ALREADY_EMPTY -28 #define ERROR_BLOCK_ALREADY_EMPTY -28
#define ERROR_BLOCK_ALREADY_FULL -29 #define ERROR_BLOCK_ALREADY_FULL -29
#define ERROR_DIR_NOT_EMPTY -30 #define ERROR_FILES_ARE_OPEN -30
#define ERROR_ALREADY_MOUNTED -31
#define ERROR_ALREADY_UNMOUNTED -32
#define ERROR_FS_NAME_NOT_EXISTS -33


/* Constants /* Constants
* *
Expand All @@ -72,7 +75,9 @@ typedef unsigned char byte;
/*256 MB*/ /*256 MB*/
#define MEM_SIZE (256<<20) #define MEM_SIZE (256<<20)


/* The smallest block size is 4 KB */ /* Memory size divided by smallest allowed block size (4KB), divided by 8 bits
* per byte */

#define MAX_BLOCK_SIZE (MEM_SIZE/(4<<10)) #define MAX_BLOCK_SIZE (MEM_SIZE/(4<<10))


enum rw { enum rw {
Expand Down Expand Up @@ -116,10 +121,8 @@ struct fcb;
typedef struct fcb fcb; typedef struct fcb fcb;


/* Device struct */ /* Device struct */
typedef struct{ typedef struct {
fcb *root; fcb *root;
/* Memory size divided by smallest allowed block, divided by 8 bits per
* byte */
byte bitmap[MAX_BLOCK_SIZE]; byte bitmap[MAX_BLOCK_SIZE];
byte numblock; byte numblock;
char fs_name; char fs_name;
Expand All @@ -131,7 +134,7 @@ typedef struct{
device device_array [MAX_DEVICE]; device device_array [MAX_DEVICE];


/* Open File struct */ /* Open File struct */
typedef struct{ typedef struct {
fcb* file; fcb* file;
byte bits; byte bits;
/* 0 0 0 0 0 0 (write access) (open) */ /* 0 0 0 0 0 0 (write access) (open) */
Expand Down
128 changes: 106 additions & 22 deletions filesystem/file_manager.c
Expand Up @@ -39,14 +39,29 @@ int init_fs (int device){
* @return Returns ERROR_SUCCESS on success, else an error code. * @return Returns ERROR_SUCCESS on success, else an error code.
*/ */
int mount (char fs_name){ int mount (char fs_name){
int i; int dev;
for(i = 0; i < MAX_DEVICE; i++){ dev = get_device(fs_name);
if(device_array[i].fs_name == fs_name && (!(device_array[i].bits & DEVICE_FORMAT_BITMASK))){
device_array[i].bits |= DEVICE_MOUNTED_BITMASK; if (dev < 0) {
return ERROR_SUCCESS; /* Bad fs_name */
} return dev;
}

/* Mount cannot work if the file system has not been formatted, or if it
* is already mounted. */
if (!(device_array[dev].bits & DEVICE_FORMAT_BITMASK)) {
/* A file system cannot have a name if it isn't formatted, so this
* should actually never happen. */
return ERROR_NOT_INITIALIZED_OR_FORMATED;
}

if (device_array[dev].bits & DEVICE_MOUNTED_BITMASK) {
return ERROR_ALREADY_MOUNTED;
} }
return ERROR_NOT_INITIALIZED_OR_FORMATED;
device_array[dev].bits |= DEVICE_MOUNTED_BITMASK;

return ERROR_SUCCESS;
} }


/** /**
Expand Down Expand Up @@ -116,18 +131,64 @@ int format(int device_num, char fs_name, int blocksize){
return format_me->numblock; return format_me->numblock;
} }


/**
* Unmounts the drive.
*
* A drive cannot be unmounted if it has open files, or if it is already
* unmounted.
*
* @param fs_name The name of the filesystem to unmount.
*
* @return Returns ERROR_SUCCESS on success, else an error code.
*/
int unmount(char fs_name){ int unmount(char fs_name){
int dev = get_device(fs_name);
int i; int i;
for(i = 0; i < MAX_DEVICE; i++){


if (dev < 0) {
/* Bad fs_name */
return dev;
}

/* A device cannot be unmounted if it is not formatted, or if it is
* already unmounted. */
if (!(device_array[dev].bits & DEVICE_FORMAT_BITMASK)) {
/* This should never happen. */
return ERROR_NOT_INITIALIZED_OR_FORMATED;
}

if (!(device_array[dev].bits & DEVICE_MOUNTED_BITMASK)) {
return ERROR_ALREADY_UNMOUNTED;
}

/* A device cannot be unmounted if there are open files. */
for(i = 0; i < MAX_OPEN; i++){
if ((open_files[i].bits & OPEN_TYPE_OPEN_BITMASK) && (open_files[i].file->device_num == dev)) {
return ERROR_FILES_ARE_OPEN;
}
} }

device_array[dev].bits |= ~DEVICE_MOUNTED_BITMASK;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }


/* Convert a file path into a file. This is very similar to the search inside /**
* create(). */ * Convert a file path into a file.
*
* This is used internally to find the file given a file path data structure,
* which is basically a linked list of strings.
*
* @param dev The device number to look for the file in
*
* @file_path The file path corresponding to the file to be returned.
*
* @return Returns a pointer to the file corresponding to file_path. Any
* error codes will be in the error field of the fcb.
*/
fcb *get_file(int dev, path *file_path) fcb *get_file(int dev, path *file_path)
{ {
/* This is very similar to the search inside create(), but we care about
* different errors in this case. */
struct path *next = file_path; struct path *next = file_path;
struct dir_queue_t *current_dir = device_array[dev].root->dirHead; struct dir_queue_t *current_dir = device_array[dev].root->dirHead;
fcb *current_file = current_dir->tail; fcb *current_file = current_dir->tail;
Expand All @@ -152,20 +213,24 @@ fcb *get_file(int dev, path *file_path)
} }
} }


return null; return current_file;
} }


/** /**
* This function closes a file by using the file handle to referance it, then sets the fbc pointer file to null and the bits to 0 * Closes the given file, by file handle.
*
* The file handle is the index in the open file array (though this is
* technically an implementation detail).
*
* @param filehandle The file handle for the file to be closed. This is the
* same file handle that will be returned to the user on a call to open().
*
* @return Returns ERROR_SUCCESS on success, else an error code.
*/ */
int close(int filehandle){ int close(int filehandle){
int i; open_files[filehandle].file = null;
for(i = 0; i < MAX_OPEN; i++){ open_files[filehandle].bits = 0;
if(i == filehandle){
open_files[i].file = null;
open_files[i].bits = 0;
}
}
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }


Expand Down Expand Up @@ -296,6 +361,11 @@ int create(char fs_name, struct path *file_path, int dir)
{ {
int dev = get_device(fs_name); int dev = get_device(fs_name);


if (dev < 0) {
/* Bad fs_name */
return dev;
}

struct path *next = file_path; struct path *next = file_path;
struct dir_queue_t *current_dir = device_array[dev].root->dirHead; struct dir_queue_t *current_dir = device_array[dev].root->dirHead;
fcb *current_file = current_dir->tail; fcb *current_file = current_dir->tail;
Expand Down Expand Up @@ -362,8 +432,16 @@ int create(char fs_name, struct path *file_path, int dir)


int delete(char fs_name, struct path *file_path) int delete(char fs_name, struct path *file_path)
{ {
int dev = get_device(fs_name); int dev = get_device(fs_name);
if (dev < 0) {
return dev;
}

fcb *file = get_file(dev, file_path); fcb *file = get_file(dev, file_path);
if (file->error < 0) {
return file->error;
}

return delete_internal(dev, file); return delete_internal(dev, file);
} }


Expand Down Expand Up @@ -418,12 +496,18 @@ int delete_internal(int dev, fcb *file)
int get_device(char fs_name) int get_device(char fs_name)
{ {
int i; int i;
for (i=0; i < MAX_DEVICE; i++) {
if (fs_name < 'A' || fs_name > 'Z') {
return ERROR_BAD_FS_NAME;
}

for (i = 0; i < MAX_DEVICE; i++) {
if (device_array[i].fs_name == fs_name) { if (device_array[i].fs_name == fs_name) {
return i; return i;
} }
} }
return ERROR_BAD_FS_NAME;
return ERROR_FS_NAME_NOT_EXISTS;
} }


/* Custom version of strcmp to compare filenames. Returns 0 if the names are /* Custom version of strcmp to compare filenames. Returns 0 if the names are
Expand Down

0 comments on commit cb36749

Please sign in to comment.