2020-01-06 20:25:06 +01:00
|
|
|
#include <kernel/fs/vfs.h>
|
|
|
|
#include <kernel/fs/stat.h>
|
|
|
|
#include <kernel/util.h>
|
|
|
|
|
2020-01-10 17:21:44 +01:00
|
|
|
/* gevice_get() - Find internal device */
|
2020-01-06 20:25:06 +01:00
|
|
|
struct device *device_get(dev_t major)
|
|
|
|
{
|
|
|
|
extern uint32_t bdevice_section;
|
|
|
|
extern uint32_t edevice_section;
|
|
|
|
struct device *device;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = -1;
|
|
|
|
device = (void *)&bdevice_section;
|
|
|
|
while ((uint32_t)&device[++i] < (uint32_t)&edevice_section)
|
|
|
|
{
|
|
|
|
if (device[i].major == major)
|
|
|
|
return (&device[i]);
|
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2020-01-10 17:21:44 +01:00
|
|
|
/* vfs_mknod - Create VFS inode (file, device special file, or pipe) named pathname */
|
2020-01-06 20:25:06 +01:00
|
|
|
int vfs_mknod(const char *pathname, mode_t mode, dev_t dev)
|
|
|
|
{
|
|
|
|
extern struct dentry *vfs_root_node;
|
|
|
|
struct dentry *parent_dentry;
|
|
|
|
struct device *device;
|
|
|
|
struct dentry *file;
|
|
|
|
char *name;
|
|
|
|
|
2020-01-10 17:21:44 +01:00
|
|
|
// Check device
|
|
|
|
// TODO: remove me !
|
|
|
|
if (dev == 0)
|
|
|
|
return (-2);
|
2020-01-06 20:25:06 +01:00
|
|
|
|
|
|
|
// Get parent dentry
|
2020-01-10 17:21:44 +01:00
|
|
|
parent_dentry = vfs_dentry_resolve(pathname, VFS_DENTRY_RESOLVE_FLAG_PATHNAME);
|
2020-01-06 20:25:06 +01:00
|
|
|
if (parent_dentry == NULL)
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
// Get folder name
|
|
|
|
name = strrchr(pathname, '/');
|
|
|
|
name = (name == NULL) ? (void *)pathname : &name[1];
|
|
|
|
|
2020-01-10 17:21:44 +01:00
|
|
|
// Try to find the device
|
|
|
|
// TODO: handle othe file (mode) !!!
|
2020-01-06 20:25:06 +01:00
|
|
|
device = device_get(dev_get_major(dev));
|
|
|
|
if (device == NULL)
|
|
|
|
return (-2);
|
|
|
|
|
|
|
|
// Tru to create empty node
|
|
|
|
file = vfs_dentry_alloc(name, mode | __S_IFCHR);
|
|
|
|
if (file == NULL)
|
|
|
|
return (-3);
|
2020-01-10 17:21:44 +01:00
|
|
|
|
2020-01-06 20:25:06 +01:00
|
|
|
|
|
|
|
// Try to open device
|
|
|
|
file->inode = device->open(dev_get_major(dev), dev_get_minor(dev));
|
|
|
|
if (file->inode == NULL)
|
|
|
|
return (-4);
|
2020-01-10 17:21:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
// Debug !
|
|
|
|
kvram_clear();
|
|
|
|
printk(0, 0, "New mknod device !");
|
|
|
|
printk(0, 1, "dentry: %p$", file);
|
|
|
|
printk(0, 2, "inode: %p$", file->inode);
|
|
|
|
printk(0, 3, "name: %s$", file->name);
|
|
|
|
printk(0, 4, "dev->file_op: %p$", &device->file_op);
|
|
|
|
kvram_display();
|
|
|
|
DBG_WAIT;
|
|
|
|
DBG_WAIT;
|
2020-01-06 20:25:06 +01:00
|
|
|
|
|
|
|
// Set file operations
|
|
|
|
file->dentry_op.file_op = &device->file_op;
|
|
|
|
|
|
|
|
// Add file into VFS
|
2020-01-10 17:21:44 +01:00
|
|
|
file->parent = parent_dentry;
|
2020-01-06 20:25:06 +01:00
|
|
|
file->next = parent_dentry->child;
|
|
|
|
parent_dentry->child = file;
|
|
|
|
return (0);
|
|
|
|
}
|