From 132c9b968dab5ffff3f989e22acdfc072d82e42d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 5 Jul 2007 18:01:43 +0200 Subject: [PATCH] svn_rev_325 implement . and .. entries --- fs/ramfs.c | 243 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 181 insertions(+), 62 deletions(-) diff --git a/fs/ramfs.c b/fs/ramfs.c index 797b1ae47..e9d62f3f6 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -7,6 +7,7 @@ #include #include #include +#include #define CHUNK_SIZE 512 @@ -17,6 +18,7 @@ struct ramfs_chunk { struct ramfs_inode { char *name; + struct ramfs_inode *parent; struct ramfs_inode *next; struct ramfs_inode *child; ulong mode; @@ -32,9 +34,9 @@ struct ramfs_priv { }; /* ---------------------------------------------------------------*/ -struct ramfs_inode * __lookup(struct ramfs_inode *node, const char *name) +struct ramfs_inode * lookup(struct ramfs_inode *node, const char *name) { -// printf("__lookup: %s in %p\n",name, node); +// printf("lookup: %s in %p\n",name, node); if(node->mode != S_IFDIR) return NULL; @@ -43,15 +45,19 @@ struct ramfs_inode * __lookup(struct ramfs_inode *node, const char *name) return NULL; while (node) { - if (!strcmp(node->name, name)) +// printf("lookup: %s\n", node->name); + if (!strcmp(node->name, name)) { +// printf("lookup: found: 0x%p\n",node); return node; + } node = node->next; } return NULL; } -struct ramfs_inode* rlookup(struct ramfs_inode *node, const char *path) +struct ramfs_inode* rlookup(struct ramfs_priv *priv, const char *path) { + struct ramfs_inode *node = &priv->root; static char *buf; char *part; //printf("rlookup %s in %p\n",path, node); @@ -62,7 +68,7 @@ struct ramfs_inode* rlookup(struct ramfs_inode *node, const char *path) goto out; do { - node = __lookup(node, part); + node = lookup(node, part); if (!node) goto out; part = strtok(NULL, "/"); @@ -73,40 +79,102 @@ out: return node; } +struct ramfs_inode* rlookup_parent(struct ramfs_priv *priv, const char *pathname, char **file) +{ + char *path; + struct ramfs_inode *node; + + pathname++; + path = strdup(pathname); + + if ((*file = strrchr(pathname, '/'))) { + char *tmp; + (*file)++; + + tmp = strrchr(path, '/'); + *tmp = 0; + node = rlookup(priv, path); + if (!node) { + errno = -ENOENT; + goto out; + } + } else { + *file = (char *)pathname; + node = &priv->root; + } + +out: + free(path); + return node; +} + +static int chunks = 0; + struct ramfs_chunk *ramfs_get_chunk(void) { struct ramfs_chunk *data = malloc(sizeof(struct ramfs_chunk)); - printf("get chunk\n"); +// printf("get chunk\n"); data->data = malloc(CHUNK_SIZE); data->next = NULL; + chunks++; +// printf("chunks: %d\n", chunks); return data; } void ramfs_put_chunk(struct ramfs_chunk *data) { - printf("put chunk\n"); +// printf("put chunk\n"); free(data->data); free(data); + chunks--; +// printf("chunks: %d\n", chunks); } -struct ramfs_inode* node_add_child(struct ramfs_inode *node, const char *filename, ulong mode) +static struct ramfs_inode* ramfs_get_inode(void) { - struct ramfs_inode *new_node = malloc(sizeof(struct ramfs_inode)); - memset(new_node, 0, sizeof(struct ramfs_inode)); + struct ramfs_inode *node = xzalloc(sizeof(struct ramfs_inode)); + return node; +} + +static void ramfs_put_inode(struct ramfs_inode *node) +{ + struct ramfs_chunk *data = node->data; + + while (data) { + struct ramfs_chunk *tmp = data->next; + ramfs_put_chunk(data); + data = tmp; + } + + free(node->name); + free(node); +} + +struct ramfs_inode* node_insert(struct ramfs_inode *parent_node, const char *filename, ulong mode) +{ + struct ramfs_inode *node, *new_node = ramfs_get_inode(); new_node->name = strdup(filename); new_node->mode = mode; - if (!(mode & S_IFDIR)) + node = parent_node->child; + + if (mode & S_IFDIR) { + struct ramfs_inode *n = ramfs_get_inode(); + n->name = strdup("."); + n->mode = S_IFDIR; + n->child = n; + n->parent = new_node; + new_node->child = n; + n = ramfs_get_inode(); + n->name = strdup(".."); + n->mode = S_IFDIR; + n->parent = new_node; + n->child = parent_node->child; + new_node->child->next = n; + } else { new_node->data = ramfs_get_chunk(); - - printf("node_add_child: %p -> %p\n", node, new_node); - if (!node->child) { - node->child = new_node; - return new_node; } - node = node->child; - while (node->next) node = node->next; @@ -119,43 +187,75 @@ struct ramfs_inode* node_add_child(struct ramfs_inode *node, const char *filenam int ramfs_create(struct device_d *dev, const char *pathname, mode_t mode) { struct ramfs_priv *priv = dev->priv; - char *path = strdup(pathname); - char *file; struct ramfs_inode *node; + char *file; - normalise_path(path); - if (*path == '/') - path++; - - printf("ramfs create: %s\n",path); - - if ((file = strrchr(path, '/'))) { - *file = 0; - file++; - node = rlookup(&priv->root, path); - if (!node) - return -ENOENT; - } else { - file = path; - node = &priv->root; - } - - if(__lookup(node, file)) - return -EEXIST; -printf("CREATE\n"); - node_add_child(node, file, mode); + node = rlookup_parent(priv, pathname, &file); + node_insert(node, file, mode); return 0; } +int ramfs_unlink(struct device_d *dev, const char *pathname) +{ + struct ramfs_priv *priv = dev->priv; + struct ramfs_inode *node, *lastnode; + char *file; + + node = rlookup_parent(priv, pathname, &file); + + lastnode = node->child->next; + node = lastnode->next; + + while (node) { + if (!strcmp(node->name, file)) { + struct ramfs_inode *tmp; + tmp = node; + lastnode->next = node->next; + ramfs_put_inode(tmp); + return 0; + } + lastnode = node; + node = node->next; + }; + return -ENOENT; +} + int ramfs_mkdir(struct device_d *dev, const char *pathname) { return ramfs_create(dev, pathname, S_IFDIR); } +int ramfs_rmdir(struct device_d *dev, const char *pathname) +{ + struct ramfs_priv *priv = dev->priv; + struct ramfs_inode *node, *lastnode; + char *file; + + node = rlookup_parent(priv, pathname, &file); + + lastnode = node->child->next; + node = lastnode->next; + + while (node) { + if (!strcmp(node->name, file)) { + struct ramfs_inode *tmp; + tmp = node; + lastnode->next = node->next; + ramfs_put_inode(tmp->child->next); + ramfs_put_inode(tmp->child); + ramfs_put_inode(tmp); + return 0; + } + lastnode = node; + node = node->next; + }; + return -ENOENT; +} + static int ramfs_open(struct device_d *dev, FILE *file, const char *filename) { struct ramfs_priv *priv = dev->priv; - struct ramfs_inode *node = rlookup(&priv->root, filename); + struct ramfs_inode *node = rlookup(priv, filename); if (!node) return -ENOENT; @@ -181,7 +281,7 @@ static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize) int size = insize; chunk = f->pos / CHUNK_SIZE; - printf("%s: reading from chunk %d\n", __FUNCTION__, chunk); +// printf("%s: reading from chunk %d\n", __FUNCTION__, chunk); /* Position ourself in stream */ data = node->data; @@ -194,20 +294,21 @@ static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize) /* Read till end of current chunk */ if (ofs) { now = min(size, CHUNK_SIZE - ofs); - printf("Reading till end of node. size: %d\n", size); +// printf("Reading till end of node. size: %d\n", size); memcpy(buf, data->data + ofs, now); size -= now; pos += now; buf += now; if (pos > node->size) node->size = now; + data = data->next; } /* Do full chunks */ while (size >= CHUNK_SIZE) { - printf("do full chunk. size: %d\n", size); - data = data->next; +// printf("do full chunk. size: %d\n", size); memcpy(buf, data->data, CHUNK_SIZE); + data = data->next; size -= CHUNK_SIZE; pos += CHUNK_SIZE; buf += CHUNK_SIZE; @@ -215,8 +316,7 @@ static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize) /* And the rest */ if (size) { - printf("do rest. size: %d\n", size); - data = data->next; +// printf("do rest. size: %d\n", size); memcpy(buf, data->data, size); } @@ -234,7 +334,7 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i int size = insize; chunk = f->pos / CHUNK_SIZE; - printf("%s: writing to chunk %d\n", __FUNCTION__, chunk); +// printf("%s: writing to chunk %d\n", __FUNCTION__, chunk); /* Position ourself in stream */ data = node->data; @@ -247,20 +347,21 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i /* Write till end of current chunk */ if (ofs) { now = min(size, CHUNK_SIZE - ofs); - printf("writing till end of node. size: %d\n", size); - memcpy(data->data, buf, now); +// printf("writing till end of node. size: %d\n", size); + memcpy(data->data + ofs, buf, now); size -= now; pos += now; buf += now; if (pos > node->size) node->size = now; + data = data->next; } /* Do full chunks */ while (size >= CHUNK_SIZE) { - printf("do full chunk. size: %d\n", size); - data = data->next; +// printf("do full chunk. size: %d\n", size); memcpy(data->data, buf, CHUNK_SIZE); + data = data->next; size -= CHUNK_SIZE; pos += CHUNK_SIZE; buf += CHUNK_SIZE; @@ -268,8 +369,7 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i /* And the rest */ if (size) { - printf("do rest. size: %d\n", size); - data = data->next; +// printf("do rest. size: %d\n", size); memcpy(data->data, buf, size); } @@ -315,8 +415,11 @@ struct dir* ramfs_opendir(struct device_d *dev, const char *pathname) { struct dir *dir; struct ramfs_priv *priv = dev->priv; - struct ramfs_inode *node = rlookup(&priv->root, pathname); + struct ramfs_inode *node; +// printf("opendir: %s\n", pathname); + node = rlookup(priv, pathname); +//printf("opendir name: %s\n", node->name); if (!node) return NULL; @@ -353,11 +456,12 @@ int ramfs_closedir(struct device_d *dev, struct dir *dir) int ramfs_stat(struct device_d *dev, const char *filename, struct stat *s) { struct ramfs_priv *priv = dev->priv; - struct ramfs_inode *node = rlookup(&priv->root, filename); + struct ramfs_inode *node = rlookup(priv, filename); +// printf("ramfs_stat: %s\n", filename); if (!node) return -ENOENT; - +// printf("stat: %s\n", node->name); s->st_size = node->size; s->st_mode = node->mode; @@ -366,29 +470,44 @@ int ramfs_stat(struct device_d *dev, const char *filename, struct stat *s) int ramfs_probe(struct device_d *dev) { - struct ramfs_priv *priv = malloc(sizeof(struct ramfs_priv)); + struct ramfs_inode *n; + struct ramfs_priv *priv = xzalloc(sizeof(struct ramfs_priv)); - printf("ramfs_probe\n"); - memset(priv, 0, sizeof(struct ramfs_priv)); +// printf("ramfs_probe\n"); dev->priv = priv; priv->root.name = "/"; priv->root.mode = S_IFDIR; + priv->root.parent = &priv->root; + n = ramfs_get_inode(); + n->name = strdup("."); + n->mode = S_IFDIR; + n->parent = &priv->root; + n->child = n; + priv->root.child = n; + n = ramfs_get_inode(); + n->name = strdup(".."); + n->mode = S_IFDIR; + n->parent = &priv->root; + n->child = priv->root.child; + priv->root.child->next = n; +// printf("priv->root: 0x%p\n", priv->root); - printf("root node: %p\n",&priv->root); return 0; } static struct fs_driver_d ramfs_driver = { .type = FS_TYPE_RAMFS, .create = ramfs_create, + .unlink = ramfs_unlink, .open = ramfs_open, .close = ramfs_close, .truncate = ramfs_truncate, .read = ramfs_read, .write = ramfs_write, .mkdir = ramfs_mkdir, + .rmdir = ramfs_rmdir, .opendir = ramfs_opendir, .readdir = ramfs_readdir, .closedir = ramfs_closedir,