feat(mkfs.stpd): make filesystem bootable (WIP)

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-07-21 09:32:17 +00:00
parent 8781f567e6
commit 45dfffc55a
45 changed files with 1245 additions and 896 deletions

9
.gitignore vendored
View file

@ -38,4 +38,11 @@ test_base64
*.trs *.trs
stpdfs-fuse stpdfs-fuse
test_hchacha test_hchacha
test_xchacha test_xchacha
tools.stpd
test-driver
config.sub
*~
hdd
config.h
*.guess

View file

@ -524,7 +524,7 @@ TIMESTAMP = NO
# normally produced when WARNINGS is set to YES. # normally produced when WARNINGS is set to YES.
# The default value is: NO. # The default value is: NO.
EXTRACT_ALL = YES EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
# be included in the documentation. # be included in the documentation.
@ -949,7 +949,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = lib src module win32 INPUT = libcrypto liblzp libstpdfs include module win32
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View file

@ -1,4 +1,4 @@
SUBDIRS = lib tools tests SUBDIRS = lib libcrypto liblzp tools
if BUILD_FUSE if BUILD_FUSE
SUBDIRS += fuse SUBDIRS += fuse

View file

@ -1,5 +1,6 @@
obj-m=$(module_DATA) obj-m += stpdfs.o
MI_OBJS = $(module_DATA) stpdfs-objs := $(module_DATA)
MI_OBJS = $(module_DATA)
all clean: all clean:
mv Makefile.automake Makefile mv Makefile.automake Makefile

4
compile_flags.txt Normal file
View file

@ -0,0 +1,4 @@
-I.
-I/usr/include/fuse3
-Ilib
-DHAVE_CONFIG_H

View file

@ -13,6 +13,10 @@ AM_PROG_AR
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_RANLIB AC_PROG_RANLIB
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_CHECK_PROG([NASM], [nasm], [nasm])
AS_IF([test -z "$NASM"], [
AC_MSG_ERROR([nasm is required])
])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
@ -21,7 +25,7 @@ AS_IF([ test "x$host_os" != "xmingw32" ], [
]) ])
AM_CONDITIONAL(BUILD_FUSE, test "x$host_os" != "xmingw32") AM_CONDITIONAL(BUILD_FUSE, test "x$host_os" != "xmingw32")
AM_CONDITIONAL(BUILD_LINUX, test "x$host_os" = "xlinux") AM_CONDITIONAL(BUILD_LINUX, test "x$host_os" = "xlinux-gnu")
AC_CHECK_INCLUDES_DEFAULT AC_CHECK_INCLUDES_DEFAULT
@ -44,8 +48,12 @@ AC_CHECK_FUNCS(m4_normalize([
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
lib/Makefile lib/Makefile
libcrypto/Makefile
libcrypto/tests/Makefile
liblzp/Makefile
liblzp/tests/Makefile
libstpdfs/Makefile
tools/Makefile tools/Makefile
tests/Makefile
linux/Makefile linux/Makefile
fuse/Makefile]) fuse/Makefile])

View file

@ -1,4 +1,4 @@
AM_CFLAGS = $(FUSE_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir) AM_CFLAGS = $(FUSE_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/include -I$(top_srcdir)
LDADD = $(FUSE_LIBS) ../lib/libstpdfs.a LDADD = $(FUSE_LIBS) ../lib/libstpdfs.a
bin_PROGRAMS = stpdfs-fuse bin_PROGRAMS = stpdfs-fuse

174
include/stupidfs.h Normal file
View file

@ -0,0 +1,174 @@
/**
* \file stupidfs.h
*
* StupidFS Filesystem
*
* ```
*
* Boot blockSuper blockInodes...InodesData...Data
*
* ```
*/
#ifndef STUPIDFS_H
# define STUPIDFS_H 1
# ifndef __KERNEL__
# include <stdint.h>
# include <stddef.h>
# endif
# define STPDFS_BLOCK_SIZE 512 /**< StupidFS block size */
# define STPDFS_INODES_PER_BLOCK (STPDFS_BLOCK_SIZE / (sizeof(struct stpdfs_inode)))
# define STPDFS_ZONES_PER_BLOCK (STPDFS_BLOCK_SIZE / sizeof(uint32_t))
# define STPDFS_DIRENT_PER_BLOCK (STPDFS_BLOCK_SIZE / (sizeof(struct stpdfs_dirent)))
# define STPDFS_SB_BLOCK 1
# define STPDFS_SB_MAGIC 0x44505453 /**< Superblock magic number */
# define STPDFS_SB_REV STPDFS_SB_REV_1 /**< current revision */
# define STPDFS_SB_REV_1 1
# define STPDFS_BADINO 0 /**< StupidFS bad inode number */
# define STPDFS_ROOTINO 1 /**< StupidFS root inode number */
# define STPDFS_NAME_MAX 28 /**< Max filename length */
/**
* \brief free block list
* ```
*
* block 99
*
* block 98
*
* ...
*
* block 2
*
* block 1
*
* block 0 block 99
*
* ...
*
* block 0 block 99
*
* ...
*
* block 0
*
* ```
*/
struct stpdfs_free {
uint32_t free[100]; /**< List of free block (0-99), index 0 point to next freelist */
uint8_t nfree; /**< index */
} __attribute__((packed));
enum stpdfs_state {
STPDFS_CLEANLY_UNMOUNTED = 0,
STPDFS_ERROR = 1,
STPDFS_DIRTY = 1,
};
/**
* \brief StupidFS Superblock
*/
struct stpdfs_sb {
uint32_t magic; /**< MUST be \ref STPDFS_SB_MAGIC */
uint32_t isize; /**< Size in block of the I list */
uint32_t fsize; /**< Size in block of the entire volume */
struct stpdfs_free freelist; /**< \see stpdfs_free */
uint8_t revision; /**< MUST be \ref STPDFS_SB_REV */
uint16_t state; /**< \see stpdfs_state */
uint64_t time; /**< Last time the superblock was modified */
} __attribute__((packed));
#define STPDFS_SB_SIZE sizeof(struct stpdfs_sb)
/**
* \brief StupidFS I-node
*
* ```
*
*
*
*
* Direct
* zone 0
*
* ...
*
* zone 6
* Indirect
* zone 7
*
* zone 8
* Double indirect
* zone 9
*
*
*
* Triple indirect
*
*
*
*
*
* ```
*/
struct stpdfs_inode {
uint16_t mode; /**< File mode */
uint16_t nlink; /**< Link count */
uint16_t uid; /**< Owner user id */
uint16_t gid; /**< Group id */
uint16_t flags; /** File flags */
uint32_t size; /** Data size in byte */
uint32_t zones[10];
uint64_t actime; /**< Access time */
uint64_t modtime; /**< Modification time */
} __attribute__((packed));
#define STPDFS_INODE_SIZE sizeof(struct inode)
# define STPDFS_NDIR 7 /**< Number of direct block */
# define STPDFS_INO_FLAG_ALOC (1 << 15)
# define STPDFS_INO_FLAG_LZP (1 << 1)
# define STPDFS_INO_FLAG_ENC (1 << 2)
# 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
# define STPDFS_S_ISUID 0x0800
# define STPDFS_S_ISGID 0x0400
# define STPDFS_S_ISVTX 0x0200
# define STPDFS_S_IRWXU 0x01C0
# define STPDFS_S_IRUSR 0x0100
# define STPDFS_S_IWUSR 0x0080
# define STPDFS_S_IXUSR 0x0040
# define STPDFS_S_IRWXG 0x0038
# define STPDFS_S_IRGRP 0x0020
# define STPDFS_S_IWGRP 0x0010
# define STPDFS_S_IXGRP 0x0008
# define STPDFS_S_IRWXO 0x0007
# define STPDFS_S_IROTH 0x0004
# define STPDFS_S_IWOTH 0x0002
# define STPDFS_S_IXOTH 0x0001
/**
* \brief StupidFS directory entry
*/
struct stpdfs_dirent {
uint32_t inode; /**< inode containing file */
char filename[STPDFS_NAME_MAX]; /** null terminated file name (\see STPDFS_NAME_MAX) */
};
#define STPDFS_DIRENT_SIZE sizeof(struct stpdfs_dirent)
#endif /* !STPIDFS_H */

View file

@ -1,8 +1,7 @@
noinst_LIBRARIES = libstpdfs.a noinst_LIBRARIES = libstpdfs.a
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)
libstpdfs_a_SOURCES = block.c \ libstpdfs_a_SOURCES = block.c \
inode.c \ inode.c \
dir.c dir.c \
superblock.c \ data.c \
compression/lzp.c \ superblock.c
crypto/hchacha.c \
crypto/xchacha.c

View file

@ -42,13 +42,13 @@ stpdfs_alloc_block(int fd, struct stpdfs_sb *sb)
sb->state = STPDFS_DIRTY; /* mark state dirty */ sb->state = STPDFS_DIRTY; /* mark state dirty */
redo: redo:
sb->nfree--; sb->freelist.nfree--;
blocknum = sb->free[sb->nfree]; blocknum = sb->freelist.free[sb->freelist.nfree];
if (sb->nfree == 0 && blocknum != 0) if (sb->freelist.nfree == 0 && blocknum != 0)
{ {
stpdfs_read(fd, blocknum, &freelist, sizeof(struct stpdfs_free)); stpdfs_read(fd, blocknum, &freelist, sizeof(struct stpdfs_free));
memcpy(sb->free, &freelist, sizeof(uint32_t) * 100); memcpy(sb->freelist.free, &freelist, sizeof(uint32_t) * 100);
sb->nfree = freelist.nfree; sb->freelist.nfree = freelist.nfree;
goto redo; goto redo;
} }
@ -69,19 +69,19 @@ stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum)
sb->state = STPDFS_DIRTY; /* mark state dirty */ sb->state = STPDFS_DIRTY; /* mark state dirty */
if (sb->nfree == 100) if (sb->freelist.nfree == 100)
{ {
memcpy(&copy, sb->free, sizeof(uint32_t) * 100); memcpy(&copy, sb->freelist.free, sizeof(uint32_t) * 100);
copy.nfree = sb->nfree; copy.nfree = sb->freelist.nfree;
stpdfs_write(fd, blocknum, &copy, sizeof(struct stpdfs_free)); stpdfs_write(fd, blocknum, &copy, sizeof(struct stpdfs_free));
sb->nfree = 1; sb->freelist.nfree = 1;
sb->free[0] = blocknum; sb->freelist.free[0] = blocknum;
} }
else else
{ {
sb->free[sb->nfree++] = blocknum; sb->freelist.free[sb->freelist.nfree++] = blocknum;
} }
sb->time = time(NULL); sb->time = time(NULL);

View file

@ -1,82 +1,180 @@
#include "stpdfs.h" #include "stpdfs.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
static void
write_indirect(int fd, struct stpdfs_sb *sb, struct stpdfs_inode *inode, size_t zone, uint8_t *buffer, size_t size) static int
stpdfs_write_indirect(int fd, uint32_t blocknum, uint8_t *buffer, size_t size)
{ {
size_t i;
uint32_t zones[STPDFS_ZONES_PER_BLOCK];
size_t byte_read;
} stpdfs_read(fd, blocknum, zones, sizeof(zones));
static void byte_read = 0;
write_zone(int fd, struct stpdfs_sb *sb, struct stpdfs_inode *inode, size_t zone, uint8_t *buffer, size_t size) for (i = 0; i < STPDFS_ZONES_PER_BLOCK; i++)
{
uint32_t zones[128];
if (zone < 7)
{ {
if (inode->zones[zone] == 0) stpdfs_read(fd, zones[i], buffer, STPDFS_BLOCK_SIZE);
{ byte_read += STPDFS_BLOCK_SIZE;
inode->zones[zone] = stpdfs_alloc_block(fd, sb);
}
stpdfs_write(fd, inode->zones[zone], buffer, size);
return; if (byte_read >= size)
}
if (zone < 135)
{
if (inode->zones[7] == 0)
{ {
inode->zones[7] = stpdfs_alloc_block(fd, sb); return (byte_read);
memset(zones, 0, 512);
stpdfs_write(fd, inode->zones[7], zones, 512);
} }
stpdfs_read(fd, inode->zones[7], zones, 512);
if (zones[zone - 7] == 0)
{
zones[zone - 7] = stpdfs_alloc_block(fd, sb);
stpdfs_write(fd, inode->zones[7], zones, 512);
}
stpdfs_write(fd, zones[zone - 7], buffer, size);
return;
} }
if (zone < 16519) return (byte_read);
{
if (inode->zones[8] == 0)
{
inode->zones[8] = stpdfs_alloc_block(fd, sb);
memset(zones, 0, 512);
stpdfs_write(fd, inode->zones[7], zones, 512);
}
stpdfs_read(fd, inode->zones[8], zones, 512);
if (zones[(zone - 135) / 128] == 0)
{
zones[(zone - 135) / 128] = stpdfs_alloc_block(fd, sb);
}
}
} }
int int
stpdfs_write_data(int fd, struct stpdfs_sb *sb, struct stpdfs_inode *inode, uint8_t *buffer, size_t size) stpdfs_write_data(int fd, struct stpdfs_sb *sb, struct stpdfs_inode *inode, uint8_t *data)
{ {
size_t idx; size_t i;
uint32_t zonenum; size_t j;
size_t max_zone; size_t byte_write;
uint32_t zones1[STPDFS_ZONES_PER_BLOCK];
uint32_t zones2[STPDFS_ZONES_PER_BLOCK];
for (idx = 0; idx < size; idx += STPDFS_BLOCK_SIZE) byte_write = 0;
for (i = 0; i < 7; i++)
{ {
max_zone = idx / STPDFS_BLOCK_SIZE; if (inode->zones[i] == 0)
for (zonenum = 0; zonenum < max_zone; zonenum++)
{ {
write_zone(fd, sb, inode, zonenum, buffer + idx, ((idx + 1) * 512) > size ? size % 512 : 512); inode->zones[i] = stpdfs_alloc_block(fd, sb);
} }
stpdfs_write(fd, inode->zones[i], data + byte_write, (inode->size - byte_write) >= STPDFS_BLOCK_SIZE ? STPDFS_BLOCK_SIZE : (inode->size - byte_write));
byte_write += STPDFS_BLOCK_SIZE;
if (byte_write >= inode->size)
{
return (byte_write);
}
} }
return (0) /*
byte_read += stpdfs_write_indirect(fd, inode->zones[7], *buffer + byte_read, inode->size - byte_read);
if (byte_read >= inode->size)
{
return (byte_read);
}
stpdfs_read(fd, inode->zones[8], zones1, sizeof(zones1));
for (i = 0; i < STPDFS_ZONES_PER_BLOCK; i++)
{
byte_read += stpdfs_read_indirect(fd, zones1[i], *buffer + byte_read, inode->size - byte_read);
if (byte_read >= inode->size)
{
return (byte_read);
}
}
stpdfs_read(fd, inode->zones[9], zones1, sizeof(zones1));
for (i = 0; i < STPDFS_ZONES_PER_BLOCK; i++)
{
stpdfs_read(fd, zones1[i], zones2, sizeof(zones2));
for (j = 0; j < STPDFS_ZONES_PER_BLOCK; j++)
{
byte_read += stpdfs_read_indirect(fd, zones2[i], *buffer + byte_read, inode->size - byte_read);
if (byte_read >= inode->size)
{
return (byte_read);
}
}
}*/
return (byte_write);
} }
static int
stpdfs_read_indirect(int fd, uint32_t blocknum, uint8_t *buffer, size_t size)
{
size_t i;
uint32_t zones[STPDFS_ZONES_PER_BLOCK];
size_t byte_read;
stpdfs_read(fd, blocknum, zones, sizeof(zones));
byte_read = 0;
for (i = 0; i < STPDFS_ZONES_PER_BLOCK; i++)
{
stpdfs_read(fd, zones[i], buffer, STPDFS_BLOCK_SIZE);
byte_read += STPDFS_BLOCK_SIZE;
if (byte_read >= size)
{
return (byte_read);
}
}
return (byte_read);
}
int
stpdfs_read_data(int fd, struct stpdfs_sb *sb, struct stpdfs_inode *inode, uint8_t **buffer)
{
size_t i;
size_t j;
size_t byte_read;
uint32_t zones1[STPDFS_ZONES_PER_BLOCK];
uint32_t zones2[STPDFS_ZONES_PER_BLOCK];
*buffer = (uint8_t *)malloc(inode->size + STPDFS_BLOCK_SIZE);
byte_read = 0;
for (i = 0; i < 7; i++)
{
stpdfs_read(fd, inode->zones[i], *buffer, STPDFS_BLOCK_SIZE);
byte_read += STPDFS_BLOCK_SIZE;
if (byte_read >= inode->size)
{
return (byte_read);
}
}
byte_read += stpdfs_read_indirect(fd, inode->zones[7], *buffer + byte_read, inode->size - byte_read);
if (byte_read >= inode->size)
{
return (byte_read);
}
stpdfs_read(fd, inode->zones[8], zones1, sizeof(zones1));
for (i = 0; i < STPDFS_ZONES_PER_BLOCK; i++)
{
byte_read += stpdfs_read_indirect(fd, zones1[i], *buffer + byte_read, inode->size - byte_read);
if (byte_read >= inode->size)
{
return (byte_read);
}
}
stpdfs_read(fd, inode->zones[9], zones1, sizeof(zones1));
for (i = 0; i < STPDFS_ZONES_PER_BLOCK; i++)
{
stpdfs_read(fd, zones1[i], zones2, sizeof(zones2));
for (j = 0; j < STPDFS_ZONES_PER_BLOCK; j++)
{
byte_read += stpdfs_read_indirect(fd, zones2[i], *buffer + byte_read, inode->size - byte_read);
if (byte_read >= inode->size)
{
return (byte_read);
}
}
}
return (byte_read);
}

View file

@ -4,60 +4,15 @@
#include <stdlib.h> #include <stdlib.h>
int int
stpdfs_dir_add_entry(int fd, uint8_t inonum, const char *name, uint32_t target) stpdfs_dir_add_entry(int fd, struct stpdfs_sb *sb, uint32_t inonum, const char *name, uint32_t target)
{ {
struct stpdfs_inode inode; struct stpdfs_inode inode;
struct stpdfs_dirent dirent[STPDFS_DIRENT_PER_BLOCK];
struct stpdfs_sb sb;
size_t max_zone;
size_t zone;
uint32_t blocknum;
stpdfs_read_superblock(fd, &sb);
stpdfs_read_inode(fd, inonum, &inode); stpdfs_read_inode(fd, inonum, &inode);
if (!(inode.mode & STPDFS_S_IFDIR)) if (!(inode.mode & STPDFS_S_IFDIR))
{ {
return (-1); return (-1);
} }
max_zone = (inode.size + sizeof(struct stpdfs_dirent)) / STPDFS_DIRENT_PER_BLOCK;
zone = max_zone;
if (max_zone > 2113671)
{
}
if (max_zone > 16519)
{
}
else if (max_zone > 135)
{
}
else if (max_zone > 7)
{
}
else
{
if (inode.zones[max_zone] == 0)
{
inode.zones[max_zone] = stpdfs_alloc_block(fd, &sb);
}
blocknum = inode.zones[max_zone];
}
stpdfs_read(fd, blocknum, &dirent, sizeof(struct stpdfs_dirent) * STPDFS_DIRENT_PER_BLOCK);
dirent[inode.size % STPDFS_DIRENT_PER_BLOCK].inode = target;
memcpy(dirent[inode.size % STPDFS_DIRENT_PER_BLOCK].filename, name, STPDFS_NAME_MAX);
stpdfs_write(fd, blocknum, &dirent, sizeof(struct stpdfs_dirent) * STPDFS_DIRENT_PER_BLOCK);
inode.size += sizeof(struct stpdfs_dirent);
stpdfs_write_inode(fd, inonum, &inode);
stpdfs_write(fd, 1, &sb, sizeof(struct stpdfs_sb));
return (0); return (0);
} }

View file

@ -8,119 +8,13 @@
* *
* ``` * ```
*/ */
#include <cstdint>
#ifndef STPDFS_H #ifndef STPDFS_H
# define STPDFS_H 1 # define STPDFS_H 1
# include <stupidfs.h>
# include <stdint.h> # include <stdint.h>
# include <stddef.h> # include <stddef.h>
# define STPDFS_SB_MAGIC 0x44505453
# define STPDFS_SB_REV STPDFS_SB_REV_1
# define STPDFS_SB_REV_1 1
# define STPDFS_INO_ROOTDIR 1
# define STPDFS_BLOCK_SIZE_BITS 9
# define STPDFS_BLOCK_SIZE (1 << STPDFS_BLOCK_SIZE_BITS)
# define STPDFS_NAME_MAX 28
# define STPDFS_INODES_PER_BLOCK (STPDFS_BLOCK_SIZE / (sizeof(struct stpdfs_inode)))
# define STPDFS_DIRENT_PER_BLOCK (STPDFS_BLOCK_SIZE / (sizeof(struct stpdfs_dirent)))
# define STPDFS_ROOT_INO 1
# define STPDFS_INO_FLAG_ALOC (1 << 15)
# define STPDFS_INO_FLAG_LARGE (1 << 0)
# define STPDFS_INO_FLAG_LZP (1 << 1)
# define STPDFS_INO_FLAG_ENC (1 << 2)
# 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
typedef uint32_t zone_t; /**< zone number */
typedef uint32_t block_t; /**< block number */
typedef uint32_t ino_t;
/**
* \brief free block list
* ```
*
* block 99
*
* block 98
*
* ...
*
* block 2
*
* block 1
*
* block 0 block 99
*
* ...
*
* block 0 block 99
*
* ...
*
* block 0
*
* ```
*/
struct stpdfs_free {
block_t free[100];
uint8_t nfree;
} __attribute__((packed));
enum stpdfs_state {
STPDFS_CLEANLY_UNMOUNTED = 0,
STPDFS_ERROR = 1,
STPDFS_DIRTY = 1,
};
/**
* \brief StupidFS Superblock
*/
struct stpdfs_sb {
uint32_t magic; /**< MUST be \ref STPDFS_SB_MAGIC */
uint32_t isize; /**< size in block of the I list */
uint32_t fsize; /**< size in block of the entire volume */
struct stpdfs_free freelist; /**< \see stpdfs_free */
uint8_t revision; /**< MUST be \ref STPDFS_SB_REV */
uint16_t state; /**< \see stpdfs_state */
uint64_t time; /**< last time the superblock was modified */
} __attribute__((packed));
#define STPDFS_SB_SIZE sizeof(struct stpdfs_sb)
/**
* \brief StupidFS I-node
*/
struct stpdfs_inode {
uint16_t mode; /**< file mode */
uint16_t nlink; /**< link count */
uint16_t uid; /**< owner user id */
uint16_t gid; /**< group id */
uint16_t flags;
uint32_t size;
zone_t zones[10];
uint64_t actime;
uint64_t modtime;
} __attribute__((packed));
#define STPDFS_INODE_SIZE sizeof(struct inode)
struct stpdfs_dirent {
ino_t inode;
char filename[STPDFS_NAME_MAX];
};
/* /*
* API * API
*/ */

5
libcrypto/Makefile.am Normal file
View file

@ -0,0 +1,5 @@
SUBDIRS = tests
noinst_LIBRARIES = libcrypto.a
AM_CFLAGS = -I$(top_srcdir)
libcrypto_a_SOURCES = hchacha.c xchacha.c

View file

@ -1,5 +1,8 @@
#ifndef STPDFS_CRYPTO_CHACHA_H /**
# define STPDFS_CRYPTO_CHACHA_H 1 * \file chacha.h
*/
#ifndef CHACHA_H
# define CHACHA_H 1
# include <stdint.h> # include <stdint.h>
# include <stddef.h> # include <stddef.h>
@ -38,4 +41,4 @@ void
xchacha12(uint8_t *out, uint8_t key[CHACHA_KEY_BYTES], uint8_t nonce[24], xchacha12(uint8_t *out, uint8_t key[CHACHA_KEY_BYTES], uint8_t nonce[24],
uint8_t *in, size_t inlen); uint8_t *in, size_t inlen);
#endif /* STPDFS_CRYPTO_CHACHA_H */ #endif /* CHACHA_H */

View file

@ -0,0 +1,9 @@
TESTS = test_hchacha test_xchacha
check_PROGRAMS = test_hchacha test_xchacha
AM_CFLAGS = -I../
LDADD = -lcmocka ../libcrypto.a
test_hchacha_SOURCES = test_hchacha.c
test_xchacha_SOURCES = test_xchacha.c

View file

@ -4,7 +4,7 @@
#include <setjmp.h> #include <setjmp.h>
#include <cmocka.h> #include <cmocka.h>
#include <crypto/chacha.h> #include "chacha.h"
/* test from https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03#section-2.2 */ /* test from https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03#section-2.2 */

View file

@ -5,7 +5,7 @@
#include <cmocka.h> #include <cmocka.h>
#include <string.h> #include <string.h>
#include <crypto/chacha.h> #include "chacha.h"
void xchacha(uint8_t *out, uint8_t key[CHACHA_KEY_BYTES], uint8_t nonce[24], void xchacha(uint8_t *out, uint8_t key[CHACHA_KEY_BYTES], uint8_t nonce[24],
uint8_t *in, size_t inlen, int round); uint8_t *in, size_t inlen, int round);

4
liblzp/Makefile.am Normal file
View file

@ -0,0 +1,4 @@
SUBDIRS = tests
noinst_LIBRARIES = liblzp.a
liblzp_a_SOURCES = lzp.c

View file

@ -1,5 +1,8 @@
#ifndef STPDFS_COMPRESSION_LZP_H /**
# define STPDFS_COMPRESSION_LZP_H 1 * \file lzp.h
*/
#ifndef LZP_H
# define LZP_H 1
# include <stddef.h> # include <stddef.h>
# include <stdint.h> # include <stdint.h>
@ -7,4 +10,4 @@
void lzp_compress(uint8_t *out, size_t *outsz, const uint8_t *in, size_t insz); void lzp_compress(uint8_t *out, size_t *outsz, const uint8_t *in, size_t insz);
void lzp_decompress(uint8_t *out, size_t *outsz, const uint8_t *in, size_t insz); void lzp_decompress(uint8_t *out, size_t *outsz, const uint8_t *in, size_t insz);
#endif /* STPDF_COMPRESSION_LZP_H */ #endif /* LZP_H */

9
liblzp/tests/Makefile.am Normal file
View file

@ -0,0 +1,9 @@
AM_CPPFLAGS = -I$(srcdir)/..
TESTS = test_lzp
check_PROGRAMS = test_lzp
LDADD = -lcmocka ../liblzp.a
test_lzp_SOURCES = test_lzp.c

2
libstpdfs/Makefile.am Normal file
View file

@ -0,0 +1,2 @@
noinst_LIBRARIES = libstpdfs.a
libstpdfs_a_SOURCES = super.c bio.c inode.c file.c dir.c

124
libstpdfs/bio.c Normal file
View file

@ -0,0 +1,124 @@
#include "stupidfs.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <libstpdfs/stpdfs.h>
static struct stpdfs_buffer *head = NULL;
size_t
stpdfs_write(int fd, uint32_t blocknum, void *data, size_t size)
{
uint8_t buffer[STPDFS_BLOCK_SIZE];
if (size > STPDFS_BLOCK_SIZE) return (-1);
lseek(fd, blocknum * STPDFS_BLOCK_SIZE, SEEK_SET);
if (size > 0)
{
memcpy(buffer, data, size);
return (write(fd, buffer, STPDFS_BLOCK_SIZE));
}
return (write(fd, data, size));
}
size_t
stpdfs_read(int fd, uint32_t blocknum, void *data, size_t size)
{
lseek(fd, blocknum * STPDFS_BLOCK_SIZE, SEEK_SET);
return (read(fd, data, size));
}
static struct stpdfs_buffer *
bget(int fd, uint32_t blocknum)
{
struct stpdfs_buffer *buff;
for (buff = head; buff != NULL; buff = buff->next)
{
if (buff->blocknum == blocknum)
{
buff->refcount++;
return (buff);
}
}
buff = (struct stpdfs_buffer *)malloc(sizeof(struct stpdfs_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 stpdfs_buffer *
stpdfs_bread(int fd, uint32_t blocknum)
{
struct stpdfs_buffer *buff;
buff = bget(fd, blocknum);
if (buff == NULL)
{
return (NULL);
}
if (buff->valid == 0)
{
stpdfs_read(fd, blocknum, buff->data, STPDFS_BLOCK_SIZE);
buff->valid = 1;
}
return (buff);
}
void
stpdfs_bwrite(struct stpdfs_buffer *buff)
{
stpdfs_write(buff->fd, buff->blocknum, buff->data, STPDFS_BLOCK_SIZE);
}
void
stpdfs_brelse(struct stpdfs_buffer *buff)
{
struct stpdfs_buffer *tmp;
buff->refcount--;
if (buff->refcount <= 0)
{
for (tmp = head; tmp != NULL; tmp = tmp->next)
{
if (tmp->next == buff)
{
tmp->next = buff->next;
break;
}
}
free(buff);
}
}
void
stpdfs_bpin(struct stpdfs_buffer *buff)
{
buff->refcount++;
}
void
stpdfs_bunpin(struct stpdfs_buffer *buff)
{
buff->refcount--;
}

0
libstpdfs/dir.c Normal file
View file

0
libstpdfs/file.c Normal file
View file

17
libstpdfs/inode.c Normal file
View file

@ -0,0 +1,17 @@
#include <libstpdfs/stpdfs.h>
#define INODE_CACHE 50
struct stpdfs_inode_info icache[INODE_CACHE];
struct inode *
stpdfs_inode_get(struct stpdfs_sb *sb, uint32_t ino)
{
return (NULL);
}
struct stpdfs_dirent *
stpdfs_lookup(struct stpdfs_inode *dir, struct stpdfs_dirent *dentry, int flags)
{
return (NULL);
}

47
libstpdfs/stpdfs.h Normal file
View file

@ -0,0 +1,47 @@
/**
* \file stpdfs.h
*/
#ifndef STPDFS_H
# define STPDFS_H 1
# include <stupidfs.h>
struct stpdfs_super_info {
struct stpdfs_sb sb;
int fd;
};
struct stpdfs_inode_info {
struct stpdfs_inode ino;
int fd;
int refcount;
};
struct stpdfs_buffer {
int valid;
uint32_t blocknum;
int refcount;
int fd;
struct stpdfs_buffer *next;
uint8_t data[STPDFS_BLOCK_SIZE];
};
/* bio.c */
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);
struct stpdfs_buffer *stpdfs_bread(int fd, uint32_t blocknum);
void stpdfs_bwrite(struct stpdfs_buffer *buff);
void stpdfs_brelse(struct stpdfs_buffer *buff);
void stpdfs_bpin(struct stpdfs_buffer *buff);
/* super.c */
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_alloc_block(int fd, struct stpdfs_sb *sb);
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
#endif /* !STPDFS_H */

76
libstpdfs/super.c Normal file
View file

@ -0,0 +1,76 @@
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <libstpdfs/stpdfs.h>
int
stpdfs_super_validate(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
stpdfs_super_open(struct stpdfs_super_info *sbi, const char *fname)
{
struct stpdfs_buffer *buff;
sbi->fd = open(fname, O_RDWR);
if (sbi->fd < 0)
{
perror(fname);
return (-1);
}
buff = stpdfs_bread(sbi->fd, 1);
if (!buff) goto err;
if (stpdfs_super_validate((struct stpdfs_sb *)buff->data) != 0) goto err;
memcpy(&sbi->sb, buff->data, sizeof(struct stpdfs_sb));
return (0);
err:
close(sbi->fd);
return (-1);
}
int
stpdfs_super_kill(struct stpdfs_super_info *sbi)
{
struct stpdfs_buffer *buff;
buff = stpdfs_bread(sbi->fd, 1);
if (buff == NULL) goto end;
memcpy(buff->data, &sbi->sb, sizeof(struct stpdfs_sb));
stpdfs_bwrite(buff);
stpdfs_brelse(buff);
end:
close(sbi->fd);
}

View file

@ -5,8 +5,8 @@ MOD_DEVDIR = $(PWD)
export module_DATA export module_DATA
EXTRA_PROGRAMS = stpdfs_module EXTRA_PROGRAMS = stpdfs_module
stpdfs_module_SOURCES = module.c stpdfs_module_SOURCES = module.c super.c
module_DATA = module.o module_DATA = module.o super.o
$(module_DATA): $(stpdfs_module_SOURCES) $(module_DATA): $(stpdfs_module_SOURCES)
mv Makefile Makefile.automake mv Makefile Makefile.automake
@ -14,7 +14,7 @@ $(module_DATA): $(stpdfs_module_SOURCES)
CPPFLAGS="" CFLAGS="" LDFLAGS="" \ CPPFLAGS="" CFLAGS="" LDFLAGS="" \
$(MAKE) -C /lib/modules/$(shell uname -r)/build \ $(MAKE) -C /lib/modules/$(shell uname -r)/build \
ARCH="x86" CC="gcc" M=$(PWD) modules\ ARCH="x86" CC="gcc" M=$(PWD) modules\
KBUILD_VERBOSE=$(KBUILD_VERBOSE) KBUILD_VERBOSE=$(KBUILD_VERBOSE)
mv Makefile.automake Makefile mv Makefile.automake Makefile
CLEANFILES = $(module_DATA) .$(module_DATA).flags $(module_DATA:.o=.mod.c) $(module_DATA:.o=.@kernelext@) CLEANFILES = $(module_DATA) .$(module_DATA).flags $(module_DATA:.o=.mod.c) $(module_DATA:.o=.@kernelext@)

View file

@ -1,610 +0,0 @@
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# linux/Makefile. Generated from Makefile.in by configure.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/stupidfs
pkgincludedir = $(includedir)/stupidfs
pkglibdir = $(libdir)/stupidfs
pkglibexecdir = $(libexecdir)/stupidfs
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-w64-mingw32
host_triplet = x86_64-w64-mingw32
EXTRA_PROGRAMS = stpdfs_module$(EXEEXT)
subdir = linux
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am_stpdfs_module_OBJECTS = module.$(OBJEXT)
stpdfs_module_OBJECTS = $(am_stpdfs_module_OBJECTS)
stpdfs_module_LDADD = $(LDADD)
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/module.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_$(V))
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_$(V))
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(stpdfs_module_SOURCES)
DIST_SOURCES = $(stpdfs_module_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(moduledir)"
DATA = $(module_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} '/c/Users/conta/Workspace/StupidFS/missing' aclocal-1.16
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1
AR = ar
AUTOCONF = ${SHELL} '/c/Users/conta/Workspace/StupidFS/missing' autoconf
AUTOHEADER = ${SHELL} '/c/Users/conta/Workspace/StupidFS/missing' autoheader
AUTOMAKE = ${SHELL} '/c/Users/conta/Workspace/StupidFS/missing' automake-1.16
AWK = gawk
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS =
CSCOPE = cscope
CTAGS = ctags
CYGPATH_W = cygpath -w
DEFS = -DPACKAGE_NAME=\"StupidFS\" -DPACKAGE_TARNAME=\"stupidfs\" -DPACKAGE_VERSION=\"0.0\" -DPACKAGE_STRING=\"StupidFS\ 0.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stupidfs\" -DVERSION=\"0.0\" -DHAVE_STDIO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1
DEPDIR = .deps
ECHO_C =
ECHO_N = -n
ECHO_T =
ETAGS = etags
EXEEXT = .exe
FUSE_CFLAGS =
FUSE_LIBS =
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
LDFLAGS =
LIBOBJS =
LIBS =
LTLIBOBJS =
MAKEINFO = ${SHELL} '/c/Users/conta/Workspace/StupidFS/missing' makeinfo
MKDIR_P = /usr/bin/mkdir -p
OBJEXT = o
PACKAGE = stupidfs
PACKAGE_BUGREPORT =
PACKAGE_NAME = StupidFS
PACKAGE_STRING = StupidFS 0.0
PACKAGE_TARNAME = stupidfs
PACKAGE_URL =
PACKAGE_VERSION = 0.0
PATH_SEPARATOR = :
PKG_CONFIG = /ucrt64/bin/pkg-config
PKG_CONFIG_LIBDIR =
PKG_CONFIG_PATH = /ucrt64/lib/pkgconfig:/ucrt64/share/pkgconfig
RANLIB = ranlib
SET_MAKE =
SHELL = /bin/sh
STRIP =
VERSION = 0.0
abs_builddir = /c/Users/conta/Workspace/StupidFS/linux
abs_srcdir = /c/Users/conta/Workspace/StupidFS/linux
abs_top_builddir = /c/Users/conta/Workspace/StupidFS
abs_top_srcdir = /c/Users/conta/Workspace/StupidFS
ac_ct_AR = ar
ac_ct_CC = gcc
am__include = include
am__leading_dot = .
am__quote =
am__tar = $${TAR-tar} chof - "$$tardir"
am__untar = $${TAR-tar} xf -
bindir = ${exec_prefix}/bin
build = x86_64-w64-mingw32
build_alias = x86_64-w64-mingw32
build_cpu = x86_64
build_os = mingw32
build_vendor = w64
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = x86_64-w64-mingw32
host_alias =
host_cpu = x86_64
host_os = mingw32
host_vendor = w64
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /c/Users/conta/Workspace/StupidFS/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /ucrt64
program_transform_name = s,x,x,
psdir = ${docdir}
runstatedir = ${localstatedir}/run
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
sysconfdir = ${prefix}/etc
target_alias =
top_build_prefix = ../
top_builddir = ..
top_srcdir = ..
moduledir = @moduledir@
KBUILD_VERBOSE = 1
MOD_DEVDIR = $(PWD)
stpdfs_module_SOURCES = module.c
module_DATA = module.o
CLEANFILES = $(module_DATA) .$(module_DATA).flags $(module_DATA:.o=.mod.c) $(module_DATA:.o=.@kernelext@)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign linux/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign linux/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
stpdfs_module$(EXEEXT): $(stpdfs_module_OBJECTS) $(stpdfs_module_DEPENDENCIES) $(EXTRA_stpdfs_module_DEPENDENCIES)
@rm -f stpdfs_module$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(stpdfs_module_OBJECTS) $(stpdfs_module_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/module.Po # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
$(am__mv) $$depbase.Tpo $$depbase.Po
# $(AM_V_CC)source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
.c.obj:
$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
$(am__mv) $$depbase.Tpo $$depbase.Po
# $(AM_V_CC)source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
install-moduleDATA: $(module_DATA)
@$(NORMAL_INSTALL)
@list='$(module_DATA)'; test -n "$(moduledir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \
$(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(moduledir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(moduledir)" || exit $$?; \
done
uninstall-moduleDATA:
@$(NORMAL_UNINSTALL)
@list='$(module_DATA)'; test -n "$(moduledir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(moduledir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(DATA)
installdirs:
for dir in "$(DESTDIR)$(moduledir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/module.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-moduleDATA
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/module.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-moduleDATA
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-generic cscopelist-am ctags ctags-am distclean \
distclean-compile distclean-generic distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-moduleDATA \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-moduleDATA
.PRECIOUS: Makefile
export module_DATA
$(module_DATA): $(stpdfs_module_SOURCES)
mv Makefile Makefile.automake
cp $(srcdir)/../Makefile.kernel Makefile
CPPFLAGS="" CFLAGS="" LDFLAGS="" \
$(MAKE) -C /lib/modules/$(shell uname -r)/build \
ARCH="x86" CC="gcc" M=$(PWD) modules\
KBUILD_VERBOSE=$(KBUILD_VERBOSE)
mv Makefile.automake Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View file

@ -2,19 +2,70 @@
* \addtogroup driver * \addtogroup driver
* @{ * @{
*/ */
#include <linux/init.h>
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include "module.h"
/** /**
* \defgroup linux Linux Kernel Module * \defgroup linux Linux Kernel Module
* @{ * @{
*/ */
struct dentry *
stpdfs_mount(struct file_system_type *fs_type, int flags,
const char *devname, void *data)
{
struct dentry *dentry;
dentry = mount_bdev(fs_type, flags, devname, data, stpdfs_fill_super);
if (IS_ERR(dentry))
{
pr_err("'%s' mount failure\n", devname);
}
else
{
pr_info("'%s' mount success\n", devname);
}
return (dentry);
}
void
stpdfs_kill_sb(struct super_block *sb)
{
(void)sb;
}
static struct file_system_type stpdfs_file_system_type = {
.owner = THIS_MODULE,
.name = "stupidfs",
.mount = stpdfs_mount,
.kill_sb = stpdfs_kill_sb,
.fs_flags = FS_REQUIRES_DEV,
.next = NULL,
};
static int __init static int __init
stpdfs_mod_init(void) stpdfs_mod_init(void)
{ {
printk("Hello, world!\n"); int ret;
return 0;
ret = register_filesystem(&stpdfs_file_system_type);
if (ret != 0)
{
pr_err("Failed to register filesystem\n");
goto err;
}
pr_info("module loaded\n");
return (0);
err:
return (ret);
} }
module_init(stpdfs_mod_init); module_init(stpdfs_mod_init);
@ -22,7 +73,12 @@ module_init(stpdfs_mod_init);
static void __exit static void __exit
stpdfs_mod_exit(void) stpdfs_mod_exit(void)
{ {
printk("Goodbye, world!\n"); if (unregister_filesystem(&stpdfs_file_system_type) != 0)
{
pr_err("Failed to unregister filesystem\n");
}
pr_info("module unloaded\n");
} }
module_exit(stpdfs_mod_exit); module_exit(stpdfs_mod_exit);

15
linux/module.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef MODULE_H
# define MODULE_H
# include "../include/stupidfs.h"
struct stpdfs_sb_info {
struct stpdfs_sb sb;
uint32_t freeblock;
uint32_t freeinode;
};
int stpdfs_fill_super(struct super_block *sb, void *data, int silent);
#endif /* !MODULE_H */

59
linux/super.c Normal file
View file

@ -0,0 +1,59 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/statfs.h>
#include <linux/blkdev.h>
#include <linux/jbd2.h>
#include <linux/namei.h>
#include <linux/parser.h>
#include "module.h"
static struct super_operations stpdfs_super_ops = {
};
int
stpdfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct buffer_head *bh = NULL;
struct stpdfs_sb_info *sbi = NULL;
sb->s_magic = STPDFS_SB_MAGIC;
sb_set_blocksize(sb, STPDFS_BLOCK_SIZE);
sb->s_maxbytes = (u32)-1;
sb->s_op = &stpdfs_super_ops;
bh = sb_bread(sb, 1);
if (bh == NULL)
{
return (-EIO);
}
if (((struct stpdfs_sb *)bh->b_data)->magic != sb->s_magic)
{
pr_err("Invalid magic number\n");
brelse(bh);
return (-EINVAL);
}
sbi = kzalloc(sizeof(struct stpdfs_sb), GFP_KERNEL);
if (sbi == NULL)
{
brelse(bh);
return (-ENOMEM);
}
memcpy(&sbi->sb, bh->b_data, sizeof(struct stpdfs_sb));
sb->s_fs_info = sbi;
brelse(bh);
return (0);
}

View file

@ -1,13 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/lib
TESTS = test_lzp test_hchacha test_xchacha
check_PROGRAMS = test_lzp test_hchacha test_xchacha
LDADD = -lcmocka ../lib/libstpdfs.a
test_lzp_SOURCES = test_lzp.c
test_hchacha_SOURCES = test_hchacha.c
test_xchacha_SOURCES = test_xchacha.c

View file

@ -1,10 +1,19 @@
AM_CFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)
LDADD = ../lib/libstpdfs.a LDADD = ../lib/libstpdfs.a
bin_PROGRAMS = mkfs.stpd tools.stpd bin_PROGRAMS = mkfs.stpd tools.stpd
mkfs_stpd_SOURCES = mkfs/main.c mkfs_stpd_SOURCES = mkfs/main.c
mkfs_stpd_LDADD = ../lib/libstpdfs.a mkfs/bootsector.o
tools_stpd_SOURCES = tools/main.c tools_stpd_SOURCES = tools/main.c tools/ls.c tools/copy.c
man_MANS = mkfs/mkfs.stpd.8 tools/tools.stpd.8 mkfs/boot.o: mkfs/boot.asm
$(NASM) -fbin -o $@ $<
mkfs/bootsector.o: mkfs/boot.o
ld -r -b binary -o $@ $<
man_MANS = mkfs/mkfs.stpd.8 tools/tools.stpd.8
CLEANFILES = mkfs/boot.o mkfs/bootsector.o

173
tools/mkfs/boot.asm Normal file
View file

@ -0,0 +1,173 @@
[BITS 16]
[ORG 0x7c00]
LOADER_BASE equ 0x1000
DISK_BUFFER equ 0x8000
STPDFS_MAGIC equ 0x44505453
BLOCK_SIZE equ 512
INODE_SIZE equ 34
INODE_ALLOCATED equ (1<<15)
CR equ 0xD
LF equ 0xA
struc inode
.mode: resb 1
.nlink: resb 1
.uid: resb 1
.gid: resb 1
.flags: resb 1
.size: resd 1
.zones: resd 10
.actime: resq 1
.modtime: resq 1
endstruc
jmp start
nop
bpb:
db 0, 0, 0
.oem_id: db "STUPIDFS"
.sector_size: dw 512
.sects_per_cluster: db 0
.reserved_sects: dw 0
.fat_count: db 0
.root_dir_entries: dw 0
.sector_count: dw 0
.media_type: db 0
.sects_per_fat: dw 0
.sects_per_track: dw 18
.head_count: dw 2
.hidden_sects: dd 0
.sector_count_big: dd 0
.drive_num: db 0
.reserved: db 0
.signature: db 0
.volume_id: dd 0
.volume_label: db "STPD.MKFS "
.filesystem_type: times 8 db 0
start:
cli
cld
jmp 0x0:.canonicalize_cs
.canonicalize_cs:
xor ax, ax
mov ds, ax
mov ss, ax
mov es, ax
mov sp, 0x7c00
mov [bpb.drive_num], dl
; ensure lba mode is supported
mov ah, 0x41
mov bx, 0x55AA
int 0x13
jc .err_lba
; reset disk
.reset_disk:
mov dl, [bpb.drive_num]
xor ah, ah
int 0x13
jc .reset_disk
; read superblock
mov ax, DISK_BUFFER/10
mov es, ax
; load two sector in memory
; superblock and first inodes
mov eax, 1
mov cx, 2
xor bx, bx
call disk_read_sectors
mov dword eax, [DISK_BUFFER]
cmp eax, STPDFS_MAGIC
jne .err_magic
; inode 0 bad
; inode 1 root dir
; inode 2 is loader, let's keep things easy
mov ax, word [DISK_BUFFER + 34 * 2 + inode.flags]
and ax, INODE_ALLOCATED
jz .err_no_loader
mov dword eax, [DISK_BUFFER + 34 * 2 + inode.size] ; size
mov dword [uFsize], eax
xor ecx, ecx
.read_loop:
cmp dword ecx, [uFsize]
jg .all_read
add ecx, BLOCK_SIZE
jmp .read_loop
.all_read:
mov eax, DISK_BUFFER + 34 * 2 + 14 ; first zone
mov ax, LOADER_BASE/10
mov es, ax
jmp 0x0:LOADER_BASE
.err_no_loader:
mov si, szErrorNoLoader
call bios_print
jmp .end
.err_magic:
mov si, szErrorNoLoader
call bios_print
jmp .end
.err_lba:
mov si, szErrorLBA
call bios_print
.end:
hlt
jmp $
bios_print:
lodsb
or al, al
jz .end
mov ah, 0x0E
int 0x10
jmp bios_print
.end:
ret
szErrorNoLoader: db "Loader not found", CR, LF, 0
szErrorBadMagic: db "Err: magic", CR, LF, 0
szErrorLBA: db "Err: LBA", CR, LF, 0
uFsize: dd 0
disk_read_sectors:
mov word [disk_packet.sectors], cx
mov word [disk_packet.segment], es
mov word [disk_packet.offset], bx
mov dword [disk_packet.lba], eax
mov si, [disk_packet]
mov dl, [bpb.drive_num]
mov ah, 0x42
int 0x13
ret
disk_packet:
db 0x10
db 0
.sectors:
dw 0
.segment:
dw 0
.offset:
dw 0
.lba:
dd 0
dd 0
times 510-($-$$) db 0
dw 0xAA55

View file

@ -2,12 +2,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <stpdfs.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <stupidfs.h>
#include <stpdfs.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
@ -22,12 +23,17 @@ static const char *prg_name;
static int inodes = -1; static int inodes = -1;
static const char *device; static const char *device;
static int blocks = -1; static int blocks = -1;
static int bootable = 0;
static struct stpdfs_sb super; static struct stpdfs_sb super;
extern const char _binary_mkfs_boot_o_start[];
extern const char _binary_mkfs_boot_o_end[];
#ifdef HAVE_STRUCT_OPTION #ifdef HAVE_STRUCT_OPTION
static struct option long_options[] = { static struct option long_options[] = {
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'}, {"version", no_argument, 0, 'V'},
{"boot", no_argument, 0, 'b'},
{"inodes", required_argument, 0, 'i'}, {"inodes", required_argument, 0, 'i'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
@ -44,6 +50,7 @@ usage(int retval)
{ {
printf("Usage: %s [options] /dev/name [blocks]\n\n", prg_name); printf("Usage: %s [options] /dev/name [blocks]\n\n", prg_name);
printf("Options:\n"); printf("Options:\n");
printf(" -b, --boot make filesystem bootable\n");
printf(" -i, --inode <num> number of inodes for the filesystem\n"); printf(" -i, --inode <num> number of inodes for the filesystem\n");
printf(" -h, --help display this help\n"); printf(" -h, --help display this help\n");
printf(" -V, --version display version\n\n"); printf(" -V, --version display version\n\n");
@ -60,6 +67,60 @@ version(void)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
uint32_t
alloc_block(int fd, struct stpdfs_sb *sb)
{
uint32_t blocknum;
struct stpdfs_free freelist;
sb->state = STPDFS_DIRTY; /* mark state dirty */
redo:
sb->freelist.nfree--;
blocknum = sb->freelist.free[sb->freelist.nfree];
if (sb->freelist.nfree == 0 && blocknum != 0)
{
stpdfs_read(fd, blocknum, &freelist, sizeof(struct stpdfs_free));
memcpy(sb->freelist.free, &freelist, sizeof(uint32_t) * 100);
sb->freelist.nfree = freelist.nfree;
goto redo;
}
sb->time = time(NULL);
return (blocknum);
}
int
free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum)
{
struct stpdfs_free copy;
if (blocknum == 0 || blocknum >= sb->fsize)
{
return (-1);
}
sb->state = STPDFS_DIRTY; /* mark state dirty */
if (sb->freelist.nfree == 100)
{
memcpy(&copy, sb->freelist.free, sizeof(uint32_t) * 100);
copy.nfree = sb->freelist.nfree;
stpdfs_write(fd, blocknum, &copy, sizeof(struct stpdfs_free));
sb->freelist.nfree = 1;
sb->freelist.free[0] = blocknum;
}
else
{
sb->freelist.free[sb->freelist.nfree++] = blocknum;
}
sb->time = time(NULL);
return (0);
}
static int static int
write_block(int fd, void *data, size_t size) write_block(int fd, void *data, size_t size)
{ {
@ -124,7 +185,7 @@ mkfs()
super.revision = STPDFS_SB_REV; 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; super.freelist.nfree = 0;
/* write inodes */ /* write inodes */
lseek(fd, 2 * STPDFS_BLOCK_SIZE, SEEK_SET); lseek(fd, 2 * STPDFS_BLOCK_SIZE, SEEK_SET);
@ -138,7 +199,7 @@ mkfs()
freeblock = blocks - (inodes + 2); freeblock = blocks - (inodes + 2);
for (nextfree = super.isize + 3; nextfree < freeblock; nextfree++) for (nextfree = super.isize + 3; nextfree < freeblock; nextfree++)
{ {
if (stpdfs_free_block(fd, &super, nextfree) != 0) if (free_block(fd, &super, nextfree) != 0)
{ {
fprintf(stderr, "error: %u\n", nextfree); fprintf(stderr, "error: %u\n", nextfree);
} }
@ -146,20 +207,20 @@ mkfs()
/* create root dir */ /* create root dir */
stpdfs_read(fd, 2, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK); stpdfs_read(fd, 2, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
inds[STPDFS_INO_ROOTDIR].modtime = time(NULL); inds[STPDFS_ROOTINO].modtime = time(NULL);
inds[STPDFS_INO_ROOTDIR].actime = time(NULL); inds[STPDFS_ROOTINO].actime = time(NULL);
inds[STPDFS_INO_ROOTDIR].size = sizeof(struct stpdfs_dirent) * 2; inds[STPDFS_ROOTINO].size = sizeof(struct stpdfs_dirent) * 2;
inds[STPDFS_INO_ROOTDIR].flags = STPDFS_INO_FLAG_ALOC; inds[STPDFS_ROOTINO].flags = STPDFS_INO_FLAG_ALOC;
inds[STPDFS_INO_ROOTDIR].mode = STPDFS_S_IFDIR; inds[STPDFS_ROOTINO].mode = STPDFS_S_IFDIR | STPDFS_S_IRUSR | STPDFS_S_IWUSR | STPDFS_S_IXUSR | STPDFS_S_IRGRP | STPDFS_S_IXGRP | STPDFS_S_IXOTH;
inds[STPDFS_INO_ROOTDIR].zones[0] = stpdfs_alloc_block(fd, &super); inds[STPDFS_ROOTINO].zones[0] = alloc_block(fd, &super);
inds[STPDFS_INO_ROOTDIR].size = sizeof(struct stpdfs_dirent) * 2; inds[STPDFS_ROOTINO].size = sizeof(struct stpdfs_dirent) * 2;
stpdfs_read(fd, inds[STPDFS_INO_ROOTDIR].zones[0], rootdirent, sizeof(struct stpdfs_dirent) * 2); stpdfs_read(fd, inds[STPDFS_ROOTINO].zones[0], rootdirent, sizeof(struct stpdfs_dirent) * 2);
strcpy(rootdirent[0].filename, "."); strcpy(rootdirent[0].filename, ".");
rootdirent[1].inode = 1; rootdirent[1].inode = 1;
strcpy(rootdirent[1].filename, ".."); strcpy(rootdirent[1].filename, "..");
rootdirent[1].inode = 1; rootdirent[1].inode = 1;
inds[STPDFS_INO_ROOTDIR].nlink += 2; inds[STPDFS_ROOTINO].nlink += 2;
stpdfs_write(fd, inds[STPDFS_INO_ROOTDIR].zones[0], rootdirent, sizeof(struct stpdfs_dirent) * 2); stpdfs_write(fd, inds[STPDFS_ROOTINO].zones[0], rootdirent, sizeof(struct stpdfs_dirent) * 2);
stpdfs_write(fd, 2, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK); stpdfs_write(fd, 2, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
/* write super block */ /* write super block */
@ -167,6 +228,11 @@ mkfs()
super.state = STPDFS_CLEANLY_UNMOUNTED; super.state = STPDFS_CLEANLY_UNMOUNTED;
stpdfs_write(fd, 1, &super, sizeof(struct stpdfs_sb)); stpdfs_write(fd, 1, &super, sizeof(struct stpdfs_sb));
if (bootable)
{
stpdfs_write(fd, 0, (void *)_binary_mkfs_boot_o_start, STPDFS_BLOCK_SIZE);
}
/* we finished \o/ */ /* we finished \o/ */
printf("StupidFS: %u blocks (%u Inodes)\n", super.fsize, super.isize); printf("StupidFS: %u blocks (%u Inodes)\n", super.fsize, super.isize);
@ -188,9 +254,9 @@ main(int argc, char **argv)
#endif /* HAVE_LIBGEN_H */ #endif /* HAVE_LIBGEN_H */
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION) #if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
while ((c = getopt_long(argc, argv, "hVi:", long_options, &idx)) != EOF) while ((c = getopt_long(argc, argv, "hVbi:", long_options, &idx)) != EOF)
#else #else
while ((c = getopt(argc, argv, "hVi:")) != EOF) while ((c = getopt(argc, argv, "hVbi:")) != EOF)
#endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */ #endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */
{ {
switch (c) switch (c)
@ -201,6 +267,9 @@ main(int argc, char **argv)
case 'V': case 'V':
version(); version();
break; break;
case 'b':
bootable = 1;
break;
case 'i': case 'i':
inodes = atoi(optarg); inodes = atoi(optarg);
break; break;

24
tools/tools/copy.c Normal file
View file

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif /* HAVE_LIBGEN_H */
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#endif /* HAVE_GETOPT_H */
static void
usage(void)
{
}
int
copy(int argc, char **argv)
{
return (EXIT_SUCCESS);
}

24
tools/tools/ls.c Normal file
View file

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif /* HAVE_LIBGEN_H */
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#endif /* HAVE_GETOPT_H */
static void
usage(void)
{
}
int
ls(int argc, char **argv)
{
return (EXIT_SUCCESS);
}

View file

@ -1,5 +1,102 @@
int #include <stdio.h>
main(void) #include <stdlib.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif /* HAVE_LIBGEN_H */
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#endif /* HAVE_GETOPT_H */
#include "tools.h"
struct command {
const char *name;
int (*cmd)(int argc, char **argv);
};
struct command commands[] = {
{"ls", &ls},
{"copy", &copy},
{NULL, NULL}
};
static const char *prg_name;
static void
usage(int retval)
{ {
return (0); int idx;
if (retval == EXIT_FAILURE)
{
fprintf(stderr, "Try '%s -h' for more information.\n", prg_name);
}
else
{
printf("Usage: %s COMMAND [OPTIONS]\n\n", prg_name);
printf("Commands:\n");
printf("\t");
for (idx = 0; commands[idx].name != NULL; idx++)
{
printf("%s ", commands[idx].name);
}
printf("\n");
printf("For more details see tools.stpd(8).\n");
}
exit(retval);
}
static void
version(void)
{
printf("%s (%s) %s\n", prg_name, PACKAGE_NAME, PACKAGE_VERSION);
exit(EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
int idx;
#ifdef HAVE_LIBGEN_H
prg_name = basename(argv[0]);
#else
prg_name = argv[0];
#endif /* HAVE_LIBGEN_H */
if (argc < 2)
{
usage(EXIT_FAILURE);
}
if (argv[1][0] == '-')
{
switch(argv[1][1])
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
default:
usage(EXIT_FAILURE);
break;
}
}
for (idx = 0; commands[idx].name != NULL; idx++)
{
if (strcmp(argv[1], commands[idx].name) == 0)
{
return (commands[idx].cmd(argc-1, argv+1));
}
}
return (EXIT_FAILURE);
} }

7
tools/tools/tools.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef TOOLS_H
# define TOOLS_H 1
int ls(int argc, char **argv);
int copy(int argc, char **argv);
#endif /* !TOOLS_H */