diff options
Diffstat (limited to 'fs/devfs.c')
-rw-r--r-- | fs/devfs.c | 106 |
1 files changed, 39 insertions, 67 deletions
diff --git a/fs/devfs.c b/fs/devfs.c index e1893d1bd0..c8ddbbdab0 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -3,9 +3,6 @@ * * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix * - * See file CREDITS for list of people who contributed to this - * project. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. @@ -31,23 +28,22 @@ #include <linux/err.h> #include <linux/mtd/mtd.h> #include <linux/mtd/mtd-abi.h> -#include <partition.h> +#include <block.h> struct devfs_inode { struct inode inode; struct cdev *cdev; }; -extern struct list_head cdev_list; - -static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) +static int devfs_read(struct device *_dev, FILE *f, void *buf, size_t size) { struct cdev *cdev = f->priv; return cdev_read(cdev, buf, size, f->pos, f->flags); } -static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size) +static int devfs_write(struct device *_dev, FILE *f, const void *buf, + size_t size) { struct cdev *cdev = f->priv; @@ -57,21 +53,15 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s return cdev_write(cdev, buf, size, f->pos, f->flags); } -static int devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos) +static int devfs_lseek(struct device *_dev, FILE *f, loff_t pos) { struct cdev *cdev = f->priv; - int ret; - - if (cdev->ops->lseek) { - ret = cdev->ops->lseek(cdev, pos + cdev->offset); - if (ret < 0) - return ret; - } - return 0; + return cdev_lseek(cdev, pos); } -static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offset) +static int devfs_erase(struct device *_dev, FILE *f, loff_t count, + loff_t offset) { struct cdev *cdev = f->priv; @@ -84,53 +74,30 @@ static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offs return cdev_erase(cdev, count, offset); } -static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, loff_t offset, int prot) +static int devfs_protect(struct device *dev, FILE *f, size_t count, + loff_t offset, int prot) { struct cdev *cdev = f->priv; - if (!cdev->ops->protect) - return -ENOSYS; - - return cdev->ops->protect(cdev, count, offset + cdev->offset, prot); + return cdev_protect(cdev, count, offset, prot); } -static int devfs_discard_range(struct device_d *dev, FILE *f, loff_t count, +static int devfs_discard_range(struct device *dev, FILE *f, loff_t count, loff_t offset) { struct cdev *cdev = f->priv; - if (!cdev->ops->discard_range) - return -ENOSYS; - - if (cdev->flags & DEVFS_PARTITION_READONLY) - return -EPERM; - - if (offset >= cdev->size) - return 0; - - if (count + offset > cdev->size) - count = cdev->size - offset; - - return cdev->ops->discard_range(cdev, count, offset + cdev->offset); + return cdev_discard_range(cdev, count, offset); } -static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags) +static int devfs_memmap(struct device *_dev, FILE *f, void **map, int flags) { struct cdev *cdev = f->priv; - int ret = -ENOSYS; - - if (!cdev->ops->memmap) - return -EINVAL; - - ret = cdev->ops->memmap(cdev, map, flags); - if (!ret) - *map = (void *)((unsigned long)*map + (unsigned long)cdev->offset); - - return ret; + return cdev_memmap(cdev, map, flags); } -static int devfs_open(struct device_d *_dev, FILE *f, const char *filename) +static int devfs_open(struct device *_dev, FILE *f, const char *filename) { struct inode *inode = f->f_inode; struct devfs_inode *node = container_of(inode, struct devfs_inode, inode); @@ -147,12 +114,10 @@ static int devfs_open(struct device_d *_dev, FILE *f, const char *filename) return ret; } - cdev->open++; - return 0; } -static int devfs_close(struct device_d *_dev, FILE *f) +static int devfs_close(struct device *_dev, FILE *f) { struct cdev *cdev = f->priv; int ret; @@ -163,33 +128,28 @@ static int devfs_close(struct device_d *_dev, FILE *f) return ret; } - cdev->open--; - return 0; } -static int devfs_flush(struct device_d *_dev, FILE *f) +static int devfs_flush(struct device *_dev, FILE *f) { struct cdev *cdev = f->priv; return cdev_flush(cdev); } -static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf) +static int devfs_ioctl(struct device *_dev, FILE *f, int request, void *buf) { struct cdev *cdev = f->priv; return cdev_ioctl(cdev, request, buf); } -static int devfs_truncate(struct device_d *dev, FILE *f, loff_t size) +static int devfs_truncate(struct device *dev, FILE *f, loff_t size) { struct cdev *cdev = f->priv; - if (cdev->ops->truncate) - return cdev->ops->truncate(cdev, size); - - return -EPERM; + return cdev_truncate(cdev, size); } static struct inode *devfs_alloc_inode(struct super_block *sb) @@ -203,13 +163,20 @@ static struct inode *devfs_alloc_inode(struct super_block *sb) return &node->inode; } +static void devfs_destroy_inode(struct inode *inode) +{ + struct devfs_inode *node = container_of(inode, struct devfs_inode, inode); + + free(node); +} + static int devfs_iterate(struct file *file, struct dir_context *ctx) { struct cdev *cdev; dir_emit_dots(file, ctx); - list_for_each_entry(cdev, &cdev_list, list) { + for_each_cdev(cdev) { dir_emit(ctx, cdev->name, strlen(cdev->name), 1 /* FIXME */, DT_REG); } @@ -263,6 +230,7 @@ static struct inode *devfs_get_inode(struct super_block *sb, const struct inode default: return NULL; case S_IFCHR: + case S_IFBLK: inode->i_op = &devfs_file_inode_operations; inode->i_fop = &devfs_file_operations; break; @@ -282,12 +250,15 @@ static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry, struct devfs_inode *dinode; struct inode *inode; struct cdev *cdev; + umode_t mode; cdev = cdev_by_name(dentry->name); if (!cdev) return ERR_PTR(-ENOENT); - inode = devfs_get_inode(dir->i_sb, dir, S_IFCHR); + mode = cdev_get_block_device(cdev) ? S_IFBLK : S_IFCHR; + + inode = devfs_get_inode(dir->i_sb, dir, mode); if (!inode) return ERR_PTR(-ENOMEM); @@ -317,12 +288,13 @@ static const struct inode_operations devfs_dir_inode_operations = static const struct super_operations devfs_ops = { .alloc_inode = devfs_alloc_inode, + .destroy_inode = devfs_destroy_inode, }; -static int devfs_probe(struct device_d *dev) +static int devfs_probe(struct device *dev) { struct inode *inode; - struct fs_device_d *fsdev = dev_to_fs_device(dev); + struct fs_device *fsdev = dev_to_fs_device(dev); struct super_block *sb = &fsdev->sb; sb->s_op = &devfs_ops; @@ -334,11 +306,11 @@ static int devfs_probe(struct device_d *dev) return 0; } -static void devfs_delete(struct device_d *dev) +static void devfs_delete(struct device *dev) { } -static struct fs_driver_d devfs_driver = { +static struct fs_driver devfs_driver = { .read = devfs_read, .write = devfs_write, .lseek = devfs_lseek, |