From ee6d36a5405305f3bbdb0457948c219731b3d9cc Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 6 Jun 2008 09:25:13 +0200 Subject: - introduce ioctl call - pass open/close/lseek through to drivers --- fs/cramfs/cramfs.c | 7 +++++++ fs/devfs.c | 36 ++++++++++++++++++++++++++++++------ fs/fs.c | 34 ++++++++++++++++++++++++++++++---- fs/ramfs.c | 7 +++++++ 4 files changed, 74 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index 9c08ad5a29..62f15d6271 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -352,6 +352,12 @@ static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) return outsize; } +static off_t cramfs_lseek(struct device_d *dev, FILE *f, off_t pos) +{ + f->pos = pos; + return f->pos; +} + static int cramfs_stat(struct device_d *_dev, const char *filename, struct stat *stat) { struct cramfs_priv *priv = _dev->priv; @@ -443,6 +449,7 @@ static struct fs_driver_d cramfs_driver = { .open = cramfs_open, .close = cramfs_close, .read = cramfs_read, + .lseek = cramfs_lseek, .opendir = cramfs_opendir, .readdir = cramfs_readdir, .closedir = cramfs_closedir, diff --git a/fs/devfs.c b/fs/devfs.c index 10c2dfeab6..12abc1829d 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -44,6 +44,19 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s return dev_write(dev, buf, size, f->pos, f->flags); } +static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos) +{ + struct device_d *dev = f->inode; + int ret; + + ret = dev_lseek(dev, pos); + + if (ret >= 0) + f->pos = pos; + + return ret; +} + static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset) { struct device_d *dev = f->inode; @@ -65,21 +78,30 @@ static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags) return dev_memmap(dev, map, flags); } -static int devfs_open(struct device_d *_dev, FILE *file, const char *filename) +static int devfs_open(struct device_d *_dev, FILE *f, const char *filename) { struct device_d *dev = get_device_by_id(filename + 1); if (!dev) return -ENOENT; - file->size = dev->size; - file->inode = dev; - return 0; + f->size = dev->size; + f->inode = dev; + return dev_open(dev, f); } -static int devfs_close(struct device_d *dev, FILE *f) +static int devfs_close(struct device_d *_dev, FILE *f) { - return 0; + struct device_d *dev = f->inode; + + return dev_close(dev, f); +} + +static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf) +{ + struct device_d *dev = f->inode; + + return dev_ioctl(dev, request, buf); } static int devfs_truncate(struct device_d *dev, FILE *f, ulong size) @@ -156,8 +178,10 @@ static struct fs_driver_d devfs_driver = { .type = FS_TYPE_DEVFS, .read = devfs_read, .write = devfs_write, + .lseek = devfs_lseek, .open = devfs_open, .close = devfs_close, + .ioctl = devfs_ioctl, .opendir = devfs_opendir, .readdir = devfs_readdir, .truncate = devfs_truncate, diff --git a/fs/fs.c b/fs/fs.c index 2d90df3f5f..3f0f1345fb 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -451,6 +451,22 @@ int creat(const char *pathname, mode_t mode) } EXPORT_SYMBOL(creat); +int ioctl(int fd, int request, void *buf) +{ + struct device_d *dev; + struct fs_driver_d *fsdrv; + FILE *f = &files[fd]; + + dev = f->dev; + + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + + if (fsdrv->ioctl) + return fsdrv->ioctl(dev, f, request, buf); + + return -ENOSYS; +} + int read(int fd, void *buf, size_t count) { struct device_d *dev; @@ -496,30 +512,40 @@ EXPORT_SYMBOL(write); off_t lseek(int fildes, off_t offset, int whence) { + struct device_d *dev; + struct fs_driver_d *fsdrv; FILE *f = &files[fildes]; + ulong pos; + errno = 0; + dev = f->dev; + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + if (!fsdrv->lseek) + return -ENOSYS; + switch(whence) { case SEEK_SET: if (offset > f->size) goto out; - f->pos = offset; + pos = offset; break; case SEEK_CUR: if (offset + f->pos > f->size) goto out; - f->pos += offset; + pos = f->pos + offset; break; case SEEK_END: if (offset) goto out; - f->pos = f->size; + pos = f->size; break; default: goto out; } - return 0; + return fsdrv->lseek(dev, f, pos); + out: errno = -EINVAL; return errno; diff --git a/fs/ramfs.c b/fs/ramfs.c index 38ef035d53..beee6b9256 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -403,6 +403,12 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i return insize; } +static off_t ramfs_lseek(struct device_d *dev, FILE *f, off_t pos) +{ + f->pos = pos; + return f->pos; +} + static int ramfs_truncate(struct device_d *dev, FILE *f, ulong size) { struct ramfs_inode *node = (struct ramfs_inode *)f->inode; @@ -540,6 +546,7 @@ static struct fs_driver_d ramfs_driver = { .truncate = ramfs_truncate, .read = ramfs_read, .write = ramfs_write, + .lseek = ramfs_lseek, .mkdir = ramfs_mkdir, .rmdir = ramfs_rmdir, .opendir = ramfs_opendir, -- cgit v1.2.3