X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/df1e857ac4d1410ae2bd354e361210b842ab7bc8..c6de44b989e9d7286337e4cbf4d82d919f9120e6:/lunaix-os/kernel/fs/iso9660/mount.c diff --git a/lunaix-os/kernel/fs/iso9660/mount.c b/lunaix-os/kernel/fs/iso9660/mount.c new file mode 100644 index 0000000..f6bb2fc --- /dev/null +++ b/lunaix-os/kernel/fs/iso9660/mount.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include + +#include + +struct cake_pile* drec_cache_pile; + +extern void +iso9660_init_inode(struct v_superblock* vsb, struct v_inode* inode); + +uint32_t +iso9660_rd_capacity(struct v_superblock* vsb) +{ + struct iso_superblock* isovsb = (struct iso_superblock*)vsb->data; + return isovsb->volume_size; +} + +int +iso9660_mount(struct v_superblock* vsb, struct v_dnode* mount_point) +{ + struct device* dev = vsb->dev; + struct iso_vol* vdesc = (struct iso_vol*)valloc(ISO9660_BLKSZ); + struct iso_vol_primary* vprim = NULL; + int errno = 0; + do { + errno = dev->read(dev, vdesc, ISO9660_BLKSZ * 16, ISO9660_BLKSZ); + if (errno < 0) { + errno = EIO; + goto done; + } + if (*(u32_t*)vdesc->std_id != ISO_SIGNATURE_LO) { + errno = ENODEV; + goto done; + } + if (vdesc->type == ISO_VOLPRIM) { + vprim = (struct iso_vol_primary*)vdesc; + break; + } + + } while (vdesc->type != ISO_VOLTERM); + + if (!vprim) { + errno = EINVAL; + goto done; + } + + struct iso_superblock* isovsb = valloc(sizeof(*isovsb)); + isovsb->lb_size = vprim->lb_size.le; + isovsb->volume_size = vprim->vol_size.le * isovsb->lb_size; + + vsb->data = isovsb; + vsb->ops.init_inode = iso9660_init_inode; + vsb->ops.read_capacity = iso9660_rd_capacity; + + struct v_inode* rootino = vfs_i_alloc(vsb); + struct iso_drecord* dir = + iso9660_get_drecord((struct iso_var_mdu*)vprim->root_record); + + if (!dir) { + vfree(isovsb); + errno = EINVAL; + goto done; + } + + struct iso_drecache drecache; + iso9660_fill_drecache(&drecache, dir); + + if ((errno = iso9660_fill_inode(rootino, &drecache, 0)) < 0) { + vfree(isovsb); + errno = EINVAL; + goto done; + } + + if ((errno = iso9660_setup_dnode(mount_point, rootino)) < 0) { + vfree(isovsb); + errno = EINVAL; + goto done; + } + + vfs_i_addhash(rootino); + +done: + vfree(vdesc); + return 0; +} + +int +iso9660_unmount(struct v_superblock* vsb) +{ + // TODO clean up +} + +void +iso9660_init() +{ + drec_cache_pile = + cake_new_pile("iso_drec", sizeof(struct iso_drecache), 1, 0); + + struct filesystem* fs = fsm_new_fs("iso9660", -1); + fs->types |= FSTYPE_ROFS; + fs->mount = iso9660_mount; + fs->unmount = iso9660_unmount; + + fsm_register(fs); +} \ No newline at end of file