From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 03/10] fs: devfs: Switch to dentry cache implementation
Date: Thu, 31 May 2018 17:04:35 +0200 [thread overview]
Message-ID: <20180531150442.16208-4-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20180531150442.16208-1-s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
fs/Kconfig | 1 -
fs/devfs.c | 150 ++++++++++++++++++++++++++++++-----------------------
2 files changed, 85 insertions(+), 66 deletions(-)
diff --git a/fs/Kconfig b/fs/Kconfig
index 2428a44766..195a5cb060 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -36,7 +36,6 @@ config FS_RAMFS
config FS_DEVFS
bool
default y
- select FS_LEGACY
prompt "devfs support"
config FS_TFTP
diff --git a/fs/devfs.c b/fs/devfs.c
index 2a7b1b3466..5d0bb2c674 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -33,6 +33,11 @@
#include <linux/mtd/mtd-abi.h>
#include <partition.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)
@@ -110,14 +115,11 @@ static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags)
static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
{
- struct cdev *cdev;
+ struct inode *inode = f->f_inode;
+ struct devfs_inode *node = container_of(inode, struct devfs_inode, inode);
+ struct cdev *cdev = node->cdev;
int ret;
- cdev = cdev_by_name(filename + 1);
-
- if (!cdev)
- return -ENOENT;
-
f->size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
FILE_SIZE_STREAM : cdev->size;
f->priv = cdev;
@@ -180,71 +182,112 @@ static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
return 0;
}
-static DIR* devfs_opendir(struct device_d *dev, const char *pathname)
+static struct inode *devfs_alloc_inode(struct super_block *sb)
{
- DIR *dir;
-
- dir = xzalloc(sizeof(DIR));
+ struct devfs_inode *node;
- if (!list_empty(&cdev_list))
- dir->priv = list_first_entry(&cdev_list, struct cdev, list);
+ node = xzalloc(sizeof(*node));
+ if (!node)
+ return NULL;
- return dir;
+ return &node->inode;
}
-static struct dirent* devfs_readdir(struct device_d *_dev, DIR *dir)
+int devfs_iterate(struct file *file, struct dir_context *ctx)
{
- struct cdev *cdev = dir->priv;
+ struct cdev *cdev;
- if (!cdev)
- return NULL;
+ dir_emit_dots(file, ctx);
- list_for_each_entry_from(cdev, &cdev_list, list) {
- strcpy(dir->d.d_name, cdev->name);
- dir->priv = list_entry(cdev->list.next, struct cdev, list);
- return &dir->d;
+ list_for_each_entry(cdev, &cdev_list, list) {
+ dir_emit(ctx, cdev->name, strlen(cdev->name),
+ 1 /* FIXME */, DT_REG);
}
- return NULL;
+
+ return 0;
}
-static int devfs_closedir(struct device_d *dev, DIR *dir)
+static const struct inode_operations devfs_file_inode_operations;
+static const struct file_operations devfs_dir_operations;
+static const struct inode_operations devfs_dir_inode_operations;
+static const struct file_operations devfs_file_operations;
+
+static struct inode *devfs_get_inode(struct super_block *sb, const struct inode *dir,
+ umode_t mode)
{
- free(dir);
- return 0;
+ struct inode *inode = new_inode(sb);
+
+ if (!inode)
+ return NULL;
+
+ inode->i_ino = get_next_ino();
+ inode->i_mode = mode;
+
+ switch (mode & S_IFMT) {
+ default:
+ return NULL;
+ case S_IFREG:
+ inode->i_op = &devfs_file_inode_operations;
+ inode->i_fop = &devfs_file_operations;
+ break;
+ case S_IFDIR:
+ inode->i_op = &devfs_dir_inode_operations;
+ inode->i_fop = &devfs_dir_operations;
+ inc_nlink(inode);
+ break;
+ }
+
+ return inode;
}
-static int devfs_stat(struct device_d *_dev, const char *filename, struct stat *s)
+static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry,
+ unsigned int flags)
{
+ struct devfs_inode *dinode;
+ struct inode *inode;
struct cdev *cdev;
- cdev = lcdev_by_name(filename + 1);
+ cdev = cdev_by_name(dentry->name);
if (!cdev)
- return -ENOENT;
+ return ERR_PTR(-ENOENT);
- s->st_mode = S_IFCHR;
- s->st_size = cdev->size;
+ inode = devfs_get_inode(dir->i_sb, dir, S_IFREG | S_IRWXUGO);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
- if (cdev->link)
- s->st_mode |= S_IFLNK;
+ dinode = container_of(inode, struct devfs_inode, inode);
- cdev = cdev_readlink(cdev);
+ inode->i_size = cdev->size;
+ dinode->cdev = cdev;
- if (cdev->ops->write)
- s->st_mode |= S_IWUSR;
- if (cdev->ops->read)
- s->st_mode |= S_IRUSR;
+ d_add(dentry, inode);
- return 0;
+ return NULL;
}
+static const struct file_operations devfs_dir_operations = {
+ .iterate = devfs_iterate,
+};
+
+static const struct inode_operations devfs_dir_inode_operations =
+{
+ .lookup = devfs_lookup,
+};
+
+static const struct super_operations devfs_ops = {
+ .alloc_inode = devfs_alloc_inode,
+};
+
static int devfs_probe(struct device_d *dev)
{
+ struct inode *inode;
struct fs_device_d *fsdev = dev_to_fs_device(dev);
+ struct super_block *sb = &fsdev->sb;
- if (strcmp(fsdev->path, "/dev")) {
- dev_err(dev, "devfs can only be mounted on /dev/\n");
- return -EINVAL;
- }
+ sb->s_op = &devfs_ops;
+
+ inode = devfs_get_inode(sb, NULL, S_IFDIR);
+ sb->s_root = d_make_root(inode);
return 0;
}
@@ -253,24 +296,6 @@ static void devfs_delete(struct device_d *dev)
{
}
-static int devfs_readlink(struct device_d *dev, const char *pathname,
- char *buf, size_t bufsz)
-{
- struct cdev *cdev;
-
- cdev = cdev_by_name(pathname + 1);
- if (!cdev)
- return -ENOENT;
-
- while (cdev->link)
- cdev = cdev->link;
-
- bufsz = min(bufsz, strlen(cdev->name));
- memcpy(buf, cdev->name, bufsz);
-
- return 0;
-}
-
static struct fs_driver_d devfs_driver = {
.read = devfs_read,
.write = devfs_write,
@@ -279,15 +304,10 @@ static struct fs_driver_d devfs_driver = {
.close = devfs_close,
.flush = devfs_flush,
.ioctl = devfs_ioctl,
- .opendir = devfs_opendir,
- .readdir = devfs_readdir,
.truncate = devfs_truncate,
- .closedir = devfs_closedir,
- .stat = devfs_stat,
.erase = devfs_erase,
.protect = devfs_protect,
.memmap = devfs_memmap,
- .readlink = devfs_readlink,
.flags = FS_DRIVER_NO_DEV,
.drv = {
.probe = devfs_probe,
--
2.17.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2018-05-31 15:05 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-31 15:04 [PATCH v2 00/10] dentry cache support Sascha Hauer
2018-05-31 15:04 ` [PATCH 01/10] fs: dentry cache implementation Sascha Hauer
2018-05-31 15:04 ` [PATCH 02/10] fs: ramfs: Switch to " Sascha Hauer
2018-05-31 15:04 ` Sascha Hauer [this message]
2018-05-31 15:04 ` [PATCH 04/10] fs: ext4: " Sascha Hauer
2018-05-31 15:04 ` [PATCH 05/10] fs: ubifs: " Sascha Hauer
2018-05-31 15:04 ` [PATCH 06/10] fs: nfs: " Sascha Hauer
2018-05-31 15:04 ` [PATCH 07/10] fs: tftp: " Sascha Hauer
2018-05-31 15:04 ` [PATCH 08/10] fs: cramfs: " Sascha Hauer
2018-05-31 15:04 ` [PATCH 09/10] fs: squashfs: " Sascha Hauer
2018-05-31 15:04 ` [PATCH 10/10] block: Adjust cache sizes Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180531150442.16208-4-s.hauer@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox