JustKernel

Ray Of Hope

Tiny Usermode FileSystem

While reading the below code, please try to find answers to the questions that I had posted in my previous post. It will help to build your understanding..

Here is the simple C code..

#include <stdio.h>
#include <stdlib.h>
#define MAX_FILES (3)
#define DISK_SIZE (1<<20)
#define FILE_NOT_FOUND -5
#define FILE_COUNT_EXCEED -3

struct fs_metadata
{
int isfile;
int size;
int fd;
char *data;
struct fs_metadata *child;
struct fs_metadata *parent;
struct fs_metadata *sibling;
};

struct fs_metadata *root = NULL;
struct fs_metadata *mydir = NULL;
struct fs_metadata *file1 = NULL;
struct fs_metadata *file2 = NULL;
struct fs_metadata *file3 = NULL;

void display_info()
{
printf(“Root Information  \n”);
printf(“Root Address = %lx\n”, root);
printf(“Root isFile = %d \n”, root->isfile);
printf(“Root fd = %d \n”, root->fd);
printf(“Rot size = %d \n”, root->size);
if(root->child != NULL)
printf(“Root child = %lx \n”, root->child);
if(root->sibling != NULL)
printf(“Root sibling = %lx \n”, root->sibling);

printf(“\n\n”);
printf(“MyDIr Information \n”);
printf(“MyDir Address = %lx\n”, mydir);
printf(“MyDir isFile = %d \n”, mydir->isfile);
printf(“MyDir fd = %d \n”, mydir->fd);
printf(“MyDir size = %d \n”, mydir->size);
if(mydir->child != NULL )
printf(“MyDir child = %lx \n”, mydir->child);
}

void dump_buf(
char *address,
int length
)
{
int i = 0; //used to keep track of line lengths
char *line = (char*)address; //used to print char version of data
unsigned char ch; // also used to print char version of data
printf(“\n”);
printf(“%08X | “, (int)address); //Print the address we are pulling from
while (length– > 0)
{
printf(“%02X “, (unsigned char)*address++); //Print each char
if (!(++i % 16) || (length == 0 && i % 16))
{ //If we come to the end of a line…
//If this is the last line, print some fillers.
if (length == 0)
{
while (i++ % 16)
{
printf(“__ “);
}
}
printf(“| “);
while (line < address)
{
// Print the character version
ch = *line++;
printf(“%c”, (ch < 33 || ch == 255) ? 0x2E : ch);
}
// If we are not on the last line, prefix the next line with the address.
if (length > 0)
{
printf(“\n%08X | “, (int)address);
}
}
}
puts(“”);
}

struct fs_metadata * initialize_fs(struct fs_metadata *init_ptr)
{
root = init_ptr;
memset(root, 0, sizeof(struct fs_metadata));
root->sibling = NULL;
root->parent = NULL;
root->data = NULL;
root->isfile = 0;
root->fd = -1;
root->size = (sizeof(struct fs_metadata));

mydir = (char *)root + sizeof(struct fs_metadata);
root->child = mydir;
memset(mydir, 0, sizeof(struct fs_metadata));
mydir->data = NULL;
mydir->child = NULL;
mydir->parent = root;
mydir->sibling = NULL;
mydir->isfile = 0;
mydir->size = sizeof(struct fs_metadata);
mydir->fd = -1;
return init_ptr;
}

int fs_create(int fd)
{
struct fs_metadata *tmp = mydir->child;
struct fs_metadata *file = NULL;
int count = 0;
int tot_data_size = 0;

if(tmp == NULL)
{
printf(“fs_create : creating first file =%d at location =%lx\n”,
fd, (char *)root + 2 * (sizeof(struct fs_metadata)));
file = (char *)root + 2 * (sizeof(struct fs_metadata));
file->parent = mydir;
file->child = NULL;
file->sibling = NULL;
file->isfile = 1;
file->data = NULL;
file->size = 0;
file->fd = fd;
mydir->child = file;
}
else
{
count = 1;
while(tmp->sibling != NULL)
{
count++;
if(count > MAX_FILES)
return FILE_COUNT_EXCEED;
tmp = tmp->sibling;
}
printf(“Creating file no %d at location %lx\n”,fd,
((char *)root + 2*(sizeof(struct fs_metadata)) + count * (sizeof(struct fs_metadata))));
file = (char *)root + 2*(sizeof(struct fs_metadata)) + count * (sizeof(struct fs_metadata));

tmp->sibling = file;
file->parent = mydir;
file->child = NULL;
file->isfile = 1;
file->data = NULL;
file->fd = fd;
file->size = 0;
}
switch(fd)
{
case 1:
file1 = file;
break;
case 2:
file2 = file;
break;
case 3:
file3 = file;
break;
default:
printf(“Illegal fd \n”);
return -1;
}
}

int fs_write(int fd, char *buf, unsigned int size)
{
struct fs_metadata *tmp = mydir->child;
struct fs_metadata *tmp1 = mydir->child;
int fs_tot_size = 0;
if(tmp == NULL)
{
printf(“fs_write: No File Exists \n”);
return -1;
}
while(tmp != NULL)
{
fs_tot_size = fs_tot_size + tmp->size;
tmp = tmp->sibling;
}
while(tmp1->sibling != NULL)
{
if(tmp1->fd == fd)
break;
tmp1 = tmp1->sibling;
}
if( tmp1->fd != fd)
{
printf(“file_write: File with FD = %d does not exist\n”, fd);
return FILE_NOT_FOUND;
}
tmp1->data = (char *)((char *)root + 500 + fs_tot_size);
tmp1->size = size;
memcpy(tmp1->data, buf, size);
return 1;
}

int fs_read(int fd, char *buf, unsigned int size)
{
struct fs_metadata *tmp = mydir->child;
int count = 0;
int fs_tot_size = 0;
if(tmp == NULL)
{
printf(“fs_read: No File Exists \n”);
return -1;
}
while(tmp->sibling != NULL)
{
if(tmp->fd == fd)
{
break;
}
tmp = tmp->sibling;
}
if(tmp->fd != fd)
{
printf(“fs_read: File with FD = %d does not exists \n”, fd);
return FILE_NOT_FOUND;
}
while(count < size)
{
printf(“%c”, tmp->data[count++]);
}
printf(“\n\n”);
return 1;

}

int fs_ls()
{
//print the number of files
// print the size of the files
struct fs_metadata *tmp = mydir->child;
int count = 0;
if(tmp == NULL)
{
printf(“fs_ls: No File Exists \n”);
return -1;
}

while(tmp != NULL)
{
printf(“fs_ls : File fd: %d, File Size = %d \n”, tmp->fd, tmp->size);
count++;
tmp = tmp->sibling;
}

printf(“Total File Count = %d\n”, count);
}

void test(void) {
char read_buf[1024];
fs_create(2);
fs_create(1);
fs_create(3);

fs_write(2, “hello world”, 11);
fs_write(3, “finally did it”,15);
fs_write(1, “make your day”,13);

fs_read(2, read_buf, 11);
fs_read(1, read_buf, 13);
fs_read(3, read_buf, 15);
fs_ls();
}

void main()
{
void *ptr;
ptr = (void *)malloc(DISK_SIZE);
memset(ptr, 0, DISK_SIZE);

ptr = initialize_fs(ptr);
//display_info();

test();
}

If any thing is not clear or you want further information, then please mail me..
Originally Posted On: 2011-06-01 01:38:13
Anshul Makkar, anshul_makkar@justkernel.com

Tags:


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.