diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-07-03 10:12:40 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-07-04 08:38:22 +0200 |
commit | 8d064097eb1033f9ada70e786dd09617ffa0eed0 (patch) | |
tree | 155d7c803db286aa039f1d74de69a5bdc6a14b71 /fs | |
parent | cca17e25bfb7e7cc2b0ab4164561f725969ce36a (diff) | |
download | barebox-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.c | 3 | ||||
-rw-r--r-- | fs/fs.c | 8 |
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) { @@ -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; |