summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2007-07-05 18:01:38 +0200
committerSascha Hauer <sha@octopus.labnet.pengutronix.de>2007-07-05 18:01:38 +0200
commit112ada667b57ec9b9bd1fc0786f5926779cb5b6e (patch)
tree0b21c8939cadfbdab3d23dfeb48b8173698e9447 /fs
parent4e7505eb8d06e71eee699e91cd974ba8a1a5717f (diff)
downloadbarebox-112ada667b57ec9b9bd1fc0786f5926779cb5b6e.tar.gz
barebox-112ada667b57ec9b9bd1fc0786f5926779cb5b6e.tar.xz
svn_rev_270
WIP FS support
Diffstat (limited to 'fs')
-rw-r--r--fs/cramfs/cramfs.c2
-rw-r--r--fs/fs.c101
-rw-r--r--fs/ramfs.c130
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;
}
diff --git a/fs/fs.c b/fs/fs.c
index 4ed3e39f4e..b43a9e7b38 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -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,