feat: mkfs.stpd (WIP)

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-06-12 13:08:50 +02:00
parent 1454a739d0
commit ec0bd60a10
8 changed files with 244 additions and 34 deletions

4
.gitignore vendored
View file

@ -28,4 +28,6 @@ src/stpdfs-fuse
Debug/
.vs/
html/
html/
.dirstamp
mkfs.stpd

View file

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

View file

@ -14,6 +14,8 @@ AC_PROG_INSTALL
AC_PROG_RANLIB
AM_PROG_CC_C_O
AC_CONFIG_HEADERS([config.h])
AS_IF([ test "x$host_os" != "xmingw32" ], [
PKG_CHECK_MODULES([FUSE], [fuse3])
])
@ -26,8 +28,23 @@ AC_CHECK_INCLUDES_DEFAULT
AC_C_CONST
AC_C_INLINE
AC_CHECK_HEADERS(m4_normalize([
libgen.h
getopt.h
]))
AC_CHECK_TYPES([struct option], [], [],
[#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif])
AC_CHECK_FUNCS(m4_normalize([
getopt_long
]))
AC_CONFIG_FILES([Makefile
lib/Makefile
tools/Makefile
linux/Makefile
fuse/Makefile])

View file

@ -1,4 +1,3 @@
#include <cstdint>
#ifndef STPDFS_H
# define STPDFS_H 1
@ -6,15 +5,16 @@
# define STPDFS_SB_MAGIC 0x44505453
# define STPDFS_BLOCK_SIZE 512
# define STPDFS_BLOCK_SIZE_BITS 10
# define STPDFS_BLOCK_SIZE (1 << STPDFS_BLOCK_SIZE_BITS)
# define STPDFS_NAME_MAX 255
# define STPDFS_INODES_PER_BLOCK (STPDFS_BLOCK_SIZE / (sizeof(struct stpdfs_inode)))
# define STPDFS_LZP_COMPRESSION (1 << 0)
# define STPDFS_FILE_ENCRYPTION (1 << 1)
typedef uint32_t stpdfs_addr_t;
typedef uint32_t stpdfs_off_t;
typedef uint64_t stpdfs_time_t;
struct stpdfs_free {
uint32_t free[100];
uint8_t nfree;
@ -25,24 +25,24 @@ struct stpdfs_free {
*/
struct stpdfs_sb {
uint32_t magic;
uint32_t isize;
uint32_t fsize;
uint32_t isize; /*< size in block of the I list */
uint32_t fsize; /*< size in block of the entire volume */
uint32_t free[100];
uint8_t nfree;
uint8_t nfree; /*< number of free block (0-100) */
uint8_t flock;
uint8_t ilock;
uint8_t fmod;
uint32_t time[2];
uint64_t time;
} __attribute__((packed));
/**
* \brief StupidFS I-node
*/
struct inode {
uint16_t mode;
uint8_t nlink;
uint8_t uid;
uint8_t gid;
uint16_t mode; /*< file mode */
uint8_t nlink; /*< link count */
uint8_t uid; /*< owner user id */
uint8_t gid; /*< group id */
uint32_t size;
uint16_t addr[8];
uint32_t actime[2];
@ -56,6 +56,4 @@ struct file {
char filename[32];
};
#endif /* !STPDFS_H */

View file

@ -1,16 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
static const char *prg_name;
void
usage(int retval)
{
}
int
main(void)
{
return (EXIT_SUCCESS);
}

7
tools/Makefile.am Normal file
View file

@ -0,0 +1,7 @@
AM_CFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir)
bin_PROGRAMS = mkfs.stpd
mkfs_stpd_SOURCES = mkfs/main.c
man_MANS = mkfs/mkfs.stpd.8

173
tools/mkfs/main.c Normal file
View file

@ -0,0 +1,173 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stpdfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.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 const char *prg_name;
static int inodes = -1;
static const char *device;
static int blocks = -1;
static struct stpdfs_sb super;
#ifdef HAVE_STRUCT_OPTION
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"inodes", required_argument, 0, 'i'},
{0, 0, 0, 0}
};
#endif /* HAVE_STRUCT_OPTION */
static void
usage(int retval)
{
if (retval == EXIT_FAILURE)
{
fprintf(stderr, "Try '%s -h' for more information.\n", prg_name);
}
else
{
printf("Usage: %s [options] /dev/name [blocks]\n\n", prg_name);
printf("Options:\n");
printf(" -i, --inode <num> number of inodes for the filesystem\n");
printf(" -h, --help display this help\n");
printf(" -V, --version display version\n\n");
printf("For more details see mkfs.stpd(8).\n");
}
exit(retval);
}
static void
version(void)
{
printf("%s (%s) %s\n", prg_name, PACKAGE_NAME, PACKAGE_VERSION);
exit(EXIT_SUCCESS);
}
static int
write_block(int fd, void *data, size_t size)
{
uint8_t buffer[STPDFS_BLOCK_SIZE];
memset(buffer, 0, STPDFS_BLOCK_SIZE);
if (data)
{
memcpy(buffer, data, size);
}
return (write(fd, buffer, STPDFS_BLOCK_SIZE) == STPDFS_BLOCK_SIZE);
}
static int
mkfs()
{
struct stat statbuf;
int fd;
int dev_block;
if (stat(device, &statbuf) < 0)
{
perror(device);
return (EXIT_FAILURE);
}
fd = open(device, O_RDWR);
if (fd < 0)
{
perror(device);
return (EXIT_FAILURE);
}
dev_block = statbuf.st_size / STPDFS_BLOCK_SIZE;
printf("device blocks: %d\n", dev_block);
if (blocks < 0)
{
blocks = dev_block;
}
if (inodes <= 0)
{
if (512 * 1024 < blocks)
{
inodes = blocks / 8;
}
else
{
inodes = blocks / 3;
}
}
write_block(fd, NULL, 0);
super.magic = STPDFS_SB_MAGIC;
super.fsize = blocks;
write_block(fd, &super, sizeof(struct stpdfs_sb));
close(fd);
return (EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
int idx;
int c;
#ifdef HAVE_LIBGEN_H
prg_name = basename(argv[0]);
#else
prg_name = argv[0];
#endif /* HAVE_LIBGEN_H */
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
while ((c = getopt_long(argc, argv, "hVi:", long_options, &idx)) != EOF)
#else
while ((c = getopt(argc, argv, "hVi:")) != EOF)
#endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */
{
switch (c)
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
case 'i':
inodes = atoi(optarg);
break;
default:
usage(EXIT_FAILURE);
break;
}
}
if (optind >= argc)
{
usage(EXIT_FAILURE);
}
device = argv[optind++];
if (optind < argc)
{
blocks = atoi(argv[optind]);
}
return (mkfs());
}

29
tools/mkfs/mkfs.stpd.8 Normal file
View file

@ -0,0 +1,29 @@
.Dd $Mdocdate$
.Dt MKFS.STPD 8
.Os
.Sh NAME
.Nm mkfs.stpd
.Nd create a Stupid filesystem on a device.
.Sh SYNOPSIS
.Nm mkfs.stpd
.Op Fl V
.Op Fl h
.Op Fl i Ar num
.Ar device
.Op blocks
.Sh DESCRIPTION
.Bl -tag -width Ds
.It Fl h
Display help menu.
.It Fl i
Number of inodes for the filesystem.
.It Fl V
Display version information.
.El
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr stupidfs 3
.Sh AUTHORS
.An -nosplit
.An d0p1 Aq Mt contact@d0p1.eu