124 lines
No EOL
2.6 KiB
C
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);
|
|
} |