X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/7b8a1bcad75628f9add4590db2bb9b8e418ee8eb..0fd474df7001837bde53da0e42e83081827c9641:/lunaix-os/kernel/device/devfs.c diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index 350bbd6..969c828 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -65,47 +65,61 @@ devfs_write_page(struct v_inode* inode, void* buffer, size_t fpos) } int -devfs_get_itype(struct device_meta* dm) +devfs_get_itype(morph_t* obj) { - int itype = VFS_IFFILE; + int itype = VFS_IFDEV; - if (valid_device_subtype_ref(dm, DEV_CAT)) { + if (morph_type_of(obj, devcat_morpher)) { return VFS_IFDIR; } - struct device* dev = resolve_device(dm); - int dev_if = dev->dev_type & DEV_MSKIF; + struct device* dev = resolve_device(obj); + + if (!dev) { + return itype; + } + int dev_if = dev->dev_type & DEV_MSKIF; if (dev_if == DEV_IFVOL) { itype |= VFS_IFVOLDEV; - } else if (dev_if == DEV_IFSEQ) { - itype |= VFS_IFSEQDEV; - } else { - itype |= VFS_IFDEV; } + + // otherwise, the mapping is considered to be generic seq dev. return itype; } -int -devfs_get_dtype(struct device_meta* dev) +static inline int +devfs_get_dtype(morph_t* dev_morph) { - if (valid_device_subtype_ref(dev, DEV_CAT)) { + if (morph_type_of(dev_morph, devcat_morpher)) { return DT_DIR; } return DT_FILE; } +static inline morph_t* +__try_resolve(struct v_inode* inode) +{ + if (!inode->data) { + return dev_object_root; + } + + return resolve_device_morph(inode->data); +} + int -devfs_mknod(struct v_dnode* dnode, struct device_meta* dev) +devfs_mknod(struct v_dnode* dnode, morph_t* obj) { - assert(dev); + struct v_inode* devnod; + + assert(obj); - struct v_inode* devnod = vfs_i_find(dnode->super_block, dev->dev_uid); + devnod = vfs_i_find(dnode->super_block, morpher_uid(obj)); if (!devnod) { if ((devnod = vfs_i_alloc(dnode->super_block))) { - devnod->id = dev->dev_uid; - devnod->data = dev; - devnod->itype = devfs_get_itype(dev); + devnod->id = morpher_uid(obj); + devnod->data = changeling_ref(obj); + devnod->itype = devfs_get_itype(obj); vfs_i_addhash(devnod); } else { @@ -120,42 +134,43 @@ devfs_mknod(struct v_dnode* dnode, struct device_meta* dev) int devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode) { - void* data = this->data; - struct device_meta* rootdev = resolve_device_meta(data); + morph_t *mobj, *root; - if (data && !rootdev) { + root = __try_resolve(this); + if (!root) { return ENOTDIR; } - struct device_meta* dev = - device_getbyhname(rootdev, &dnode->name); - - if (!dev) { + mobj = changeling_find(root, &dnode->name); + if (!mobj) { return ENOENT; } - return devfs_mknod(dnode, dev); + return devfs_mknod(dnode, mobj); } int devfs_readdir(struct v_file* file, struct dir_context* dctx) { - void* data = file->inode->data; - struct device_meta* rootdev = resolve_device_meta(data); + morph_t *mobj, *root; - if (data && !rootdev) { + root = __try_resolve(file->inode); + if (!root) { return ENOTDIR; } - struct device_meta* dev = - device_getbyoffset(rootdev, dctx->index); - - if (!dev) { + if (fsapi_handle_pseudo_dirent(file, dctx)) { + return 1; + } + + mobj = changeling_get_at(root, file->f_pos - 2); + if (!mobj) { return 0; } - dctx->read_complete_callback( - dctx, dev->name.value, dev->name.len, devfs_get_dtype(dev)); + dctx->read_complete_callback(dctx, + mobj->name.value, mobj->name.len, + devfs_get_dtype(mobj)); return 1; } @@ -164,6 +179,12 @@ devfs_init_inode(struct v_superblock* vsb, struct v_inode* inode) { inode->ops = &devfs_inode_ops; inode->default_fops = &devfs_file_ops; + + // we set default access right to be 0775. + // TODO need a way to allow this to be changed + + fsapi_inode_setaccess(inode, FSACL_DEFAULT); + fsapi_inode_setowner(inode, 0, 0); } int @@ -195,10 +216,11 @@ devfs_unmount(struct v_superblock* vsb) void devfs_init() { - struct filesystem* fs = fsm_new_fs("devfs", 5); - fsm_register(fs); - fs->mount = devfs_mount; - fs->unmount = devfs_unmount; + struct filesystem* fs; + fs = fsapi_fs_declare("devfs", FSTYPE_PSEUDO); + + fsapi_fs_set_mntops(fs, devfs_mount, devfs_unmount); + fsapi_fs_finalise(fs); } EXPORT_FILE_SYSTEM(devfs, devfs_init);