feat(tools): inspect, dump superblock
This commit is contained in:
parent
43da2b6b53
commit
a9874daf28
|
@ -62,7 +62,7 @@
|
||||||
struct stpdfs_free {
|
struct stpdfs_free {
|
||||||
uint32_t free[100]; /**< List of free block (0-99), index 0 point to next freelist */
|
uint32_t free[100]; /**< List of free block (0-99), index 0 point to next freelist */
|
||||||
uint8_t nfree; /**< index */
|
uint8_t nfree; /**< index */
|
||||||
} __attribute__((packed));
|
};
|
||||||
|
|
||||||
enum stpdfs_state {
|
enum stpdfs_state {
|
||||||
STPDFS_CLEANLY_UNMOUNTED = 0,
|
STPDFS_CLEANLY_UNMOUNTED = 0,
|
||||||
|
|
|
@ -42,7 +42,6 @@ redo:
|
||||||
int
|
int
|
||||||
fs_bfree(struct fs_super *super, uint32_t blocknum)
|
fs_bfree(struct fs_super *super, uint32_t blocknum)
|
||||||
{
|
{
|
||||||
struct stpdfs_free copy;
|
|
||||||
struct fs_buffer *buff;
|
struct fs_buffer *buff;
|
||||||
|
|
||||||
if (blocknum == 0 || blocknum >= super->sb.fsize)
|
if (blocknum == 0 || blocknum >= super->sb.fsize)
|
||||||
|
|
|
@ -59,7 +59,7 @@ fs_bio_bread(int fd, uint32_t blocknum)
|
||||||
void
|
void
|
||||||
fs_bio_bwrite(struct fs_buffer *buff)
|
fs_bio_bwrite(struct fs_buffer *buff)
|
||||||
{
|
{
|
||||||
fs_bio_raw_read(buff->fd, buff->blocknum, buff->data, STPDFS_BLOCK_SIZE);
|
fs_bio_raw_write(buff->fd, buff->blocknum, buff->data, STPDFS_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -88,15 +88,3 @@ fs_bio_brelse(struct fs_buffer *buff)
|
||||||
|
|
||||||
free(buff);
|
free(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
stpdfs_bpin(struct fs_buffer *buff)
|
|
||||||
{
|
|
||||||
buff->refcount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
stpdfs_bunpin(struct fs_buffer *buff)
|
|
||||||
{
|
|
||||||
buff->refcount--;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stupidfs.h>
|
#include <stupidfs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
fs_bio_raw_write(int fd, uint32_t blocknum, void *data, size_t size)
|
fs_bio_raw_write(int fd, uint32_t blocknum, void *data, size_t size)
|
||||||
|
|
|
@ -11,21 +11,25 @@ fs_super_valide(struct stpdfs_sb *sb)
|
||||||
{
|
{
|
||||||
if (sb->magic != STPDFS_SB_MAGIC)
|
if (sb->magic != STPDFS_SB_MAGIC)
|
||||||
{
|
{
|
||||||
|
printf("bad magic\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb->revision != STPDFS_SB_REV)
|
if (sb->revision != STPDFS_SB_REV)
|
||||||
{
|
{
|
||||||
|
printf("bad rev\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb->fsize == 0 || sb->isize == 0)
|
if (sb->fsize == 0 || sb->isize == 0)
|
||||||
{
|
{
|
||||||
|
printf("size null\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb->isize > sb->fsize)
|
if (sb->isize > sb->fsize)
|
||||||
{
|
{
|
||||||
|
printf("invalid size\n");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +41,7 @@ fs_super_open(struct fs_super *super, const char *fname)
|
||||||
{
|
{
|
||||||
struct fs_buffer *buff;
|
struct fs_buffer *buff;
|
||||||
|
|
||||||
super->fd = open(fname, O_RDWR);
|
super->fd = open(fname, O_RDWR | O_BINARY);
|
||||||
if (super->fd < 0)
|
if (super->fd < 0)
|
||||||
{
|
{
|
||||||
perror(fname);
|
perror(fname);
|
||||||
|
@ -48,6 +52,9 @@ fs_super_open(struct fs_super *super, const char *fname)
|
||||||
if (!buff) goto err;
|
if (!buff) goto err;
|
||||||
|
|
||||||
memcpy(&super->sb, buff->data, sizeof(struct stpdfs_sb));
|
memcpy(&super->sb, buff->data, sizeof(struct stpdfs_sb));
|
||||||
|
|
||||||
|
fs_bio_brelse(buff);
|
||||||
|
|
||||||
if (fs_super_valide(&super->sb) != 0) goto err;
|
if (fs_super_valide(&super->sb) != 0) goto err;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -11,5 +11,6 @@ struct fs_super {
|
||||||
|
|
||||||
|
|
||||||
int fs_super_kill(struct fs_super *super);
|
int fs_super_kill(struct fs_super *super);
|
||||||
|
int fs_super_open(struct fs_super *super, const char *fname);
|
||||||
|
|
||||||
#endif /* !FS_SUPER_H */
|
#endif /* !FS_SUPER_H */
|
|
@ -39,7 +39,7 @@ stpdfs_super_open(struct stpdfs_super_info *sbi, const char *fname)
|
||||||
{
|
{
|
||||||
struct stpdfs_buffer *buff;
|
struct stpdfs_buffer *buff;
|
||||||
|
|
||||||
sbi->fd = open(fname, O_RDWR);
|
sbi->fd = open(fname, O_RDWR | O_BINARY);
|
||||||
if (sbi->fd < 0)
|
if (sbi->fd < 0)
|
||||||
{
|
{
|
||||||
perror(fname);
|
perror(fname);
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)
|
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)
|
||||||
LDADD = ../libstpdfs/libstpdfs.a ../libfs/libfs.a
|
LDADD = ../libstpdfs/libstpdfs.a ../libfs/libfs.a
|
||||||
|
|
||||||
bin_PROGRAMS = mkfs.stpd tools.stpd
|
bin_PROGRAMS = mkfs.stpd tools.stpd inspect.stpd
|
||||||
|
|
||||||
mkfs_stpd_SOURCES = mkfs/main.c
|
mkfs_stpd_SOURCES = mkfs/main.c
|
||||||
mkfs_stpd_LDADD = ../libfs/libfs.a mkfs/bootsector.o
|
mkfs_stpd_LDADD = ../libfs/libfs.a mkfs/bootsector.o
|
||||||
|
|
||||||
tools_stpd_SOURCES = tools/main.c tools/ls.c tools/copy.c
|
tools_stpd_SOURCES = tools/main.c tools/ls.c tools/copy.c
|
||||||
|
|
||||||
|
inspect_stpd_SOURCES = inspect/main.c
|
||||||
|
|
||||||
mkfs/boot.o: mkfs/boot.asm
|
mkfs/boot.o: mkfs/boot.asm
|
||||||
$(NASM) -fbin -o $@ $<
|
$(NASM) -fbin -o $@ $<
|
||||||
|
|
||||||
|
|
164
tools/inspect/main.c
Normal file
164
tools/inspect/main.c
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
#include "libfs/inode.h"
|
||||||
|
#include "libfs/super.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.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 <libfs/fs.h>
|
||||||
|
|
||||||
|
static const char *prg_name;
|
||||||
|
static const char *device;
|
||||||
|
static int inode = -1;
|
||||||
|
static int block = -1;
|
||||||
|
static int super = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_OPTION
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"version", no_argument, 0, 'V'},
|
||||||
|
{"inode", required_argument, 0, 'i'},
|
||||||
|
{"block", required_argument, 0, 'b'},
|
||||||
|
{"super", no_argument, 0, 's'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
#endif /* HAVE_STRUCT_OPTION */
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
inspect(void)
|
||||||
|
{
|
||||||
|
struct fs_super sb;
|
||||||
|
struct fs_inode *ip;
|
||||||
|
time_t time;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (fs_super_open(&sb, device) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Bad super\n");
|
||||||
|
return (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (super)
|
||||||
|
{
|
||||||
|
printf("Super:\n");
|
||||||
|
printf(" magic: %x\n", sb.sb.magic);
|
||||||
|
printf(" isize: %u\n", sb.sb.isize);
|
||||||
|
printf(" fsize: %u\n", sb.sb.fsize);
|
||||||
|
printf(" freelist:\n");
|
||||||
|
for (idx = 0; idx < sb.sb.freelist.nfree; idx++)
|
||||||
|
{
|
||||||
|
printf("\tblock[%02u]: %x\n", idx, sb.sb.freelist.free[idx]);
|
||||||
|
}
|
||||||
|
printf(" revision: %u\n", sb.sb.revision);
|
||||||
|
printf(" state: %hu\n", sb.sb.state);
|
||||||
|
time = sb.sb.time;
|
||||||
|
printf(" time: %s", ctime(&time));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inode > 0)
|
||||||
|
{
|
||||||
|
ip = fs_inode_get(&sb, inode);
|
||||||
|
if (ip->valid == 0)
|
||||||
|
{
|
||||||
|
fs_inode_read(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Inode %d:\n", inode);
|
||||||
|
printf(" mode: %ho\n", ip->inode.mode);
|
||||||
|
printf(" nlink: %hu\n", ip->inode.nlink);
|
||||||
|
printf(" size: %u\n", ip->inode.size);
|
||||||
|
time = ip->inode.actime;
|
||||||
|
printf(" actime: %s", ctime(&time));
|
||||||
|
time = ip->inode.modtime;
|
||||||
|
printf(" modtime: %s", ctime(&time));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fs_super_kill(&sb);
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
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\n\n", prg_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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:b:s", long_options, &idx)) != EOF)
|
||||||
|
#else
|
||||||
|
while ((c = getopt(argc, argv, "hVi:b:s")) != EOF)
|
||||||
|
#endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
usage(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
version();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
inode = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
block = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
super = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind >= argc)
|
||||||
|
{
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
device = argv[optind];
|
||||||
|
|
||||||
|
return (inspect());
|
||||||
|
}
|
|
@ -81,7 +81,7 @@ create_create_super(struct fs_super *super)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
super->fd = open(device, O_RDWR);
|
super->fd = open(device, O_RDWR | O_BINARY);
|
||||||
if (super->fd < 0)
|
if (super->fd < 0)
|
||||||
{
|
{
|
||||||
perror(device);
|
perror(device);
|
||||||
|
@ -132,7 +132,10 @@ mkfs()
|
||||||
memset(dinodes, 0, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
memset(dinodes, 0, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
||||||
for (idx = 2; idx < (super.sb.isize + 2); idx++)
|
for (idx = 2; idx < (super.sb.isize + 2); idx++)
|
||||||
{
|
{
|
||||||
if (fs_bio_raw_write(super.fd, idx, dinodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK));
|
if (fs_bio_raw_write(super.fd, idx, dinodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK) != sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "wtf?:");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set free blocks */
|
/* set free blocks */
|
||||||
|
@ -154,6 +157,7 @@ mkfs()
|
||||||
|
|
||||||
rootip->inode.modtime = time(NULL);
|
rootip->inode.modtime = time(NULL);
|
||||||
rootip->inode.actime = time(NULL);
|
rootip->inode.actime = time(NULL);
|
||||||
|
memset(rootip->inode.zones, 0, sizeof(uint32_t) * 10);
|
||||||
rootip->inode.size = 0;
|
rootip->inode.size = 0;
|
||||||
rootip->inode.flags = STPDFS_INO_FLAG_ALOC;
|
rootip->inode.flags = STPDFS_INO_FLAG_ALOC;
|
||||||
rootip->inode.mode = STPDFS_S_IFDIR | STPDFS_S_IRUSR | STPDFS_S_IWUSR | STPDFS_S_IXUSR | STPDFS_S_IRGRP | STPDFS_S_IXGRP | STPDFS_S_IXOTH;
|
rootip->inode.mode = STPDFS_S_IFDIR | STPDFS_S_IRUSR | STPDFS_S_IWUSR | STPDFS_S_IXUSR | STPDFS_S_IRGRP | STPDFS_S_IXGRP | STPDFS_S_IXOTH;
|
||||||
|
|
|
@ -1,293 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <libstpdfs/stpdfs.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 int bootable = 0;
|
|
||||||
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
|
|
||||||
static struct option long_options[] = {
|
|
||||||
{"help", no_argument, 0, 'h'},
|
|
||||||
{"version", no_argument, 0, 'V'},
|
|
||||||
{"boot", no_argument, 0, 'b'},
|
|
||||||
{"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(" -b, --boot make filesystem bootable\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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(©, sb->freelist.free, sizeof(uint32_t) * 100);
|
|
||||||
copy.nfree = sb->freelist.nfree;
|
|
||||||
|
|
||||||
stpdfs_write(fd, blocknum, ©, 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
|
|
||||||
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;
|
|
||||||
struct stpdfs_dirent rootdirent[2];
|
|
||||||
int fd;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
super.magic = STPDFS_SB_MAGIC;
|
|
||||||
super.revision = STPDFS_SB_REV;
|
|
||||||
super.isize = inodes / STPDFS_INODES_PER_BLOCK;
|
|
||||||
super.fsize = blocks;
|
|
||||||
super.freelist.nfree = 0;
|
|
||||||
|
|
||||||
/* write inodes */
|
|
||||||
lseek(fd, 2 * STPDFS_BLOCK_SIZE, SEEK_SET);
|
|
||||||
memset(&inds, 0, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
|
||||||
for (idx = 0; idx < super.isize; idx++)
|
|
||||||
{
|
|
||||||
if (write_block(fd, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set free blocks */
|
|
||||||
freeblock = blocks - (inodes + 2);
|
|
||||||
for (nextfree = super.isize + 3; nextfree < freeblock; nextfree++)
|
|
||||||
{
|
|
||||||
if (free_block(fd, &super, nextfree) != 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "error: %u\n", nextfree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create root dir */
|
|
||||||
stpdfs_read(fd, 2, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
|
||||||
inds[STPDFS_ROOTINO].modtime = time(NULL);
|
|
||||||
inds[STPDFS_ROOTINO].actime = time(NULL);
|
|
||||||
inds[STPDFS_ROOTINO].size = sizeof(struct stpdfs_dirent) * 2;
|
|
||||||
inds[STPDFS_ROOTINO].flags = STPDFS_INO_FLAG_ALOC;
|
|
||||||
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_ROOTINO].zones[0] = alloc_block(fd, &super);
|
|
||||||
inds[STPDFS_ROOTINO].size = sizeof(struct stpdfs_dirent) * 2;
|
|
||||||
stpdfs_read(fd, inds[STPDFS_ROOTINO].zones[0], rootdirent, sizeof(struct stpdfs_dirent) * 2);
|
|
||||||
strcpy(rootdirent[0].filename, ".");
|
|
||||||
rootdirent[1].inode = 1;
|
|
||||||
strcpy(rootdirent[1].filename, "..");
|
|
||||||
rootdirent[1].inode = 1;
|
|
||||||
inds[STPDFS_ROOTINO].nlink += 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);
|
|
||||||
|
|
||||||
/* write super block */
|
|
||||||
super.time = time(NULL);
|
|
||||||
super.state = STPDFS_CLEANLY_UNMOUNTED;
|
|
||||||
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/ */
|
|
||||||
printf("StupidFS: %u blocks (%u Inodes)\n", super.fsize, super.isize);
|
|
||||||
|
|
||||||
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, "hVbi:", long_options, &idx)) != EOF)
|
|
||||||
#else
|
|
||||||
while ((c = getopt(argc, argv, "hVbi:")) != EOF)
|
|
||||||
#endif /* HAVE_GETOPT_LONG && HAVE_STRUCT_OPTION */
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 'h':
|
|
||||||
usage(EXIT_SUCCESS);
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
version();
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
bootable = 1;
|
|
||||||
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());
|
|
||||||
}
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
#include "libfs/fs.h"
|
||||||
|
#include "libfs/inode.h"
|
||||||
|
#include "libfs/super.h"
|
||||||
#include "stupidfs.h"
|
#include "stupidfs.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -44,25 +47,30 @@ usage(int retval)
|
||||||
static int
|
static int
|
||||||
do_ls(void)
|
do_ls(void)
|
||||||
{
|
{
|
||||||
struct stpdfs_super_info sbi;
|
struct fs_super super;
|
||||||
struct stpdfs_inode_info *ip;
|
struct fs_inode *ip;
|
||||||
struct stpdfs_dirent dirent;
|
struct stpdfs_dirent dirent;
|
||||||
size_t idx;
|
size_t idx;
|
||||||
|
|
||||||
if (stpdfs_super_open(&sbi, image))
|
if (fs_super_open(&super, image))
|
||||||
{
|
{
|
||||||
return (EXIT_FAILURE);
|
return (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = stpdfs_inode_get(&sbi, STPDFS_ROOTINO);
|
ip = fs_inode_get(&super, STPDFS_ROOTINO);
|
||||||
|
if (ip->valid == 0)
|
||||||
|
{
|
||||||
|
fs_inode_read(ip);
|
||||||
|
}
|
||||||
|
|
||||||
for (idx = 0; idx < ip->inode.size; idx += STPDFS_DIRENT_SIZE)
|
for (idx = 0; idx < ip->inode.size; idx += STPDFS_DIRENT_SIZE)
|
||||||
{
|
{
|
||||||
stpdfs_inode_read(ip, (uint8_t *)&dirent, idx, STPDFS_DIRENT_SIZE);
|
fs_read(ip, (uint8_t *)&dirent, idx, STPDFS_DIRENT_SIZE);
|
||||||
printf("%s\n", dirent.filename);
|
printf("%s\n", dirent.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
stpdfs_super_kill(&sbi);
|
fs_super_kill(&super);
|
||||||
return (EXIT_SUCCESS);
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue