diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2007-07-05 18:01:38 +0200 |
---|---|---|
committer | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-07-05 18:01:38 +0200 |
commit | 112ada667b57ec9b9bd1fc0786f5926779cb5b6e (patch) | |
tree | 0b21c8939cadfbdab3d23dfeb48b8173698e9447 /fs | |
parent | 4e7505eb8d06e71eee699e91cd974ba8a1a5717f (diff) | |
download | barebox-112ada667b57ec9b9bd1fc0786f5926779cb5b6e.tar.gz barebox-112ada667b57ec9b9bd1fc0786f5926779cb5b6e.tar.xz |
svn_rev_270
WIP FS support
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cramfs/cramfs.c | 2 | ||||
-rw-r--r-- | fs/fs.c | 101 | ||||
-rw-r--r-- | fs/ramfs.c | 130 |
3 files changed, 183 insertions, 50 deletions
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index 25631a6b74..c8ef7d7ff0 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -294,7 +294,7 @@ static int cramfs_open(struct device_d *_dev, FILE *file, const char *filename) return -ENOENT; file->pos = 0; - file->inode = (struct cramfs_inode *)(dev->map_base + offset); + file->inode = dev->map_base + offset; return 0; } @@ -102,10 +102,10 @@ FILE *get_file(void) int i; for (i = 3; i < MAX_FILES; i++) { - if (!files[i].used) { - files[i].used = 1; - files[i].no = i; + if (!files[i].in_use) { memset(&files[i], 0, sizeof(FILE)); + files[i].in_use = 1; + files[i].no = i; return &files[i]; } } @@ -114,27 +114,60 @@ FILE *get_file(void) void put_file(FILE *f) { - files[f->no].used = 0; + files[f->no].in_use = 0; } -int open(const char *pathname, int flags) +static FILE* get_file_by_pathname(const char *pathname) { - struct device_d *dev; - struct fs_driver_d *fsdrv; - struct mtab_entry *e; FILE *f; - int ret; f = get_file(); if (!f) { errno = -EMFILE; - return errno; + return NULL; } if (!strncmp(pathname, "/dev/", 5)) { - dev = get_device_by_id(pathname + 5); - f->dev = dev; - } else { + f->dev = get_device_by_id(pathname + 5); + } + + return f; +} + +int creat(const char *pathname, mode_t mode) +{ + struct mtab_entry *e; + struct device_d *dev; + struct fs_driver_d *fsdrv; + + e = get_mtab_entry_by_path(pathname); + if (!e) { + errno = -ENOENT; + return errno; + } + + if (e != mtab) + pathname += strlen(e->path); + + dev = e->dev; + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + + errno = fsdrv->create(dev, pathname, mode); + + return errno; +} + +int open(const char *pathname, int flags) +{ + struct device_d *dev; + struct fs_driver_d *fsdrv; + struct mtab_entry *e; + FILE *f; + int ret; + + f = get_file_by_pathname(pathname); + + if (!f->dev) { e = get_mtab_entry_by_path(pathname); if (!e) { errno = -ENOENT; @@ -155,7 +188,7 @@ int open(const char *pathname, int flags) goto out; } } - +printf("open: %d\n",f->no); return f->no; out: @@ -170,21 +203,35 @@ int read(int fd, void *buf, size_t count) FILE *f = &files[fd]; dev = f->dev; + printf("READ: dev: %p\n",dev); if (dev->type == DEVICE_TYPE_FS) { fsdrv = (struct fs_driver_d *)dev->driver->type_data; errno = fsdrv->read(dev, f, buf, count); - return errno; } else { errno = dev->driver->read(dev, buf, count, f->pos, 0); /* FIXME: flags */ - if (errno > 0) - f->pos += errno; - return errno; } + if (errno > 0) + f->pos += errno; + return errno; } ssize_t write(int fd, const void *buf, size_t count) { - return -EROFS; + struct device_d *dev; + struct fs_driver_d *fsdrv; + FILE *f = &files[fd]; + + dev = f->dev; + printf("WRITE: dev: %p\n",dev); + if (dev->type == DEVICE_TYPE_FS) { + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + errno = fsdrv->write(dev, f, buf, count); + } else { + errno = dev->driver->write(dev, buf, count, f->pos, 0); /* FIXME: flags */ + } + if (errno > 0) + f->pos += errno; + return errno; } int close(int fd) @@ -194,10 +241,14 @@ int close(int fd) FILE *f = &files[fd]; dev = f->dev; - fsdrv = (struct fs_driver_d *)dev->driver->type_data; + + if (dev->type == DEVICE_TYPE_FS) { + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + errno = fsdrv->close(dev, f); + } put_file(f); - return fsdrv->close(dev, f); + return errno; } int mount (struct device_d *dev, char *fsname, char *path) @@ -368,7 +419,8 @@ int stat(const char *filename, struct stat *s) struct device_d *dev; struct fs_driver_d *fsdrv; struct mtab_entry *e; - char *f = strdup(filename); + char *buf = strdup(filename); + char *f = buf; memset(s, 0, sizeof(struct stat)); @@ -386,9 +438,12 @@ int stat(const char *filename, struct stat *s) fsdrv = (struct fs_driver_d *)dev->driver->type_data; + if (*f == 0) + f = "/"; + errno = fsdrv->stat(dev, f, s); out: - free(f); + free(buf); return errno; } diff --git a/fs/ramfs.c b/fs/ramfs.c index d271b27bf9..a17315d6f2 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -8,33 +8,38 @@ #include <asm-generic/errno.h> #include <linux/stat.h> +#define CHUNK_SIZE 512 + struct data_d { char *data; - ulong size; struct data_d *next; }; -struct node_d { +struct ramfs_inode { char *name; - struct node_d *next; - struct node_d *child; + struct ramfs_inode *next; + struct ramfs_inode *child; ulong mode; struct handle_d *handle; + ulong size; struct data_d *data; }; struct ramfs_priv { - struct node_d root; + struct ramfs_inode root; }; /* ---------------------------------------------------------------*/ -struct node_d * __lookup(struct node_d *node, const char *name) +struct ramfs_inode * __lookup(struct ramfs_inode *node, const char *name) { // printf("__lookup: %s in %p\n",name, node); + if(node->mode != S_IFDIR) + return NULL; + node = node->child; - if (!node || node->mode != S_IFDIR) + if (!node) return NULL; while (node) { @@ -45,7 +50,7 @@ struct node_d * __lookup(struct node_d *node, const char *name) return NULL; } -struct node_d* rlookup(struct node_d *node, const char *path) +struct ramfs_inode* rlookup(struct ramfs_inode *node, const char *path) { static char *buf; char *part; @@ -68,14 +73,14 @@ out: return node; } -int node_add_child(struct node_d *node, const char *filename, ulong mode) +int node_add_child(struct ramfs_inode *node, const char *filename, ulong mode) { - struct node_d *new_node = malloc(sizeof(struct node_d)); - memset(new_node, 0, sizeof(struct node_d)); + struct ramfs_inode *new_node = malloc(sizeof(struct ramfs_inode)); + memset(new_node, 0, sizeof(struct ramfs_inode)); new_node->name = strdup(filename); new_node->mode = mode; -// printf("node_add_child: %p -> %p\n", node, new_node); + printf("node_add_child: %p -> %p\n", node, new_node); if (!node->child) { node->child = new_node; return 0; @@ -92,18 +97,18 @@ int node_add_child(struct node_d *node, const char *filename, ulong mode) /* ---------------------------------------------------------------*/ -int ramfs_create(struct device_d *dev, const char *pathname, ulong mode) +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 node_d *node; + struct ramfs_inode *node; normalise_path(path); if (*path == '/') path++; -// printf("after normalise: %s\n",path); + printf("ramfs create: %s\n",path); if ((file = strrchr(path, '/'))) { *file = 0; @@ -118,7 +123,7 @@ int ramfs_create(struct device_d *dev, const char *pathname, ulong mode) if(__lookup(node, file)) return -EEXIST; - +printf("CREATE\n"); return node_add_child(node, file, mode); } @@ -139,20 +144,87 @@ int ramfs_probe(struct device_d *dev) priv->root.name = "/"; priv->root.mode = S_IFDIR; + printf("root node: %p\n",&priv->root); + return 0; +} + +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); + + if (!node) + return -ENOENT; + + file->pos = 0; + file->inode = node; + return 0; +} + +static int ramfs_close(struct device_d *dev, FILE *f) +{ return 0; } -static int ramfs_open(struct device_d *_dev, FILE *file, const char *filename) +static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) { - return -ENOENT; + return 0; +} + +struct data_d *ramfs_get_chunk(void) +{ + struct data_d *data = malloc(sizeof(struct data_d)); + data->data = malloc(CHUNK_SIZE); + data->next = NULL; + return data; +} + +static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size) +{ + struct ramfs_inode *node = (struct ramfs_inode *)f->inode; + int chunk; + struct data_d *data = node->data; + int ofs; + int outsize = 0; + int now; + + chunk = f->pos / CHUNK_SIZE; + printf("%s: wrinting to chunk %d\n", __FUNCTION__, chunk); + + if (!node->data) + node->data = ramfs_get_chunk(); + + while (chunk) { + data = data->next; + chunk--; + } + + ofs = f->pos % CHUNK_SIZE; + + while (size) { + if (ofs == CHUNK_SIZE) { + printf("get new chunk\n"); + data->next = ramfs_get_chunk(); + data = data->next; + } + + now = min(size, CHUNK_SIZE - ofs); + printf("now: %d data->data: %p buf: %p\n", now, data->data, buf); + memcpy(data->data, buf, now); + size -= now; + buf += now; + ofs += now; + outsize += now; + } + return outsize; } struct dir* ramfs_opendir(struct device_d *dev, const char *pathname) { struct dir *dir; struct ramfs_priv *priv = dev->priv; - struct node_d *node = rlookup(&priv->root, pathname); - + struct ramfs_inode *node = rlookup(&priv->root, pathname); +printf("opendir: %s\n",pathname); if (!node) return NULL; @@ -163,16 +235,18 @@ struct dir* ramfs_opendir(struct device_d *dev, const char *pathname) if (!dir) return NULL; - dir->node = node->child; + dir->priv = node->child; return dir; } struct dirent* ramfs_readdir(struct device_d *dev, struct dir *dir) { - if (dir->node) { - strcpy(dir->d.name, dir->node->name); - dir->node = dir->node->next; + struct ramfs_inode *node = dir->priv; + + if (node) { + strcpy(dir->d.name, node->name); + dir->priv = node->next; return &dir->d; } return NULL; @@ -187,8 +261,8 @@ 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 node_d *node = rlookup(&priv->root, filename); - + struct ramfs_inode *node = rlookup(&priv->root, filename); +printf("%s: %s node: %p\n",__FUNCTION__, filename, node); if (!node) { errno = -ENOENT; return -ENOENT; @@ -203,6 +277,10 @@ static struct fs_driver_d ramfs_driver = { .type = FS_TYPE_RAMFS, .create = ramfs_create, .open = ramfs_open, + .close = ramfs_close, + + .read = ramfs_read, + .write = ramfs_write, .mkdir = ramfs_mkdir, |