vfs: Add devtmpfs + memfiles
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: ISC
|
||||
|
||||
#include <zinnia/chardev.h>
|
||||
|
||||
void chardev_init(
|
||||
struct chardev* dev,
|
||||
const struct chardev_ops* ops,
|
||||
const struct vfs_file_ops* file_ops,
|
||||
uint32_t major,
|
||||
uint32_t minor
|
||||
) {
|
||||
refcount_init(&dev->rc);
|
||||
dev->ops = ops;
|
||||
dev->file_ops = file_ops;
|
||||
dev->dev = dev_make(major, minor);
|
||||
}
|
||||
|
||||
void chardev_ref(struct chardev* dev) {
|
||||
refcount_inc(&dev->rc);
|
||||
}
|
||||
|
||||
void chardev_unref(struct chardev* dev) {
|
||||
if (refcount_dec(&dev->rc) && dev->ops && dev->ops->destroy)
|
||||
dev->ops->destroy(dev);
|
||||
}
|
||||
|
||||
static errno_t chardev_node_open(struct vfs_node* node, struct vfs_file* file) {
|
||||
struct chardev* dev = node->priv;
|
||||
file->ops = dev->file_ops;
|
||||
if (dev->ops && dev->ops->open)
|
||||
return dev->ops->open(dev, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void chardev_node_destroy(struct vfs_node* node) {
|
||||
chardev_unref(node->priv);
|
||||
}
|
||||
|
||||
static const struct vfs_node_ops chardev_node_ops = {
|
||||
.destroy = chardev_node_destroy,
|
||||
.device = {
|
||||
.open = chardev_node_open,
|
||||
},
|
||||
};
|
||||
|
||||
errno_t devtmpfs_add_chardev(const char* name, struct chardev* dev, mode_t mode) {
|
||||
struct vfs_mknod_target target = {
|
||||
.type = VNODE_CHARDEV,
|
||||
.ops = &chardev_node_ops,
|
||||
.priv = dev,
|
||||
.rdev = dev->dev,
|
||||
};
|
||||
|
||||
chardev_ref(dev);
|
||||
struct vfs_path root = devtmpfs_root();
|
||||
errno_t status = vfs_mknod(root, root, name, mode, &target, ident_kernel(), nullptr);
|
||||
vfs_path_drop(root);
|
||||
if (status)
|
||||
chardev_unref(dev);
|
||||
return status;
|
||||
}
|
||||
|
||||
errno_t devtmpfs_mkdir(const char* name, mode_t mode) {
|
||||
struct vfs_path root = devtmpfs_root();
|
||||
errno_t status = vfs_mkdir(root, root, name, mode, ident_kernel());
|
||||
vfs_path_drop(root);
|
||||
return status;
|
||||
}
|
||||
|
||||
errno_t devtmpfs_remove(const char* name) {
|
||||
struct vfs_path root = devtmpfs_root();
|
||||
errno_t status = vfs_unlink(root, root, name, ident_kernel());
|
||||
vfs_path_drop(root);
|
||||
return status;
|
||||
}
|
||||
|
||||
errno_t devtmpfs_symlink(const char* name, const char* target) {
|
||||
struct vfs_path root = devtmpfs_root();
|
||||
errno_t status = vfs_symlink(root, root, name, target, ident_kernel());
|
||||
vfs_path_drop(root);
|
||||
return status;
|
||||
}
|
||||
Reference in New Issue
Block a user