feat(tools/mkfs): write root directory
This commit is contained in:
parent
ac9c46bf24
commit
4c730f50f8
69
lib/block.c
69
lib/block.c
|
@ -1,26 +1,85 @@
|
||||||
#include "stpdfs.h"
|
#include "stpdfs.h"
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
stpdfs_write(int fd, uint32_t blocknum, void *data, size_t size)
|
stpdfs_write(int fd, uint32_t blocknum, void *data, size_t size)
|
||||||
{
|
{
|
||||||
return (0);
|
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
|
size_t
|
||||||
stpdfs_read(int fd, uint32_t blocknum, void *data, size_t size)
|
stpdfs_read(int fd, uint32_t blocknum, void *data, size_t size)
|
||||||
{
|
{
|
||||||
return (0);
|
lseek(fd, blocknum * STPDFS_BLOCK_SIZE, SEEK_SET);
|
||||||
|
|
||||||
|
return (read(fd, data, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
stpdfs_alloc_block(int fd)
|
stpdfs_alloc_block(int fd, struct stpdfs_sb *sb)
|
||||||
{
|
{
|
||||||
return (0);
|
uint32_t blocknum;
|
||||||
|
struct stpdfs_free freelist;
|
||||||
|
|
||||||
|
sb->state = STPDFS_DIRTY; /* mark state dirty */
|
||||||
|
redo:
|
||||||
|
sb->nfree--;
|
||||||
|
blocknum = sb->free[sb->nfree];
|
||||||
|
if (sb->nfree == 0 && blocknum != 0)
|
||||||
|
{
|
||||||
|
stpdfs_read(fd, blocknum, &freelist, sizeof(struct stpdfs_free));
|
||||||
|
memcpy(sb->free, &freelist, sizeof(uint32_t) * 100);
|
||||||
|
sb->nfree = freelist.nfree;
|
||||||
|
goto redo;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb->time = time(NULL);
|
||||||
|
|
||||||
|
return (blocknum);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
stpdfs_free_block(int fd)
|
stpdfs_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->nfree == 100)
|
||||||
|
{
|
||||||
|
memcpy(©, sb->free, sizeof(uint32_t) * 100);
|
||||||
|
copy.nfree = sb->nfree;
|
||||||
|
|
||||||
|
stpdfs_write(fd, blocknum, ©, sizeof(struct stpdfs_free));
|
||||||
|
|
||||||
|
sb->nfree = 1;
|
||||||
|
sb->free[0] = blocknum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb->free[sb->nfree++] = blocknum;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb->time = time(NULL);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
67
lib/inode.c
67
lib/inode.c
|
@ -1,10 +1,71 @@
|
||||||
#include "stpdfs.h"
|
#include "stpdfs.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
alloc_inode(int fd)
|
stpdfs_locate_inode(uint32_t inode)
|
||||||
{
|
{
|
||||||
uint32_t start = 1;
|
return (2 + inode / STPDFS_INODES_PER_BLOCK);
|
||||||
uint32_t block;
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_read_inode()
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_write_inode()
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
stpdfd_alloc_inode(int fd, struct stpdfs_sb *sb)
|
||||||
|
{
|
||||||
|
uint32_t start = 2;
|
||||||
|
uint32_t blocknum;
|
||||||
|
struct stpdfs_inode inodes[STPDFS_INODES_PER_BLOCK];
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
blocknum = 2;
|
||||||
|
|
||||||
|
for (blocknum = 2; (blocknum - 2) < sb->isize; blocknum++)
|
||||||
|
{
|
||||||
|
stpdfs_read(fd, blocknum, inodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
||||||
|
|
||||||
|
for (idx = (start % STPDFS_INODES_PER_BLOCK); idx < STPDFS_INODES_PER_BLOCK; idx++)
|
||||||
|
{
|
||||||
|
if (!(inodes[start].flags & STPDFS_INO_FLAG_ALOC))
|
||||||
|
{
|
||||||
|
inodes[start].flags |= STPDFS_INO_FLAG_ALOC;
|
||||||
|
return (start);
|
||||||
|
}
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_free_inode(int fd, struct stpdfs_sb *sb, uint32_t ino)
|
||||||
|
{
|
||||||
|
uint32_t blocknum;
|
||||||
|
struct stpdfs_inode inodes[STPDFS_INODES_PER_BLOCK];
|
||||||
|
|
||||||
|
blocknum = 2 + ino / STPDFS_INODES_PER_BLOCK;
|
||||||
|
if (blocknum >= sb->fsize || (blocknum - 2) >= sb->isize)
|
||||||
|
{
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb->state = STPDFS_DIRTY;
|
||||||
|
|
||||||
|
stpdfs_read(fd, blocknum, inodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
||||||
|
|
||||||
|
memset(&inodes[ino % STPDFS_INODES_PER_BLOCK], 0, sizeof(struct stpdfs_inode));
|
||||||
|
|
||||||
|
stpdfs_write(fd, blocknum, inodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
10
lib/stpdfs.h
10
lib/stpdfs.h
|
@ -8,6 +8,8 @@
|
||||||
# define STPDFS_SB_REV STPDFS_SB_REV_1
|
# define STPDFS_SB_REV STPDFS_SB_REV_1
|
||||||
# define STPDFS_SB_REV_1 1
|
# define STPDFS_SB_REV_1 1
|
||||||
|
|
||||||
|
# define STPDFS_INO_ROOTDIR 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)
|
||||||
|
|
||||||
|
@ -35,7 +37,8 @@ struct stpdfs_free {
|
||||||
|
|
||||||
enum stpdfs_state {
|
enum stpdfs_state {
|
||||||
STPDFS_CLEANLY_UNMOUNTED = 0,
|
STPDFS_CLEANLY_UNMOUNTED = 0,
|
||||||
STPDFS_ERROR = 1
|
STPDFS_ERROR = 1,
|
||||||
|
STPDFS_DIRTY = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,9 +86,14 @@ struct stpdfs_dirent {
|
||||||
size_t stpdfs_write(int fd, uint32_t blocknum, void *data, size_t size);
|
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);
|
size_t stpdfs_read(int fd, uint32_t blocknum, void *data, size_t size);
|
||||||
|
|
||||||
|
uint32_t stpdfs_alloc_block(int fd, struct stpdfs_sb *sb);
|
||||||
|
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
|
||||||
|
|
||||||
/* superblock.c */
|
/* superblock.c */
|
||||||
int stpdfs_superblock_valid(const struct stpdfs_sb *sb);
|
int stpdfs_superblock_valid(const struct stpdfs_sb *sb);
|
||||||
int stpdfs_read_superblock(int fd, struct stpdfs_sb *sb);
|
int stpdfs_read_superblock(int fd, struct stpdfs_sb *sb);
|
||||||
|
|
||||||
|
/* inode.c */
|
||||||
|
uint32_t stpdfd_alloc_inode(int fd, struct stpdfs_sb *sb);
|
||||||
|
|
||||||
#endif /* !STPDFS_H */
|
#endif /* !STPDFS_H */
|
|
@ -1,4 +1,5 @@
|
||||||
AM_CFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir)
|
AM_CFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir)
|
||||||
|
LDADD = ../lib/libstpdfs.a
|
||||||
|
|
||||||
bin_PROGRAMS = mkfs.stpd
|
bin_PROGRAMS = mkfs.stpd
|
||||||
|
|
||||||
|
|
|
@ -74,26 +74,6 @@ 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(©, super.free, sizeof(uint32_t) * 100);
|
|
||||||
copy.nfree = super.nfree;
|
|
||||||
lseek(fd, num * STPDFS_BLOCK_SIZE, SEEK_SET);
|
|
||||||
write_block(fd, ©, sizeof(struct stpdfs_free));
|
|
||||||
super.nfree = 1;
|
|
||||||
super.free[0] = num;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
super.free[super.nfree++] = num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mkfs()
|
mkfs()
|
||||||
|
@ -140,8 +120,6 @@ mkfs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_block(fd, NULL, 0);
|
|
||||||
|
|
||||||
super.magic = STPDFS_SB_MAGIC;
|
super.magic = STPDFS_SB_MAGIC;
|
||||||
super.revision = STPDFS_SB_REV;
|
super.revision = STPDFS_SB_REV;
|
||||||
super.isize = inodes / STPDFS_INODES_PER_BLOCK;
|
super.isize = inodes / STPDFS_INODES_PER_BLOCK;
|
||||||
|
@ -151,36 +129,44 @@ mkfs()
|
||||||
/* write inodes */
|
/* write inodes */
|
||||||
lseek(fd, 2 * STPDFS_BLOCK_SIZE, SEEK_SET);
|
lseek(fd, 2 * STPDFS_BLOCK_SIZE, SEEK_SET);
|
||||||
memset(&inds, 0, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
memset(&inds, 0, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
||||||
inds[1].modtime = time(NULL);
|
for (idx = 0; idx < super.isize; idx++)
|
||||||
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);
|
if (write_block(fd, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set free blocks */
|
||||||
freeblock = blocks - (inodes + 2);
|
freeblock = blocks - (inodes + 2);
|
||||||
for (nextfree = super.isize + 3; nextfree < freeblock; nextfree++)
|
for (nextfree = super.isize + 3; nextfree < freeblock; nextfree++)
|
||||||
{
|
{
|
||||||
add_free_block(fd, nextfree);
|
if (stpdfs_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_INO_ROOTDIR].modtime = time(NULL);
|
||||||
|
inds[STPDFS_INO_ROOTDIR].actime = time(NULL);
|
||||||
|
inds[STPDFS_INO_ROOTDIR].size = sizeof(struct stpdfs_dirent) * 2;
|
||||||
|
inds[STPDFS_INO_ROOTDIR].flags = STPDFS_INO_FLAG_ALOC;
|
||||||
|
inds[STPDFS_INO_ROOTDIR].mode = STPDFS_S_IFDIR;
|
||||||
|
inds[STPDFS_INO_ROOTDIR].zones[0] = stpdfs_alloc_block(fd, &super);
|
||||||
|
inds[STPDFS_INO_ROOTDIR].size = sizeof(struct stpdfs_dirent) * 2;
|
||||||
|
stpdfs_read(fd, inds[STPDFS_INO_ROOTDIR].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;
|
||||||
|
stpdfs_write(fd, inds[STPDFS_INO_ROOTDIR].zones[0], rootdirent, sizeof(struct stpdfs_dirent) * 2);
|
||||||
|
stpdfs_write(fd, 2, &inds, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
||||||
|
|
||||||
/* write super block */
|
/* write super block */
|
||||||
lseek(fd, 1 * STPDFS_BLOCK_SIZE, SEEK_SET);
|
|
||||||
super.time = time(NULL);
|
super.time = time(NULL);
|
||||||
super.state = STPDFS_CLEANLY_UNMOUNTED;
|
super.state = STPDFS_CLEANLY_UNMOUNTED;
|
||||||
write_block(fd, &super, sizeof(struct stpdfs_sb));
|
stpdfs_write(fd, 1, &super, sizeof(struct stpdfs_sb));
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
Loading…
Reference in a new issue