StupidFS/libstpdfs/inode.c
2024-07-27 10:57:23 +00:00

124 lines
No EOL
2.6 KiB
C

#include "stpdfs.h"
#include "stupidfs.h"
#include <libstpdfs/stpdfs.h>
#include <stdint.h>
#include <string.h>
#define INODE_CACHE 50
#define IBLOCK(x) (x / STPDFS_INODES_PER_BLOCK + 2)
static struct stpdfs_inode_info icache[INODE_CACHE] = {0};
struct stpdfs_inode_info *
stpdfs_inode_get(struct stpdfs_super_info *sbi, uint32_t inum)
{
struct stpdfs_inode_info *empty;
int idx;
empty = NULL;
for (idx = 0; idx < INODE_CACHE; idx++)
{
if (icache[idx].refcount > 0 && icache[idx].inum == inum)
{
icache[idx].refcount++;
return (&icache[idx]);
}
if (empty == NULL && icache[idx].refcount == 0)
{
empty = &icache[idx];
}
}
if (empty == NULL) return (NULL);
empty->sbi = sbi;
empty->inum = inum;
empty->refcount = 1;
empty->valid = 0;
return (empty);
}
struct stpdfs_inode_info *
stpdfs_inode_alloc(struct stpdfs_super_info *sbi)
{
uint32_t inum;
struct stpdfs_buffer *buff;
struct stpdfs_inode *dinode;
for (inum = 1; inum < sbi->sb.isize; inum++)
{
buff = stpdfs_bread(sbi->fd, IBLOCK(inum));
dinode = (struct stpdfs_inode *)buff->data + inum % STPDFS_INODES_PER_BLOCK;
if ((dinode->flags & STPDFS_INO_FLAG_ALOC) == 0)
{
dinode->flags = STPDFS_INO_FLAG_ALOC;
stpdfs_bwrite(buff);
stpdfs_brelse(buff);
return (stpdfs_inode_get(sbi, inum));
}
stpdfs_brelse(buff);
}
return (NULL);
}
void
stpdfs_inode_update(struct stpdfs_inode_info *ip)
{
struct stpdfs_buffer *buff;
struct stpdfs_inode *dinode;
buff = stpdfs_bread(ip->sbi->fd, IBLOCK(ip->inum));
dinode = (struct stpdfs_inode *)buff->data + ip->inum % STPDFS_INODES_PER_BLOCK;
memcpy(dinode, &ip->inode, sizeof(struct stpdfs_inode));
stpdfs_bwrite(buff);
stpdfs_brelse(buff);
}
int
stpdfs_inode_bmap(struct stpdfs_inode_info *ip, uint32_t blocknum)
{
uint32_t *addrs;
uint32_t index;
struct stpdfs_buffer *buff;
if (blocknum < STPDFS_NDIR)
{
if (ip->inode.zones[blocknum] == 0)
{
ip->inode.zones[blocknum] = stpdfs_super_balloc(ip->sbi);
}
return (ip->inode.zones[blocknum]);
}
index = blocknum - STPDFS_NDIR;
if (blocknum < (STPDFS_BLOCK_SIZE/sizeof(int32_t) + STPDFS_SIND))
{
if (ip->inode.zones[STPDFS_SIND] == 0)
{
ip->inode.zones[STPDFS_SIND] = stpdfs_super_balloc(ip->sbi);
}
buff = stpdfs_bread(ip->sbi->fd, ip->inode.zones[STPDFS_SIND]);
addrs = (uint32_t *)buff->data;
if (addrs[index] == 0)
{
addrs[index] = stpdfs_super_balloc(ip->sbi);
}
stpdfs_brelse(buff);
return (addrs[index]);
}
/* TODO double and triple ind */
return (0);
}
struct stpdfs_dirent *
stpdfs_lookup(struct stpdfs_inode *dir, struct stpdfs_dirent *dentry, int flags)
{
return (NULL);
}