wip
This commit is contained in:
parent
45dfffc55a
commit
5186d32e63
|
@ -130,6 +130,9 @@ struct stpdfs_inode {
|
||||||
#define STPDFS_INODE_SIZE sizeof(struct inode)
|
#define STPDFS_INODE_SIZE sizeof(struct inode)
|
||||||
|
|
||||||
# define STPDFS_NDIR 7 /**< Number of direct block */
|
# 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_ALOC (1 << 15)
|
||||||
# define STPDFS_INO_FLAG_LZP (1 << 1)
|
# define STPDFS_INO_FLAG_LZP (1 << 1)
|
||||||
|
|
|
@ -1,15 +1,122 @@
|
||||||
|
#include "stpdfs.h"
|
||||||
|
#include "stupidfs.h"
|
||||||
#include <libstpdfs/stpdfs.h>
|
#include <libstpdfs/stpdfs.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define INODE_CACHE 50
|
#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 *
|
struct stpdfs_inode_info *
|
||||||
stpdfs_inode_get(struct stpdfs_sb *sb, uint32_t ino)
|
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);
|
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 *
|
struct stpdfs_dirent *
|
||||||
stpdfs_lookup(struct stpdfs_inode *dir, struct stpdfs_dirent *dentry, int flags)
|
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_info {
|
||||||
struct stpdfs_inode ino;
|
int valid;
|
||||||
int fd;
|
|
||||||
int refcount;
|
int refcount;
|
||||||
|
uint32_t inum;
|
||||||
|
struct stpdfs_super_info *sbi;
|
||||||
|
|
||||||
|
struct stpdfs_inode inode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stpdfs_file {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stpdfs_buffer {
|
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_read_super(struct stpdfs_super_info *sbi, int fd);
|
||||||
int stpdfs_super_validate(struct stpdfs_sb *sb);
|
int stpdfs_super_validate(struct stpdfs_sb *sb);
|
||||||
int stpdfs_super_kill(struct stpdfs_super_info *sbi);
|
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);
|
uint32_t stpdfs_alloc_block(int fd, struct stpdfs_sb *sb);
|
||||||
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
|
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
#include "stupidfs.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -70,7 +72,78 @@ stpdfs_super_kill(struct stpdfs_super_info *sbi)
|
||||||
stpdfs_bwrite(buff);
|
stpdfs_bwrite(buff);
|
||||||
|
|
||||||
stpdfs_brelse(buff);
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
close(sbi->fd);
|
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