summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2007-07-05 18:01:39 +0200
committerSascha Hauer <sha@octopus.labnet.pengutronix.de>2007-07-05 18:01:39 +0200
commiteaff0679f342d9dd36827b4df0326aa54747812e (patch)
tree83691837cda9187750b3f5651d318b232e080ccd /fs
parenta4b702a62fe81d4c775ac1a4c088aea7682e55aa (diff)
downloadbarebox-eaff0679f342d9dd36827b4df0326aa54747812e.tar.gz
barebox-eaff0679f342d9dd36827b4df0326aa54747812e.tar.xz
svn_rev_281
read support for ramfs
Diffstat (limited to 'fs')
-rw-r--r--fs/cramfs/cramfs.c5
-rw-r--r--fs/fs.c6
-rw-r--r--fs/ramfs.c52
3 files changed, 60 insertions, 3 deletions
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index 8a57241350..e7f7495435 100644
--- a/fs/cramfs/cramfs.c
+++ b/fs/cramfs/cramfs.c
@@ -277,6 +277,7 @@ static int cramfs_closedir(struct device_d *dev, struct dir *_dir)
static int cramfs_open(struct device_d *_dev, FILE *file, const char *filename)
{
struct cramfs_priv *priv = _dev->priv;
+ struct cramfs_inode *inode;
struct fs_device_d *fsdev = _dev->type_data;
struct device_d *dev = fsdev->parent;
char *f;
@@ -293,7 +294,9 @@ static int cramfs_open(struct device_d *_dev, FILE *file, const char *filename)
if (offset <= 0)
return -ENOENT;
- file->inode = (void*)dev->map_base + offset;
+ inode = (void*)dev->map_base + offset;
+ file->inode = inode;
+ file->size = inode->size;
return 0;
}
diff --git a/fs/fs.c b/fs/fs.c
index 55bd2290a1..22fcbd554f 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -234,8 +234,12 @@ int read(int fd, void *buf, size_t count)
if (dev->type == DEVICE_TYPE_FS) {
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
printf("\nreading %d bytes at %d\n",count, f->pos);
+ if (f->pos + count > f->size)
+ count = f->size - f->pos;
errno = fsdrv->read(dev, f, buf, count);
} else {
+ if (f->pos + count > dev->size)
+ count = dev->size - f->pos;
errno = dev->driver->read(dev, buf, count, f->pos, 0); /* FIXME: flags */
}
if (errno > 0)
@@ -261,6 +265,8 @@ ssize_t write(int fd, const void *buf, size_t count)
}
errno = fsdrv->write(dev, f, buf, count);
} else {
+ if (f->pos + count > dev->size)
+ count = dev->size - f->pos;
errno = dev->driver->write(dev, buf, count, f->pos, 0); /* FIXME: flags */
}
if (errno > 0)
diff --git a/fs/ramfs.c b/fs/ramfs.c
index 63338398c6..bff9804878 100644
--- a/fs/ramfs.c
+++ b/fs/ramfs.c
@@ -186,9 +186,57 @@ static int ramfs_close(struct device_d *dev, FILE *f)
return 0;
}
-static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
+static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
{
- return 0;
+ struct ramfs_inode *node = (struct ramfs_inode *)f->inode;
+ int chunk;
+ struct ramfs_chunk *data;
+ int ofs;
+ int now;
+ int pos = f->pos;
+ int size = insize;
+
+ chunk = f->pos / CHUNK_SIZE;
+ printf("%s: reading from chunk %d\n", __FUNCTION__, chunk);
+
+ /* Position ourself in stream */
+ data = node->data;
+ while (chunk) {
+ data = data->next;
+ chunk--;
+ }
+ ofs = f->pos % CHUNK_SIZE;
+
+ /* Read till end of current chunk */
+ if (ofs) {
+ now = min(size, CHUNK_SIZE - ofs);
+ 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;
+ }
+
+ /* Do full chunks */
+ while (size >= CHUNK_SIZE) {
+ printf("do full chunk. size: %d\n", size);
+ data = data->next;
+ memcpy(buf, data->data, CHUNK_SIZE);
+ size -= CHUNK_SIZE;
+ pos += CHUNK_SIZE;
+ buf += CHUNK_SIZE;
+ }
+
+ /* And the rest */
+ if (size) {
+ printf("do rest. size: %d\n", size);
+ data = data->next;
+ memcpy(buf, data->data, size);
+ }
+
+ return insize;
}
static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t insize)