diff options
Diffstat (limited to 'CS3871/filesystem')
-rw-r--r-- | CS3871/filesystem/README.rst | 0 | ||||
-rw-r--r-- | CS3871/filesystem/disk.h | 17 | ||||
-rw-r--r-- | CS3871/filesystem/disk.o | bin | 0 -> 3352 bytes | |||
-rw-r--r-- | CS3871/filesystem/tfs.c | 352 |
4 files changed, 369 insertions, 0 deletions
diff --git a/CS3871/filesystem/README.rst b/CS3871/filesystem/README.rst new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/CS3871/filesystem/README.rst diff --git a/CS3871/filesystem/disk.h b/CS3871/filesystem/disk.h new file mode 100644 index 0000000..7bf6ad0 --- /dev/null +++ b/CS3871/filesystem/disk.h @@ -0,0 +1,17 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define TRACKS 128 +#define SECTORS 4096 + +/* 10ms per track change */ +/* 10ms/SECTORS per unit sector distance > 1 */ + +void dinit(); + +void rsector(int t,int s,unsigned char *b); + +void wsector(int t,int s,unsigned char *b); + + diff --git a/CS3871/filesystem/disk.o b/CS3871/filesystem/disk.o Binary files differnew file mode 100644 index 0000000..b1a36f8 --- /dev/null +++ b/CS3871/filesystem/disk.o diff --git a/CS3871/filesystem/tfs.c b/CS3871/filesystem/tfs.c new file mode 100644 index 0000000..fe2d94c --- /dev/null +++ b/CS3871/filesystem/tfs.c @@ -0,0 +1,352 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/time.h> +#include "disk.h" + +#define MAX_INODES 1000 +#define INODE_START (TRACKS * SECTORS) / (8 * 512) +#define MAX_FILES 50 + +struct block_ptr { + char track; + short sector; +}; +struct blockll{ + struct block_ptr data; + struct blockll *next; +}; + +struct meta_data{ + char name[8]; + int size; + int read; + int write; + int create; +}; + +struct inode { + struct meta_data info; + struct block_ptr data[20]; +}; + + +struct inode_list{ + struct inode *node; + struct inode_list *next; +}; + +struct file { + struct inode *node; + int mode; + int next_sec; + int free; +}; + + +int inode_list_size = 0; +struct inode_list *root, *end; + +char bitmap[TRACKS][SECTORS/8]; + +struct file files[MAX_FILES]; +int size; + + + +int check_bitmap(t,s) +int t,s; +{ + char tmp; + tmp = bitmap[t][s/8]; + tmp &= (1 << (s % 8)); + return (int) tmp; +} + +void set_bitmap(t,s) +int t,s; +{ + bitmap[t][s/8] |= (1 << (s % 8)); + return; +} + +void print_bitmap() +{ + int i,j; + for(i = 0; i < 128; i++){ + + printf("\n%4d ", i); + for (j = 0; j < 4096/8; j++) { + printf("%02x", bitmap[i][j]); + if (j %31 == 0) { + printf("\n%4d ",i); + } + } + } +} + + +/* TODO + * Implement inode table as binary tree to speedup searches + */ +struct inode* inode_search(name) +char *name; +{ + if (strcmp(name,"") == 0) { + return -1; + } + int i; + struct inode_list *tmp = root; + + for(i = 0; i < MAX_INODES && i < inode_list_size; i++){ + tmp = tmp->next; + if(strcmp(name, tmp->node->info.name) == 0) + return tmp->node; + } + return -2; +} + +struct blockll* get_blocks(size) +int size; +{ + int i, t, s; + struct blockll *root, *current = malloc(sizeof(struct blockll)); + root = current; + + for (i = 0; size > 0 && i < (4096 * 128); i++) { + t = i / 4096; + s = i % 4096; + + if (!check_bitmap(t, s)) { + current->next = malloc(sizeof(struct blockll)); + current = current->next; + current-> next = NULL; + current->data.track = (char) t; + current->data.sector = (short) s; + + set_bitmap(t,s); + size-= 512; + } + } + + return i <(4096 * 128) ? root : NULL; +} + +struct inode_list* inode_create(name) +char *name; +{ + struct timeval *tmp_time = malloc(sizeof(struct timeval)); + + struct inode_list *tmp = malloc(sizeof(struct inode_list)); + struct inode *tmp_node = malloc(sizeof(struct inode)); + + + tmp->node = tmp_node; + + memcpy(&(tmp->node->info.name), name, strlen(name)); + + gettimeofday(tmp_time, NULL); + + tmp->node->info.create = tmp_time->tv_sec; + tmp->node->info.read = tmp_time->tv_sec; + tmp->node->info.write = tmp_time->tv_sec; + + end->next = tmp; + end = tmp; + inode_list_size++; + + return tmp; +} + +int inode_init() +{ + int n = MAX_INODES / 4; + int i; + char *ptr; + struct inode_list *tmp; + + if (MAX_INODES % 4 > 0) + n++; + + char *buf = malloc(512 * n); + + for (i =0; i < n; i++) { + rsector(0, i, buf + (512 * i)); + } + ptr = buf; + + tmp = root; + + for(i=0; i< MAX_INODES; i++) { + tmp->next = malloc(sizeof(struct inode_list)); + memcpy(&tmp->node, ptr, 64); + ptr += 64; + tmp = tmp->next; + inode_list_size++; + } +} + +/*save inodes to first n sectors on disk*/ +void inode_save() +{ + int i, j; + char *buf = malloc(512); + struct inode_list *tmp = root; + + for (i = 0; i < MAX_INODES && tmp->next;i++) { + for (j = 0; j < 4; j++){ + tmp = tmp->next; + memcpy(buf + j, tmp->node, sizeof(struct inode)); + } + wsector(0, INODE_START + i, buf); + } +} + +struct inode* inode_from_fd(fd) +int fd; +{ + int i; + struct inode_list *tmp = root; + + for (i = 0; i < fd; i++) { + tmp = tmp->next; + } + + return tmp->node; +} + +int find_fd() +{ + int i; + for (i = 0; i < size; i++) { + if (files[i].free) + return i; + } +} + +int tfs_init() +{ + int i; + root = malloc(sizeof(struct inode_list)); + end = root; + + dinit(); + /* + * + * has issue if inodes have not been written to disk i.e. first run + inode_init(); + */ + for (i = 0; i < MAX_FILES; i++) { + files[i].free = 1; + } +} + + +int open(fname, mode) +char *fname, *mode; +{ + struct inode *fnode = inode_search(fname); + int fd; + + if (fnode == -1) + return -1; + + if (fnode == -2){ + fnode = inode_create(fname)->node; + } + fd = find_fd(); + + files[fd].node = fnode; + files[fd].mode = *mode; + files[fd].next_sec = 0; + files[fd].free = 0; + size++; + + return fd; +} + +int close(fd) +int fd; +{ + if (files[fd].free) + return -1; + + files[fd].free = 1; + return 1; +} + +int read(fd, buf) +int fd; +char *buf; +{ + if (files[fd].free || files[fd].mode || (files[fd].next_sec == 20)) + return -1; + + + rsector(files[fd].node->data[files[fd].next_sec].track, files[fd].node->data[files[fd].next_sec].sector, buf); + files[fd].next_sec++; + return 512; +} + +int write(fd, buf) +int fd; +char *buf; +{ + if ((files[fd].next_sec == 20) || !files[fd].mode) + return 0; + + struct blockll *tmp = get_blocks(500); + files[fd].node->data[files[fd].next_sec].track = tmp->data.track; + files[fd].node->data[files[fd].next_sec].sector = tmp->data.sector; + + wsector(files[fd].node->data[files[fd].next_sec].track, files[fd].node->data[files[fd].next_sec].sector, buf); + return 1; +} + +int ulink(fname) +char *fname; +{ + struct inode_list *tmp = root; + struct inode *d; + int i; + + for(i = 0; i < MAX_INODES && i < inode_list_size; i++){ + tmp = tmp->next; + if(strcmp(fname, tmp->next->node->info.name) == 0) + break;; + } + + d = tmp->next->node; + tmp->next = tmp->next->next; + free(d); + return 1; + } + +int main() +{ + tfs_init(); + + /* + *Test Writing + */ + int mode = 1; + int fd = open("test", &mode); + + char buf[512]; + memcpy(&buf, "Hello Filesystem", strlen("Hello Filesystem")); + + int test = write(fd, &buf); + close(fd); + + /* + *Test reading + */ + mode = 0; + fd = open("test", &mode); + char buf2[512]; + read(fd, &buf2); + printf("wrote: %s\n", buf); + + printf("read: %s\n", buf2); + +} |