This commit is contained in:
d0p1 🏳️‍⚧️ 2024-07-27 10:57:23 +00:00
parent 45dfffc55a
commit 5186d32e63
4 changed files with 197 additions and 5 deletions

View file

@ -130,6 +130,9 @@ struct stpdfs_inode {
#define STPDFS_INODE_SIZE sizeof(struct inode)
# define STPDFS_NDIR 7 /**< Number of direct block */
# define STPDFS_SIND 7 /**< Indirect block */
# define STPDFS_DIND 8 /**< Double indirect */
# define STPDFS_TIND 9 /**< Triple indirect */
# define STPDFS_INO_FLAG_ALOC (1 << 15)
# define STPDFS_INO_FLAG_LZP (1 << 1)

View file

@ -1,15 +1,122 @@
#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)
struct stpdfs_inode_info icache[INODE_CACHE];
static struct stpdfs_inode_info icache[INODE_CACHE] = {0};
struct inode *
stpdfs_inode_get(struct stpdfs_sb *sb, uint32_t ino)
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)
{

View file

@ -12,9 +12,16 @@ struct stpdfs_super_info {
};
struct stpdfs_inode_info {
struct stpdfs_inode ino;
int fd;
int valid;
int refcount;
uint32_t inum;
struct stpdfs_super_info *sbi;
struct stpdfs_inode inode;
};
struct stpdfs_file {
};
struct stpdfs_buffer {
@ -40,6 +47,8 @@ void stpdfs_bpin(struct stpdfs_buffer *buff);
int stpdfs_read_super(struct stpdfs_super_info *sbi, int fd);
int stpdfs_super_validate(struct stpdfs_sb *sb);
int stpdfs_super_kill(struct stpdfs_super_info *sbi);
uint32_t stpdfs_super_balloc(struct stpdfs_super_info *sbi);
int stpdfs_super_bfreee(struct stpdfs_super_info *sbi, uint32_t blocknum);
uint32_t stpdfs_alloc_block(int fd, struct stpdfs_sb *sb);
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);

View file

@ -1,4 +1,6 @@
#include "stupidfs.h"
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
@ -70,7 +72,78 @@ stpdfs_super_kill(struct stpdfs_super_info *sbi)
stpdfs_bwrite(buff);
stpdfs_brelse(buff);
end:
close(sbi->fd);
return (0);
}
uint32_t
stpdfs_super_balloc(struct stpdfs_super_info *sbi)
{
uint32_t blocknum;
struct stpdfs_free freelist;
struct stpdfs_buffer *buff;
sbi->sb.state = STPDFS_DIRTY;
redo:
sbi->sb.freelist.nfree--;
blocknum = sbi->sb.freelist.free[sbi->sb.freelist.nfree];
if (sbi->sb.freelist.nfree == 0 && blocknum != 0)
{
buff = stpdfs_bread(sbi->fd, blocknum);
memcpy(&sbi->sb.freelist, buff->data, sizeof(struct stpdfs_free));
goto redo;
}
buff = stpdfs_bread(sbi->fd, 1);
memcpy(buff->data, &sbi->sb, sizeof(struct stpdfs_sb));
stpdfs_bwrite(buff);
buff = stpdfs_bread(sbi->fd, blocknum);
memset(buff->data, 0, STPDFS_BLOCK_SIZE);
stpdfs_bwrite(buff);
stpdfs_brelse(buff);
sbi->sb.time = time(NULL);
return (blocknum);
}
int
stpdfs_super_bfreee(struct stpdfs_super_info *sbi, uint32_t blocknum)
{
struct stpdfs_free copy;
struct stpdfs_buffer *buff;
if (blocknum == 0 || blocknum >= sbi->sb.fsize)
{
return (-1);
}
sbi->sb.state = STPDFS_DIRTY;
if (sbi->sb.freelist.nfree == 100)
{
buff = stpdfs_bread(sbi->fd, blocknum);
memcpy(buff->data, &sbi->sb.freelist, sizeof(struct stpdfs_free));
stpdfs_bwrite(buff);
stpdfs_brelse(buff);
sbi->sb.freelist.nfree = 1;
sbi->sb.freelist.free[0] = blocknum;
}
else
{
sbi->sb.freelist.free[sbi->sb.freelist.nfree++] = blocknum;
}
sbi->sb.time = time(NULL);
buff = stpdfs_bread(sbi->fd, 1);
memcpy(buff->data, &sbi->sb, sizeof(struct stpdfs_sb));
stpdfs_bwrite(buff);
return (0);
}