feat(lib): read superblock

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-06-13 10:34:08 +02:00
parent 9a8950c304
commit ba62e6aaac
11 changed files with 254 additions and 90 deletions

2
.gitignore vendored
View file

@ -31,3 +31,5 @@ Debug/
html/ html/
.dirstamp .dirstamp
mkfs.stpd mkfs.stpd
*.gz
*.pdf

View file

@ -2417,7 +2417,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and # the macro expansion is limited to the macros specified with the PREDEFINED and
@ -2425,7 +2425,7 @@ MACRO_EXPANSION = NO
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = NO EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES, the include files in the # If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found. # INCLUDE_PATH will be searched if a #include is found.
@ -2458,8 +2458,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = PREDEFINED = __attribute__(x)=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The # tag can be used to specify a list of macro names that should be expanded. The
# macro definition that is found in the sources will be used. Use the PREDEFINED # macro definition that is found in the sources will be used. Use the PREDEFINED

View file

@ -85,10 +85,9 @@ struct stpdfs_sb {
uint32_t fsize; uint32_t fsize;
uint32_t free[100]; uint32_t free[100];
uint8_t nfree; uint8_t nfree;
uint8_t flock; uint8_t revision;
uint8_t ilock; uint8_t state;
uint8_t fmod; uint64_t time;
uint32_t time[2];
}; };
\end{lstlisting} \end{lstlisting}
@ -97,13 +96,14 @@ struct stpdfs_sb {
\begin{lstlisting}[language=C] \begin{lstlisting}[language=C]
struct inode { struct inode {
uint16_t mode; uint16_t mode;
uint8_t nlink; uint16_t nlink;
uint8_t uid; uint16_t uid;
uint8_t gid; uint16_t gid;
uint16_t flags;
uint32_t size; uint32_t size;
uint16_t addr[8]; uint32_t zones[10];
uint32_t actime[2]; uint64_t actime;
uint32_t modtime[2]; uint64_t modtime;
}; };
\end{lstlisting} \end{lstlisting}
\appendix \appendix

View file

@ -1,2 +1,2 @@
noinst_LIBRARIES = libstpdfs.a noinst_LIBRARIES = libstpdfs.a
libstpdfs_a_SOURCES = codec/base64.c libstpdfs_a_SOURCES = block.c superblock.c codec/base64.c

26
lib/block.c Normal file
View file

@ -0,0 +1,26 @@
#include "stpdfs.h"
#include <stdint.h>
size_t
stpdfs_write(int fd, uint32_t blocknum, void *data, size_t size)
{
return (0);
}
size_t
stpdfs_read(int fd, uint32_t blocknum, void *data, size_t size)
{
return (0);
}
uint32_t
stpdfs_alloc_block(int fd)
{
return (0);
}
int
stpdfs_free_block(int fd)
{
return (0);
}

View file

@ -0,0 +1,57 @@
/*
; hash(h, x) (h = (h << 4) ^ x)
section '.code' code
; xor hash, hash
; xor mask, mask
; j = 1
; while (insz > 0)
; {
; if (ecx == 8)
; {
; mov [out], mask
; xor ecx, ecx
; xor mask, mask
; j = 1;
; }
; c = in[inpos++]
; if (c == table[hash])
; {
; mask |= 1 << ecx
; }
; else
; {
; table[hash] = c
; out[j] = c;
; }
; HASH(hash, c)
; ecx++;
; }
*/
#include <stdint.h>
#define LZP_HASH_ORDER 16
#define LZP_HASH_SIZE (1 << LZP_HASH_ORDER)
#define HASH(h, x) ((h << 4) ^ x)
void
lzp_compress()
{
uint32_t hash = 0;
uint32_t mask = 0;
char c;
uint8_t table[LZP_HASH_SIZE] = { 0 };
while (1)
{
hash = HASH(hash, c);
}
}
void
lzp_decompress()
{
}

View file

@ -1,57 +0,0 @@
/*
; hash(h, x) (h = (h << 4) ^ x)
section '.code' code
; xor hash, hash
; xor mask, mask
; j = 1
; while (insz > 0)
; {
; if (ecx == 8)
; {
; mov [out], mask
; xor ecx, ecx
; xor mask, mask
; j = 1;
; }
; c = in[inpos++]
; if (c == table[hash])
; {
; mask |= 1 << ecx
; }
; else
; {
; table[hash] = c
; out[j] = c;
; }
; HASH(hash, c)
; ecx++;
; }
*/
#include <stdint.h>
#define LZP_HASH_ORDER 16
#define LZP_HASH_SIZE (1 << LZP_HASH_ORDER)
#define HASH(h, x) ((h << 4) ^ x)
void
lzp_compress()
{
uint32_t hash = 0;
uint32_t mask = 0;
char c;
uint8_t table[LZP_HASH_SIZE] = { 0 };
while (1)
{
hash = HASH(hash, c);
}
}
void
lzp_decompress()
{
}

10
lib/inode.c Normal file
View file

@ -0,0 +1,10 @@
#include "stpdfs.h"
uint32_t
alloc_inode(int fd)
{
uint32_t start = 1;
uint32_t block;
return (0);
}

View file

@ -2,60 +2,90 @@
# define STPDFS_H 1 # define STPDFS_H 1
# include <stdint.h> # include <stdint.h>
# include <stddef.h>
# define STPDFS_SB_MAGIC 0x44505453 # define STPDFS_SB_MAGIC 0x44505453
# define STPDFS_SB_REV STPDFS_SB_REV_1
# define STPDFS_SB_REV_1 1
# define STPDFS_BLOCK_SIZE_BITS 9 # define STPDFS_BLOCK_SIZE_BITS 9
# define STPDFS_BLOCK_SIZE (1 << STPDFS_BLOCK_SIZE_BITS) # define STPDFS_BLOCK_SIZE (1 << STPDFS_BLOCK_SIZE_BITS)
# define STPDFS_NAME_MAX 255 # define STPDFS_NAME_MAX 28
# define STPDFS_INODES_PER_BLOCK (STPDFS_BLOCK_SIZE / (sizeof(struct stpdfs_inode))) # define STPDFS_INODES_PER_BLOCK (STPDFS_BLOCK_SIZE / (sizeof(struct stpdfs_inode)))
# define STPDFS_ROOT_INO 1 # define STPDFS_ROOT_INO 1
# define STPDFS_LZP_COMPRESSION (1 << 0) # define STPDFS_INO_FLAG_ALOC (1 << 15)
# define STPDFS_FILE_ENCRYPTION (1 << 1) # define STPDFS_INO_FLAG_LZP (1 << 0)
# define STPDFS_INO_FLAG_ENC (1 << 1)
# define STPDFS_S_IFMT 0xF000
# define STPDFS_S_IFSOCK 0xA000
# define STPDFS_S_IFLNK 0xC000
# define STPDFS_S_IFREG 0x8000
# define STPDFS_S_IFBLK 0x6000
# define STPDFS_S_IFDIR 0x4000
struct stpdfs_free { struct stpdfs_free {
uint32_t free[100]; uint32_t free[100];
uint8_t nfree; uint8_t nfree;
} __attribute__((packed)); } __attribute__((packed));
enum stpdfs_state {
STPDFS_CLEANLY_UNMOUNTED = 0,
STPDFS_ERROR = 1
};
/** /**
* \brief StupidFS Superblock * \brief StupidFS Superblock
*/ */
struct stpdfs_sb { struct stpdfs_sb {
uint32_t magic; uint32_t magic; /**< MUST be \ref STPDFS_SB_MAGIC */
uint32_t isize; /**< size in block of the I list */ uint32_t isize; /**< size in block of the I list */
uint32_t fsize; /**< size in block of the entire volume */ uint32_t fsize; /**< size in block of the entire volume */
uint32_t free[100]; uint32_t free[100];
uint8_t nfree; /**< number of free block (0-100) */ uint8_t nfree; /**< number of free block (0-100) */
uint8_t flock; uint8_t revision; /**< MUST be \ref STPDFS_SB_REV */
uint8_t ilock; uint16_t state; /**< \see stpdfs_state */
uint8_t fmod; uint64_t time; /**< last time the superblock was modified */
uint64_t time;
} __attribute__((packed)); } __attribute__((packed));
#define STPDFS_SB_SIZE sizeof(struct stpdfs_sb)
/** /**
* \brief StupidFS I-node * \brief StupidFS I-node
*/ */
struct stpdfs_inode { struct stpdfs_inode {
uint16_t mode; /**< file mode */ uint16_t mode; /**< file mode */
uint8_t nlink; /**< link count */ uint16_t nlink; /**< link count */
uint8_t uid; /**< owner user id */ uint16_t uid; /**< owner user id */
uint8_t gid; /**< group id */ uint16_t gid; /**< group id */
uint16_t flags;
uint32_t size; uint32_t size;
uint32_t zones[10]; uint32_t zones[10];
uint32_t actime[2]; uint64_t actime;
uint32_t modtime[2]; uint64_t modtime;
} __attribute__((packed)); } __attribute__((packed));
#define INODE_SIZE sizeof(struct inode) #define STPDFS_INODE_SIZE sizeof(struct inode)
struct file { struct stpdfs_dirent {
uint32_t inode; uint32_t inode;
char filename[32]; char filename[STPDFS_NAME_MAX];
}; };
/*
* API
*/
size_t stpdfs_write(int fd, uint32_t blocknum, void *data, size_t size);
size_t stpdfs_read(int fd, uint32_t blocknum, void *data, size_t size);
/* superblock.c */
int stpdfs_superblock_valid(const struct stpdfs_sb *sb);
int stpdfs_read_superblock(int fd, struct stpdfs_sb *sb);
#endif /* !STPDFS_H */ #endif /* !STPDFS_H */

36
lib/superblock.c Normal file
View file

@ -0,0 +1,36 @@
#include "stpdfs.h"
#include <time.h>
int
stpdfs_superblock_valid(const struct stpdfs_sb *sb)
{
return (sb->magic == STPDFS_SB_MAGIC && sb->revision == STPDFS_SB_REV);
}
int
stpdfs_read_superblock(int fd, struct stpdfs_sb *sb)
{
if (stpdfs_read(fd, 1, sb, sizeof(struct stpdfs_sb)) != sizeof(struct stpdfs_sb))
{
return (-1);
}
if (stpdfs_superblock_valid(sb))
{
return (0);
}
return (-1);
}
int
stpdfs_write_superblock(int fd, struct stpdfs_sb *sb)
{
sb->time = time(NULL);
if (stpdfs_write(fd, 1, sb, sizeof(struct stpdfs_sb)) != sizeof(struct stpdfs_sb))
{
return (-1);
}
return (0);
}

View file

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include <stpdfs.h> #include <stpdfs.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -73,12 +74,39 @@ write_block(int fd, void *data, size_t size)
return (write(fd, buffer, STPDFS_BLOCK_SIZE) == STPDFS_BLOCK_SIZE); return (write(fd, buffer, STPDFS_BLOCK_SIZE) == STPDFS_BLOCK_SIZE);
} }
static void
add_free_block(int fd, int num)
{
struct stpdfs_free copy;
if (super.nfree == 100)
{
memcpy(&copy, super.free, sizeof(uint32_t) * 100);
copy.nfree = super.nfree;
lseek(fd, num * STPDFS_BLOCK_SIZE, SEEK_SET);
write_block(fd, &copy, sizeof(struct stpdfs_free));
super.nfree = 1;
super.free[0] = num;
}
else
{
super.free[super.nfree++] = num;
}
}
static int static int
mkfs() mkfs()
{ {
struct stat statbuf; struct stat statbuf;
struct stpdfs_dirent rootdirent[2];
int fd; int fd;
int dev_block; int dev_block;
int idx;
struct stpdfs_inode inds[STPDFS_INODES_PER_BLOCK];
struct stpdfs_free freebuff;
int freeblock;
int nextfree;
if (stat(device, &statbuf) < 0) if (stat(device, &statbuf) < 0)
{ {
@ -115,13 +143,46 @@ mkfs()
write_block(fd, NULL, 0); write_block(fd, NULL, 0);
super.magic = STPDFS_SB_MAGIC; super.magic = STPDFS_SB_MAGIC;
super.revision = STPDFS_SB_REV;
super.isize = inodes / STPDFS_INODES_PER_BLOCK; super.isize = inodes / STPDFS_INODES_PER_BLOCK;
super.fsize = blocks; super.fsize = blocks;
super.nfree = 0;
/* write inodes */
lseek(fd, 2 * STPDFS_BLOCK_SIZE, SEEK_SET);
memset(&inds, 0, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
inds[1].modtime = time(NULL);
inds[1].actime = time(NULL);
inds[1].size = sizeof(struct stpdfs_dirent) * 2;
inds[1].flags = STPDFS_INO_FLAG_ALOC;
inds[1].mode = STPDFS_S_IFDIR;
write_block(fd, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
memset(&inds, 0, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
for (idx = 1; idx < super.isize; idx++)
{
write_block(fd, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
}
freeblock = blocks - (inodes + 2);
for (nextfree = super.isize + 3; nextfree < freeblock; nextfree++)
{
add_free_block(fd, nextfree);
}
strcpy(rootdirent[0].filename, ".");
rootdirent[1].inode = 1;
strcpy(rootdirent[1].filename, "..");
rootdirent[1].inode = 1;
/* write super block */
lseek(fd, 1 * STPDFS_BLOCK_SIZE, SEEK_SET);
super.time = time(NULL); super.time = time(NULL);
super.state = STPDFS_CLEANLY_UNMOUNTED;
write_block(fd, &super, sizeof(struct stpdfs_sb)); write_block(fd, &super, sizeof(struct stpdfs_sb));
printf("StupidFS: %u blocks (%u Inodes)\n", super.fsize, super.isize);
close(fd); close(fd);
return (EXIT_SUCCESS); return (EXIT_SUCCESS);