summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-07-03 10:12:40 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-07-04 08:38:22 +0200
commit8d064097eb1033f9ada70e786dd09617ffa0eed0 (patch)
tree155d7c803db286aa039f1d74de69a5bdc6a14b71 /fs
parentcca17e25bfb7e7cc2b0ab4164561f725969ce36a (diff)
downloadbarebox-8d064097eb1033f9ada70e786dd09617ffa0eed0.tar.gz
barebox-8d064097eb1033f9ada70e786dd09617ffa0eed0.tar.xz
fs: fix standard zero, full devices
The standard devices are currently broken since they have the size ~0. As now files use loff_t as file size which is a signed type the read implementation gets confused and now returns -1. The current implementation also has the (somewhat theorical) problem that we do not have real streaming devices, so /dev/zero went out of zeroes after reading 4GB (or now LLONG_MAX). This patch introduces a new cdev flag DEVFS_IS_CHARACTER_DEV and a new file size flag FILE_SIZE_STREAM which makes it possible to create real stream devices instead. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs')
-rw-r--r--fs/devfs.c3
-rw-r--r--fs/fs.c8
2 files changed, 6 insertions, 5 deletions
diff --git a/fs/devfs.c b/fs/devfs.c
index ea8b250a68..fccf25a721 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -121,7 +121,8 @@ static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
if (!cdev)
return -ENOENT;
- f->size = cdev->size;
+ f->size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
+ FILE_SIZE_STREAM : cdev->size;
f->inode = cdev;
if (cdev->ops->open) {
diff --git a/fs/fs.c b/fs/fs.c
index 1774fb719f..0b376a544b 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -643,7 +643,7 @@ int read(int fd, void *buf, size_t count)
fsdrv = dev_to_fs_driver(dev);
- if (f->pos + count > f->size)
+ if (f->size != FILE_SIZE_STREAM && f->pos + count > f->size)
count = f->size - f->pos;
if (!count)
@@ -672,7 +672,7 @@ ssize_t write(int fd, const void *buf, size_t count)
dev = f->dev;
fsdrv = dev_to_fs_driver(dev);
- if (f->pos + count > f->size) {
+ if (f->size != FILE_SIZE_STREAM && f->pos + count > f->size) {
ret = fsdrv->truncate(dev, f, f->pos + count);
if (ret) {
if (ret != -ENOSPC)
@@ -740,12 +740,12 @@ loff_t lseek(int fildes, loff_t offset, int whence)
switch (whence) {
case SEEK_SET:
- if (offset > f->size)
+ if (f->size != FILE_SIZE_STREAM && offset > f->size)
goto out;
pos = offset;
break;
case SEEK_CUR:
- if (offset + f->pos > f->size)
+ if (f->size != FILE_SIZE_STREAM && offset + f->pos > f->size)
goto out;
pos = f->pos + offset;
break;