From a36758a5018f6a3792c164cd2a313d4f61b7111e Mon Sep 17 00:00:00 2001 From: Minep Date: Fri, 11 Nov 2022 23:45:51 +0000 Subject: [PATCH] feat: (vfs) write_page and read_page file operations fix: (iso9660) infinite loop when scanning iso9660 volume descriptors chore: clean up --- lunaix-os/includes/lunaix/common.h | 4 ++ lunaix-os/includes/lunaix/device.h | 2 + lunaix-os/includes/lunaix/fs.h | 10 ++++ lunaix-os/includes/lunaix/mm/page.h | 4 -- lunaix-os/kernel/block/block.c | 70 +++++++++++++++++++++++++ lunaix-os/kernel/device/devfs.c | 30 +++++++++++ lunaix-os/kernel/device/input.c | 7 +++ lunaix-os/kernel/fs/iso9660/directory.c | 6 ++- lunaix-os/kernel/fs/iso9660/inode.c | 2 + lunaix-os/kernel/fs/iso9660/mount.c | 8 +-- lunaix-os/kernel/fs/pcache.c | 10 ++-- lunaix-os/kernel/fs/ramfs/ramfs.c | 2 + lunaix-os/kernel/fs/twifs/twifs.c | 2 + lunaix-os/kernel/process/taskfs.c | 2 + lunaix-os/kernel/tty/lxconsole.c | 14 +++++ 15 files changed, 160 insertions(+), 13 deletions(-) diff --git a/lunaix-os/includes/lunaix/common.h b/lunaix-os/includes/lunaix/common.h index f5a24a7..1ebf158 100644 --- a/lunaix-os/includes/lunaix/common.h +++ b/lunaix-os/includes/lunaix/common.h @@ -1,6 +1,10 @@ #ifndef __LUNAIX_CONSTANTS_H #define __LUNAIX_CONSTANTS_H +#define PG_SIZE_BITS 12 +#define PG_SIZE (1 << PG_SIZE_BITS) +#define PG_INDEX_BITS 10 + #define MEM_1MB 0x100000 #define MEM_4MB 0x400000 diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index c456df4..fd234f0 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -30,6 +30,8 @@ struct device void* underlay; int (*read)(struct device* dev, void* buf, size_t offset, size_t len); int (*write)(struct device* dev, void* buf, size_t offset, size_t len); + int (*read_page)(struct device* dev, void* buf, size_t offset); + int (*write_page)(struct device* dev, void* buf, size_t offset); int (*exec_cmd)(struct device* dev, uint32_t req, va_list args); }; diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index f6a2e62..024b4ea 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -120,6 +120,16 @@ struct v_file_ops { int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos); int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos); + + // for operatiosn {write|read}_page, following are true: + // + `len` always equals to PG_SIZE + // + `fpos` always PG_SIZE aligned. + // These additional operations allow underlying fs to use more specialized + // and optimized code. + + int (*write_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos); + int (*read_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos); + int (*readdir)(struct v_file* file, struct dir_context* dctx); int (*seek)(struct v_inode* inode, size_t offset); // optional int (*close)(struct v_file* file); diff --git a/lunaix-os/includes/lunaix/mm/page.h b/lunaix-os/includes/lunaix/mm/page.h index 9458277..781a4ce 100644 --- a/lunaix-os/includes/lunaix/mm/page.h +++ b/lunaix-os/includes/lunaix/mm/page.h @@ -3,10 +3,6 @@ #include #include -#define PG_SIZE_BITS 12 -#define PG_SIZE (1 << PG_SIZE_BITS) -#define PG_INDEX_BITS 10 - #define PG_MAX_ENTRIES 1024U #define PG_LAST_TABLE PG_MAX_ENTRIES - 1 #define PG_FIRST_TABLE 0 diff --git a/lunaix-os/kernel/block/block.c b/lunaix-os/kernel/block/block.c index 6203fc7..1cade0c 100644 --- a/lunaix-os/kernel/block/block.c +++ b/lunaix-os/kernel/block/block.c @@ -140,6 +140,72 @@ __block_write(struct device* dev, void* buf, size_t offset, size_t len) return errno; } +int +__block_read_page(struct device* dev, void* buf, size_t offset) +{ + struct vecbuf* vbuf = NULL; + struct block_dev* bdev = (struct block_dev*)dev->underlay; + + u32_t lba = offset / bdev->blk_size + bdev->start_lba; + u32_t rd_lba = MIN(lba + PG_SIZE / bdev->blk_size, bdev->end_lba); + + if (rd_lba <= lba) { + return 0; + } + + rd_lba -= lba; + + vbuf_alloc(&vbuf, buf, rd_lba * bdev->blk_size); + + struct blkio_req* req = blkio_vrd(vbuf, lba, NULL, NULL, 0); + + blkio_commit(bdev->blkio, req, BLKIO_WAIT); + + int errno = req->errcode; + if (!errno) { + errno = rd_lba * bdev->blk_size; + } else { + errno = -errno; + } + + blkio_free_req(req); + vbuf_free(vbuf); + return errno; +} + +int +__block_write_page(struct device* dev, void* buf, size_t offset) +{ + struct vecbuf* vbuf = NULL; + struct block_dev* bdev = (struct block_dev*)dev->underlay; + + u32_t lba = offset / bdev->blk_size + bdev->start_lba; + u32_t rd_lba = MIN(lba + PG_SIZE / bdev->blk_size, bdev->end_lba); + + if (rd_lba <= lba) { + return 0; + } + + rd_lba -= lba; + + vbuf_alloc(&vbuf, buf, rd_lba * bdev->blk_size); + + struct blkio_req* req = blkio_vwr(vbuf, lba, NULL, NULL, 0); + + blkio_commit(bdev->blkio, req, BLKIO_WAIT); + + int errno = req->errcode; + if (!errno) { + errno = rd_lba * bdev->blk_size; + } else { + errno = -errno; + } + + blkio_free_req(req); + vbuf_free(vbuf); + return errno; +} + int __block_rd_lb(struct block_dev* bdev, void* buf, u64_t start, size_t count) { @@ -250,7 +316,9 @@ __block_register(struct block_dev* bdev) struct device* dev = device_addvol(NULL, bdev, "sd%c", 'a' + free_slot); dev->write = __block_write; + dev->write_page = __block_write_page; dev->read = __block_read; + dev->read_page = __block_read_page; bdev->dev = dev; strcpy(bdev->bdev_id, dev->name_val); @@ -271,7 +339,9 @@ blk_mount_part(struct block_dev* bdev, struct device* dev = device_addvol(NULL, pbdev, "%sp%d", bdev->bdev_id, index + 1); dev->write = __block_write; + dev->write_page = __block_write_page; dev->read = __block_read; + dev->read_page = __block_read_page; pbdev->start_lba = start_lba; pbdev->end_lba = end_lba; diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index 012f919..c265c4b 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -35,6 +35,34 @@ devfs_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos) return dev->write(dev, buffer, fpos, len); } +int +devfs_read_page(struct v_inode* inode, void* buffer, size_t len, size_t fpos) +{ + assert(inode->data); + + struct device* dev = (struct device*)inode->data; + + if (!dev->read_page) { + return ENOTSUP; + } + + return dev->read_page(dev, buffer, fpos); +} + +int +devfs_write_page(struct v_inode* inode, void* buffer, size_t len, size_t fpos) +{ + assert(inode->data); + + struct device* dev = (struct device*)inode->data; + + if (!dev->read_page) { + return ENOTSUP; + } + + return dev->read_page(dev, buffer, fpos); +} + int devfs_get_itype(struct device* dev) { @@ -157,6 +185,8 @@ struct v_inode_ops devfs_inode_ops = { .dir_lookup = devfs_dirlookup, struct v_file_ops devfs_file_ops = { .close = default_file_close, .read = devfs_read, + .read_page = devfs_read_page, .write = devfs_write, + .write_page = devfs_write_page, .seek = default_file_seek, .readdir = devfs_readdir }; \ No newline at end of file diff --git a/lunaix-os/kernel/device/input.c b/lunaix-os/kernel/device/input.c index 5ddf6a4..a96cb00 100644 --- a/lunaix-os/kernel/device/input.c +++ b/lunaix-os/kernel/device/input.c @@ -62,6 +62,12 @@ __input_dev_read(struct device* dev, void* buf, size_t offset, size_t len) return sizeof(struct input_evt_pkt); } +int +__input_dev_read_pg(struct device* dev, void* buf, size_t offset) +{ + return __input_dev_read(dev, buf, offset, PG_SIZE); +} + struct input_device* input_add_device(char* name_fmt, ...) { @@ -78,6 +84,7 @@ input_add_device(char* name_fmt, ...) idev->dev_if = dev; dev->read = __input_dev_read; + dev->read_page = __input_dev_read_pg; va_end(args); diff --git a/lunaix-os/kernel/fs/iso9660/directory.c b/lunaix-os/kernel/fs/iso9660/directory.c index 71244a9..816f6eb 100644 --- a/lunaix-os/kernel/fs/iso9660/directory.c +++ b/lunaix-os/kernel/fs/iso9660/directory.c @@ -21,8 +21,10 @@ iso9660_fill_drecache(struct iso_drecache* cache, struct iso_drecord* drec) u32_t l = drec->name.len; while (l < (u32_t)-1 && drec->name.content[l--] != ';') ; - l = (l + 1) ? l : drec->name.len; - l = MIN(l, ISO9660_IDLEN); + l++; + l = l ? l : drec->name.len; + l = MIN(l, ISO9660_IDLEN - 1); + strncpy(cache->name_val, drec->name.content, l); cache->name = HSTR(cache->name_val, l); hstr_rehash(&cache->name, HSTR_FULL_HASH); diff --git a/lunaix-os/kernel/fs/iso9660/inode.c b/lunaix-os/kernel/fs/iso9660/inode.c index 31f85ce..f88eee5 100644 --- a/lunaix-os/kernel/fs/iso9660/inode.c +++ b/lunaix-os/kernel/fs/iso9660/inode.c @@ -11,7 +11,9 @@ static struct v_inode_ops iso_inode_ops = { static struct v_file_ops iso_file_ops = { .close = iso9660_close, .read = iso9660_read, + .read_page = iso9660_read, .write = iso9660_write, + .write_page = iso9660_write, .seek = iso9660_seek, .readdir = iso9660_readdir }; diff --git a/lunaix-os/kernel/fs/iso9660/mount.c b/lunaix-os/kernel/fs/iso9660/mount.c index f6bb2fc..5d7bb81 100644 --- a/lunaix-os/kernel/fs/iso9660/mount.c +++ b/lunaix-os/kernel/fs/iso9660/mount.c @@ -24,9 +24,10 @@ 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; + u32_t lba = 16; int errno = 0; do { - errno = dev->read(dev, vdesc, ISO9660_BLKSZ * 16, ISO9660_BLKSZ); + errno = dev->read(dev, vdesc, ISO9660_BLKSZ * lba, ISO9660_BLKSZ); if (errno < 0) { errno = EIO; goto done; @@ -39,7 +40,7 @@ iso9660_mount(struct v_superblock* vsb, struct v_dnode* mount_point) vprim = (struct iso_vol_primary*)vdesc; break; } - + lba++; } while (vdesc->type != ISO_VOLTERM); if (!vprim) { @@ -81,10 +82,11 @@ iso9660_mount(struct v_superblock* vsb, struct v_dnode* mount_point) } vfs_i_addhash(rootino); + return 0; done: vfree(vdesc); - return 0; + return errno; } int diff --git a/lunaix-os/kernel/fs/pcache.c b/lunaix-os/kernel/fs/pcache.c index c27f78b..317e491 100644 --- a/lunaix-os/kernel/fs/pcache.c +++ b/lunaix-os/kernel/fs/pcache.c @@ -84,9 +84,10 @@ pcache_get_page(struct pcache* pcache, { struct pcache_pg* pg = btrie_get(&pcache->tree, index); int is_new = 0; - *offset = index & ((1 << pcache->tree.truncated) - 1); + u32_t mask = ((1 << pcache->tree.truncated) - 1); + *offset = index & mask; if (!pg && (pg = pcache_new_page(pcache, index))) { - pg->fpos = index - *offset; + pg->fpos = index & ~mask; pcache->n_pages++; is_new = 1; } @@ -137,7 +138,8 @@ pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos) } // Filling up the page - errno = inode->default_fops->read(inode, pg->pg, PG_SIZE, pg->fpos); + errno = + inode->default_fops->read_page(inode, pg->pg, PG_SIZE, pg->fpos); if (errno >= 0 && errno < PG_SIZE) { // EOF len = MIN(len, buf_off + errno); @@ -176,7 +178,7 @@ pcache_commit(struct v_inode* inode, struct pcache_pg* page) } int errno = - inode->default_fops->write(inode, page->pg, PG_SIZE, page->fpos); + inode->default_fops->write_page(inode, page->pg, PG_SIZE, page->fpos); if (!errno) { page->flags &= ~PCACHE_DIRTY; diff --git a/lunaix-os/kernel/fs/ramfs/ramfs.c b/lunaix-os/kernel/fs/ramfs/ramfs.c index f33d330..bcffa16 100644 --- a/lunaix-os/kernel/fs/ramfs/ramfs.c +++ b/lunaix-os/kernel/fs/ramfs/ramfs.c @@ -135,5 +135,7 @@ const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir, const struct v_file_ops ramfs_file_ops = { .readdir = ramfs_readdir, .close = default_file_close, .read = default_file_read, + .read_page = default_file_read, .write = default_file_write, + .write_page = default_file_write, .seek = default_file_seek }; \ No newline at end of file diff --git a/lunaix-os/kernel/fs/twifs/twifs.c b/lunaix-os/kernel/fs/twifs/twifs.c index 312c0a4..fcadafd 100644 --- a/lunaix-os/kernel/fs/twifs/twifs.c +++ b/lunaix-os/kernel/fs/twifs/twifs.c @@ -268,7 +268,9 @@ twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...) const struct v_file_ops twifs_file_ops = { .close = default_file_close, .read = __twifs_fread, + .read_page = __twifs_fread, .write = __twifs_fwrite, + .write_page = __twifs_fwrite, .readdir = __twifs_iterate_dir }; const struct v_inode_ops twifs_inode_ops = { .dir_lookup = __twifs_dirlookup, diff --git a/lunaix-os/kernel/process/taskfs.c b/lunaix-os/kernel/process/taskfs.c index 28c3713..7534703 100644 --- a/lunaix-os/kernel/process/taskfs.c +++ b/lunaix-os/kernel/process/taskfs.c @@ -133,7 +133,9 @@ taskfs_dirlookup(struct v_inode* this, struct v_dnode* dnode) static struct v_file_ops taskfs_file_ops = { .close = default_file_close, .read = default_file_read, + .read_page = default_file_read, .write = default_file_write, + .write_page = default_file_write, .readdir = taskfs_readdir, .seek = default_file_seek }; static struct v_inode_ops taskfs_inode_ops = { .dir_lookup = taskfs_dirlookup, diff --git a/lunaix-os/kernel/tty/lxconsole.c b/lunaix-os/kernel/tty/lxconsole.c index d555175..80a7be6 100644 --- a/lunaix-os/kernel/tty/lxconsole.c +++ b/lunaix-os/kernel/tty/lxconsole.c @@ -121,12 +121,26 @@ lxconsole_init() lx_console.flush_timer = NULL; } +int +__tty_write_pg(struct device* dev, void* buf, size_t offset) +{ + return __tty_write(dev, buf, offset, PG_SIZE); +} + +int +__tty_read_pg(struct device* dev, void* buf, size_t offset) +{ + return __tty_read(dev, buf, offset, PG_SIZE); +} + void lxconsole_spawn_ttydev() { struct device* tty_dev = device_addseq(NULL, &lx_console, "tty"); tty_dev->write = __tty_write; + tty_dev->write_page = __tty_write_pg; tty_dev->read = __tty_read; + tty_dev->read_page = __tty_read_pg; tty_dev->exec_cmd = __tty_exec_cmd; waitq_init(&lx_reader); -- 2.27.0