Compare commits
1 commit
7043ece1c3
...
5186d32e63
Author | SHA1 | Date | |
---|---|---|---|
d0p1 🏳️⚧️ | 5186d32e63 |
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in a new issue