diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2007-07-05 18:01:39 +0200 |
---|---|---|
committer | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-07-05 18:01:39 +0200 |
commit | eaff0679f342d9dd36827b4df0326aa54747812e (patch) | |
tree | 83691837cda9187750b3f5651d318b232e080ccd /fs | |
parent | a4b702a62fe81d4c775ac1a4c088aea7682e55aa (diff) | |
download | barebox-eaff0679f342d9dd36827b4df0326aa54747812e.tar.gz barebox-eaff0679f342d9dd36827b4df0326aa54747812e.tar.xz |
svn_rev_281
read support for ramfs
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cramfs/cramfs.c | 5 | ||||
-rw-r--r-- | fs/fs.c | 6 | ||||
-rw-r--r-- | fs/ramfs.c | 52 |
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; } @@ -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) |