return 0;
}
+ struct iso_inode* isoino = inode->data;
+ if (!llist_empty(&isoino->drecaches)) {
+ dnode->data = &isoino->drecaches;
+ vfs_assign_inode(dnode, inode);
+ return 0;
+ }
+
int errno = 0;
struct device* dev = dnode->super_block->dev;
- struct iso_inode* isoino = inode->data;
- struct llist_header* lead = valloc(sizeof(*lead));
void* records = valloc(ISO9660_BLKSZ);
u32_t current_pos = -ISO9660_BLKSZ, max_pos = inode->fsize,
blk = inode->lb_addr * ISO9660_BLKSZ, blk_offset = (u32_t)-1;
- llist_init_head(lead);
-
// As per 6.8.1, Directory structure shall NOT recorded in interleave mode.
do {
if (blk_offset >= ISO9660_BLKSZ - sizeof(struct iso_drecord)) {
struct iso_drecache* cache = cake_grab(drec_cache_pile);
iso9660_fill_drecache(cache, drec, mdu->len);
- llist_append(lead, &cache->caches);
+ llist_append(&isoino->drecaches, &cache->caches);
cont:
blk_offset += mdu->len;
} while (current_pos + blk_offset < max_pos);
- dnode->data = lead;
- isoino->drecaches = lead;
+ dnode->data = &isoino->drecaches;
vfs_assign_inode(dnode, inode);
iso9660_dir_lookup(struct v_inode* this, struct v_dnode* dnode)
{
struct iso_inode* isoino = this->data;
- struct llist_header* lead = isoino->drecaches;
struct iso_drecache *pos, *n;
- llist_for_each(pos, n, lead, caches)
+ llist_for_each(pos, n, &isoino->drecaches, caches)
{
if (HSTR_EQ(&dnode->name, &pos->name)) {
goto found;
#include <klibc/string.h>
#include <lunaix/fs.h>
#include <lunaix/fs/iso9660.h>
+#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/spike.h>
+extern struct cake_pile* drec_cache_pile;
+
static struct v_inode_ops iso_inode_ops = {
.dir_lookup = iso9660_dir_lookup,
.open = iso9660_open,
.seek = iso9660_seek,
.readdir = iso9660_readdir };
+void
+iso9660_inode_destruct(struct v_inode* inode)
+{
+ struct iso_inode* isoino = inode->data;
+
+ struct iso_drecache *pos, *n;
+ llist_for_each(pos, n, &isoino->drecaches, caches)
+ {
+ cake_release(drec_cache_pile, pos);
+ }
+
+ vfree(isoino);
+}
+
void
iso9660_init_inode(struct v_superblock* vsb, struct v_inode* inode)
{
- inode->data = vzalloc(sizeof(struct iso_inode));
+ struct iso_inode* isoino = vzalloc(sizeof(struct iso_inode));
+ llist_init_head(&isoino->drecaches);
+ inode->data = isoino;
+ inode->destruct = iso9660_inode_destruct;
}
int
pcache_release(inode->pg_cache);
vfree(inode->pg_cache);
}
- inode->ops->sync(inode);
+ // we don't need to sync inode.
+ // If an inode can be free, then it must be properly closed.
+ // Hence it must be synced already!
+ if (inode->destruct) {
+ inode->destruct(inode);
+ }
hlist_delete(&inode->hash_list);
cake_release(inode_pile, inode);
}