refactor: move libstpdf to libfs (WIP)

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-08-08 16:06:00 +02:00
parent 806b71237e
commit 3f68ab8263
16 changed files with 659 additions and 2 deletions

View file

@ -1,4 +1,4 @@
SUBDIRS = libstpdfs libcrypto liblzp tools SUBDIRS = libstpdfs libcrypto liblzp libfs tools
if BUILD_FUSE if BUILD_FUSE
SUBDIRS += fuse SUBDIRS += fuse

View file

@ -47,12 +47,12 @@ AC_CHECK_FUNCS(m4_normalize([
])) ]))
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
lib/Makefile
libcrypto/Makefile libcrypto/Makefile
libcrypto/tests/Makefile libcrypto/tests/Makefile
liblzp/Makefile liblzp/Makefile
liblzp/tests/Makefile liblzp/tests/Makefile
libstpdfs/Makefile libstpdfs/Makefile
libfs/Makefile
tools/Makefile tools/Makefile
linux/Makefile linux/Makefile
fuse/Makefile]) fuse/Makefile])

3
libfs/Makefile.am Normal file
View file

@ -0,0 +1,3 @@
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)
noinst_LIBRARIES = libfs.a
libfs_a_SOURCES = bio/raw.c bio/bio.c balloc.c dir.c inode.c rw.c super.c

77
libfs/balloc.c Normal file
View file

@ -0,0 +1,77 @@
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <stupidfs.h>
#include "super.h"
#include "bio/bio.h"
uint32_t
fs_balloc(struct fs_super *super)
{
uint32_t blocknum;
struct stpdfs_free freelist;
struct fs_buffer *buff;
super->sb.state = STPDFS_DIRTY;
redo:
super->sb.freelist.nfree--;
blocknum = super->sb.freelist.free[super->sb.freelist.nfree];
if (super->sb.freelist.nfree == 0 && blocknum != 0)
{
buff = fs_bio_bread(super->fd, blocknum);
memcpy(&super->sb.freelist, buff->data, sizeof(struct stpdfs_free));
goto redo;
}
super->sb.time = time(NULL);
buff = fs_bio_bread(super->fd, STPDFS_SB_BLOCK);
memcpy(buff->data, &super->sb, sizeof(struct stpdfs_sb));
fs_bio_bwrite(buff);
fs_bio_brelse(buff);
buff = fs_bio_bread(super->fd, blocknum);
memset(buff->data, 0, STPDFS_BLOCK_SIZE);
fs_bio_bwrite(buff);
fs_bio_brelse(buff);
return (blocknum);
}
int
fs_bfree(struct fs_super *super, uint32_t blocknum)
{
struct stpdfs_free copy;
struct fs_buffer *buff;
if (blocknum == 0 || blocknum >= super->sb.fsize)
{
return (-1);
}
super->sb.state = STPDFS_DIRTY;
if (super->sb.freelist.nfree == 100)
{
buff = fs_bio_bread(super->fd, blocknum);
memcpy(buff->data, &super->sb.freelist, sizeof(struct stpdfs_free));
fs_bio_bwrite(buff);
fs_bio_brelse(buff);
super->sb.freelist.nfree = 1;
super->sb.freelist.free[0] = blocknum;
}
else
{
super->sb.freelist.free[super->sb.freelist.nfree++] = blocknum;
}
super->sb.time = time(NULL);
buff = fs_bio_bread(super->fd, STPDFS_SB_BLOCK);
memcpy(buff->data, &super->sb, sizeof(struct stpdfs_sb));
fs_bio_bwrite(buff);
fs_bio_brelse(buff);
return (0);
}

102
libfs/bio/bio.c Normal file
View file

@ -0,0 +1,102 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include "bio.h"
static struct fs_buffer *head = NULL;
static struct fs_buffer *
bget(int fd, uint32_t blocknum)
{
struct fs_buffer *buff;
for (buff = head; buff != NULL; buff = buff->next)
{
if (buff->blocknum == blocknum)
{
buff->refcount++;
return (buff);
}
}
buff = (struct fs_buffer *)malloc(sizeof(struct fs_buffer));
if (buff == NULL) return (NULL);
buff->next = head;
buff->blocknum = blocknum;
buff->valid = 0;
buff->refcount = 1;
buff->fd = fd;
head = buff;
return (buff);
}
struct fs_buffer *
fs_bio_bread(int fd, uint32_t blocknum)
{
struct fs_buffer *buff;
buff = bget(fd, blocknum);
if (buff == NULL)
{
return (NULL);
}
if (buff->valid == 0)
{
fs_bio_raw_read(fd, blocknum, buff->data, STPDFS_BLOCK_SIZE);
buff->valid = 1;
}
return (buff);
}
void
fs_bio_bwrite(struct fs_buffer *buff)
{
fs_bio_raw_read(buff->fd, buff->blocknum, buff->data, STPDFS_BLOCK_SIZE);
}
void
fs_bio_brelse(struct fs_buffer *buff)
{
struct fs_buffer *tmp;
buff->refcount--;
if (buff->refcount > 0) return;
if (buff == head)
{
head = buff->next;
}
else
{
for (tmp = head; tmp != NULL; tmp = tmp->next)
{
if (tmp->next == buff)
{
tmp->next = buff->next;
break;
}
}
}
free(buff);
}
void
stpdfs_bpin(struct fs_buffer *buff)
{
buff->refcount++;
}
void
stpdfs_bunpin(struct fs_buffer *buff)
{
buff->refcount--;
}

25
libfs/bio/bio.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef FS_BIO_H
# define FS_BIO_H 1
# include <stdint.h>
# include <stupidfs.h>
struct fs_buffer {
int valid;
uint32_t blocknum;
int refcount;
int fd;
struct fs_buffer *next;
uint8_t data[STPDFS_BLOCK_SIZE];
};
size_t fs_bio_raw_write(int fd, uint32_t blocknum, void *data, size_t size);
size_t fs_bio_raw_read(int fd, uint32_t blocknum, void *data, size_t size);
struct fs_buffer *fs_bio_bread(int fd, uint32_t blocknum);
void fs_bio_brelse(struct fs_buffer *buff);
void fs_bio_bwrite(struct fs_buffer *buff);
#endif /* !FS_BIO_H */

35
libfs/bio/raw.c Normal file
View file

@ -0,0 +1,35 @@
#include <stdint.h>
#include <unistd.h>
#include <stupidfs.h>
size_t
fs_bio_raw_write(int fd, uint32_t blocknum, void *data, size_t size)
{
if (size > STPDFS_BLOCK_SIZE)
{
return (-1);
}
if (lseek(fd, blocknum * STPDFS_BLOCK_SIZE, SEEK_SET) == -1)
{
return (-1);
}
return (write(fd, data, size));
}
size_t
fs_bio_raw_read(int fd, uint32_t blocknum, void *data, size_t size)
{
if (size > STPDFS_BLOCK_SIZE)
{
return (-1);
}
if (lseek(fd, blocknum * STPDFS_BLOCK_SIZE, SEEK_SET) == -1)
{
return (-1);
}
return (read(fd, data, size));
}

34
libfs/dir.c Normal file
View file

@ -0,0 +1,34 @@
#include "inode.h"
#include "fs.h"
#include "stupidfs.h"
#include <errno.h>
#include <stdint.h>
#include <string.h>
struct fs_inode *
fs_dir_lookup(struct fs_inode *dp, const char *name, size_t *offset)
{
size_t idx;
struct stpdfs_dirent dirent;
if (!(dp->inode.flags & STPDFS_S_IFDIR))
{
errno = ENOTDIR;
return (NULL);
}
for (idx = 0; idx < dp->inode.size; idx += STPDFS_DIRENT_SIZE)
{
fs_read(dp, (uint8_t *)&dirent, idx, STPDFS_DIRENT_SIZE);
if (dirent.inode == 0) continue;
if (strncmp(name, dirent.filename, STPDFS_NAME_MAX))
{
if (offset) *offset = idx;
return (fs_inode_get(dp->super, dirent.inode));
}
}
return (NULL);
}

15
libfs/dir.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef FS_DIR_H
# define FS_DIR_H 1
# include <stupidfs.h>
struct fs_dir {
char name[STPDFS_NAME_MAX];
uint32_t inum;
};
#endif /* !FS_DIR_H */

14
libfs/file.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef FS_FILE_H
# define FS_FILE_H 1
# include "inode.h"
struct fs_file {
int refcount;
struct fs_inode *ip;
struct fs_file *next;
};
#endif /* !FS_FILE_H */

13
libfs/fs.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef FS_H
# define FS_H 1
# include <stdint.h>
# include "super.h"
# include "inode.h"
uint32_t fs_balloc(struct fs_super *super);
int fs_bfree(struct fs_super *super, uint32_t blocknum);
int fs_read(struct fs_inode *ip, uint8_t *dest, size_t offset, size_t size);
#endif /* !FS_H */

100
libfs/inode.c Normal file
View file

@ -0,0 +1,100 @@
#include <stdlib.h>
#include <string.h>
#include "inode.h"
#include "bio/bio.h"
#include "stupidfs.h"
#define IBLOCK(x) (x / STPDFS_INODES_PER_BLOCK + 2)
static struct fs_inode *head;
struct fs_inode *
fs_inode_get(struct fs_super *super, uint32_t inum)
{
struct fs_inode *ip;
for (ip = head; ip != NULL; ip = ip->next)
{
if (ip->inum == inum)
{
ip->refcount++;
return (ip);
}
}
ip = (struct fs_inode *)malloc(sizeof(struct fs_inode));
if (ip == NULL) return (NULL);
ip->super = super;
ip->inum = 0;
ip->refcount = 1;
ip->valid = 0;
return (ip);
}
struct fs_inode *
fs_inode_read(struct fs_inode *ip)
{
struct fs_buffer *buff;
struct stpdfs_inode *dinode;
if (ip == NULL) return (NULL);
buff = fs_bio_bread(ip->super->fd, IBLOCK(ip->inum));
if (buff == NULL) return (NULL);
dinode = (struct stpdfs_inode *)buff->data;
memcpy(&ip->inode, dinode, sizeof(struct stpdfs_inode));
fs_bio_brelse(buff);
ip->valid = 1;
return (ip);
}
int
fs_inode_update(struct fs_inode *ip)
{
struct fs_buffer *buff;
struct stpdfs_inode *dinode;
buff = fs_bio_bread(ip->super->fd, IBLOCK(ip->inum));
if (buff == NULL) return (-1);
dinode = (struct stpdfs_inode *)buff->data + ip->inum % STPDFS_INODES_PER_BLOCK;
memcpy(dinode, &ip->inode, sizeof(struct stpdfs_inode));
fs_bio_bwrite(buff);
fs_bio_brelse(buff);
return (0);
}
void
fs_inode_release(struct fs_inode *ip)
{
struct fs_inode *tmp;
ip->refcount--;
if (ip->refcount > 0) return;
if (ip == head)
{
head = ip->next;
}
else
{
for (tmp = head; tmp != NULL; tmp = tmp->next)
{
if (tmp->next == tmp)
{
tmp->next = ip->next;
break;
}
}
}
free(ip);
}

23
libfs/inode.h Normal file
View file

@ -0,0 +1,23 @@
#ifndef FS_INODE_H
# define FS_INODE_H 1
# include <stdint.h>
# include <stupidfs.h>
# include "super.h"
struct fs_inode {
int valid;
uint32_t inum;
int refcount;
struct fs_super *super;
struct stpdfs_inode inode;
struct fs_inode *next;
};
struct fs_inode *fs_inode_get(struct fs_super *super, uint32_t inum);
int fs_inode_update(struct fs_inode *ip);
#endif /* !FS_INODE_H */

122
libfs/rw.c Normal file
View file

@ -0,0 +1,122 @@
#include <stdint.h>
#include <string.h>
#include <stupidfs.h>
#include "fs.h"
#include "bio/bio.h"
#ifndef MIN
# define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif /* !MIN */
static int
bmap(struct fs_inode *ip, uint32_t blocknum)
{
uint32_t *addrs;
uint32_t index;
struct fs_buffer *buff;
if (blocknum < STPDFS_NDIR)
{
if (ip->inode.zones[blocknum] == 0)
{
ip->inode.zones[blocknum] = fs_balloc(ip->super);
}
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] = fs_balloc(ip->super);
}
buff = fs_bio_bread(ip->super->fd, ip->inode.zones[STPDFS_SIND]);
addrs = (uint32_t *)buff->data;
if (addrs[index] == 0)
{
addrs[index] = fs_balloc(ip->super);
}
fs_bio_brelse(buff);
return (addrs[index]);
}
/* TODO double and triple ind */
return (0);
}
int
fs_read(struct fs_inode *ip, uint8_t *dest, size_t offset, size_t size)
{
size_t total;
size_t rd;
uint32_t zone;
struct fs_buffer *buff;
if (offset > ip->inode.size)
{
return (0);
}
total = 0;
while (total < size)
{
zone = bmap(ip, offset/STPDFS_BLOCK_SIZE);
if (zone == 0) return (total);
buff = fs_bio_bread(ip->super->fd, zone);
rd = MIN(size - total, STPDFS_BLOCK_SIZE - offset % STPDFS_BLOCK_SIZE);
memcpy(dest, buff->data + (offset % STPDFS_BLOCK_SIZE), rd);
fs_bio_brelse(buff);
total += rd;
offset += rd;
dest += rd;
}
return (total);
}
int
fs_write(struct fs_inode *ip, const uint8_t *src, size_t offset, size_t size)
{
size_t total;
size_t rd;
uint32_t zone;
struct fs_buffer *buff;
if (offset > ip->inode.size)
{
return (0);
}
total = 0;
while (total < size)
{
zone = bmap(ip, offset/STPDFS_BLOCK_SIZE);
if (zone == 0) break;
buff = fs_bio_bread(ip->super->fd, zone);
rd = MIN(size - total, STPDFS_BLOCK_SIZE - offset % STPDFS_BLOCK_SIZE);
memcpy(buff->data + (offset % STPDFS_BLOCK_SIZE), src, rd);
fs_bio_bwrite(buff);
fs_bio_brelse(buff);
total += rd;
offset += rd;
src += rd;
}
if (offset > ip->inode.size)
{
ip->inode.size = offset;
}
fs_inode_update(ip);
return (total);
}

82
libfs/super.c Normal file
View file

@ -0,0 +1,82 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stupidfs.h>
#include "super.h"
#include "bio/bio.h"
int
fs_super_valide(struct stpdfs_sb *sb)
{
if (sb->magic != STPDFS_SB_MAGIC)
{
return (-1);
}
if (sb->revision != STPDFS_SB_REV)
{
return (-1);
}
if (sb->fsize == 0 || sb->isize == 0)
{
return (-1);
}
if (sb->isize > sb->fsize)
{
return (-1);
}
return (0);
}
int
fs_super_open(struct fs_super *super, const char *fname)
{
struct fs_buffer *buff;
super->fd = open(fname, O_RDWR);
if (super->fd < 0)
{
perror(fname);
return (-1);
}
buff = fs_bio_bread(super->fd, STPDFS_SB_BLOCK);
if (!buff) goto err;
memcpy(&super->sb, buff->data, sizeof(struct stpdfs_sb));
if (fs_super_valide(&super->sb) != 0) goto err;
return (0);
err:
close(super->fd);
return (-1);
}
int
fs_super_kill(struct fs_super *super)
{
struct fs_buffer *buff;
int ret;
ret = 0;
buff = fs_bio_bread(super->fd, STPDFS_SB_BLOCK);
if (buff == NULL)
{
ret = 1;
goto end;
}
memcpy(buff->data, &super->sb, sizeof(struct stpdfs_sb));
fs_bio_bwrite(buff);
fs_bio_brelse(buff);
end:
close(super->fd);
return (ret);
}

12
libfs/super.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef FS_SUPER_H
# define FS_SUPER_H 1
# include <stdint.h>
# include <stupidfs.h>
struct fs_super {
int fd;
struct stpdfs_sb sb;
};
#endif /* !FS_SUPER_H */