Compare commits
2 commits
5186d32e63
...
7043ece1c3
Author | SHA1 | Date | |
---|---|---|---|
d0p1 🏳️⚧️ | 7043ece1c3 | ||
d0p1 🏳️⚧️ | c5f4b5878b |
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS = lib libcrypto liblzp tools
|
SUBDIRS = libstpdfs libcrypto liblzp tools
|
||||||
|
|
||||||
if BUILD_FUSE
|
if BUILD_FUSE
|
||||||
SUBDIRS += fuse
|
SUBDIRS += fuse
|
||||||
|
|
|
@ -164,6 +164,142 @@ struct inode {
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
|
\section{Dirent}
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=C]
|
||||||
|
struct stpdfs_dirent {
|
||||||
|
ino_t inode;
|
||||||
|
char filename[STPDFS_NAME_MAX];
|
||||||
|
};
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
\appendix
|
\appendix
|
||||||
|
|
||||||
|
\chapter{LZP implementation}
|
||||||
|
|
||||||
|
\section{Compression}
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=C]
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define LZP_HASH_ORDER 16
|
||||||
|
#define LZP_HASH_SIZE (1 << LZP_HASH_ORDER)
|
||||||
|
|
||||||
|
#define HASH(h, x) ((h << 4) ^ x)
|
||||||
|
|
||||||
|
void
|
||||||
|
lzp_compress(uint8_t *out, size_t *outsz, const uint8_t *in, size_t insz)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
uint16_t hash;
|
||||||
|
uint32_t mask;
|
||||||
|
uint8_t table[LZP_HASH_SIZE] = { 0 };
|
||||||
|
size_t i, j;
|
||||||
|
size_t inpos;
|
||||||
|
size_t outpos;
|
||||||
|
uint8_t buff[9];
|
||||||
|
|
||||||
|
inpos = 0;
|
||||||
|
outpos = 0;
|
||||||
|
hash = 0;
|
||||||
|
while (inpos < insz)
|
||||||
|
{
|
||||||
|
j = 1;
|
||||||
|
mask = 0;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (inpos >= insz)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = in[inpos++];
|
||||||
|
|
||||||
|
if (table[hash] == c)
|
||||||
|
{
|
||||||
|
mask |= 1 << i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
table[hash] = c;
|
||||||
|
buff[j++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = HASH(hash, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
buff[0] = mask;
|
||||||
|
if (out != NULL)
|
||||||
|
{
|
||||||
|
memcpy(out + outpos, buff, j);
|
||||||
|
}
|
||||||
|
outpos += j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outsz = outpos;
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\section{Decompression}
|
||||||
|
\begin{lstlisting}[language=C]
|
||||||
|
void
|
||||||
|
lzp_decompress(uint8_t *out, size_t *outsz, const uint8_t *in, size_t insz)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
uint16_t hash = 0;
|
||||||
|
uint32_t mask = 0;
|
||||||
|
uint8_t table[LZP_HASH_SIZE] = { 0 };
|
||||||
|
size_t i, j;
|
||||||
|
size_t inpos;
|
||||||
|
size_t outpos;
|
||||||
|
uint8_t buff[9];
|
||||||
|
|
||||||
|
inpos = 0;
|
||||||
|
outpos = 0;
|
||||||
|
while (inpos < insz)
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
if (inpos >= insz)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = in[inpos++];
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if ((mask & (1 << i)) != 0)
|
||||||
|
{
|
||||||
|
c = table[hash];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (inpos >= insz)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = in[inpos++];
|
||||||
|
table[hash] = c;
|
||||||
|
}
|
||||||
|
buff[j++] = c;
|
||||||
|
hash = HASH(hash, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j > 0)
|
||||||
|
{
|
||||||
|
if (out != NULL)
|
||||||
|
{
|
||||||
|
memcpy(out + outpos, buff, j);
|
||||||
|
}
|
||||||
|
outpos += j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outsz = outpos;
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
|
@ -130,6 +130,9 @@ struct stpdfs_inode {
|
||||||
#define STPDFS_INODE_SIZE sizeof(struct inode)
|
#define STPDFS_INODE_SIZE sizeof(struct inode)
|
||||||
|
|
||||||
# define STPDFS_NDIR 7 /**< Number of direct block */
|
# define STPDFS_NDIR 7 /**< Number of direct block */
|
||||||
|
# define STPDFS_SIND 7 /**< Indirect block */
|
||||||
|
# define STPDFS_DIND 8 /**< Double indirect */
|
||||||
|
# define STPDFS_TIND 9 /**< Triple indirect */
|
||||||
|
|
||||||
# define STPDFS_INO_FLAG_ALOC (1 << 15)
|
# define STPDFS_INO_FLAG_ALOC (1 << 15)
|
||||||
# define STPDFS_INO_FLAG_LZP (1 << 1)
|
# define STPDFS_INO_FLAG_LZP (1 << 1)
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
noinst_LIBRARIES = libstpdfs.a
|
|
||||||
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)
|
|
||||||
libstpdfs_a_SOURCES = block.c \
|
|
||||||
inode.c \
|
|
||||||
dir.c \
|
|
||||||
data.c \
|
|
||||||
superblock.c
|
|
89
lib/block.c
89
lib/block.c
|
@ -1,89 +0,0 @@
|
||||||
/**
|
|
||||||
* file: block.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stpdfs.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
stpdfs_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
|
|
||||||
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->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);
|
|
||||||
}
|
|
180
lib/data.c
180
lib/data.c
|
@ -1,180 +0,0 @@
|
||||||
#include "stpdfs.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
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_write_data(int fd, struct stpdfs_sb *sb, struct stpdfs_inode *inode, uint8_t *data)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t j;
|
|
||||||
size_t byte_write;
|
|
||||||
uint32_t zones1[STPDFS_ZONES_PER_BLOCK];
|
|
||||||
uint32_t zones2[STPDFS_ZONES_PER_BLOCK];
|
|
||||||
|
|
||||||
byte_write = 0;
|
|
||||||
for (i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
if (inode->zones[i] == 0)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
18
lib/dir.c
18
lib/dir.c
|
@ -1,18 +0,0 @@
|
||||||
#include "stpdfs.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
stpdfs_dir_add_entry(int fd, struct stpdfs_sb *sb, uint32_t inonum, const char *name, uint32_t target)
|
|
||||||
{
|
|
||||||
struct stpdfs_inode inode;
|
|
||||||
|
|
||||||
stpdfs_read_inode(fd, inonum, &inode);
|
|
||||||
if (!(inode.mode & STPDFS_S_IFDIR))
|
|
||||||
{
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
85
lib/inode.c
85
lib/inode.c
|
@ -1,85 +0,0 @@
|
||||||
#include "stpdfs.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
stpdfs_locate_inode(uint32_t inode)
|
|
||||||
{
|
|
||||||
return (2 + inode / STPDFS_INODES_PER_BLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
stpdfs_read_inode(int fd, uint32_t inodenum, struct stpdfs_inode *ino)
|
|
||||||
{
|
|
||||||
struct stpdfs_inode inodes[STPDFS_INODES_PER_BLOCK];
|
|
||||||
|
|
||||||
stpdfs_read(fd, 2 + inodenum / STPDFS_INODES_PER_BLOCK, (uint8_t *)&inodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
|
||||||
|
|
||||||
memcpy(ino, &inodes[inodenum % STPDFS_INODES_PER_BLOCK], sizeof(struct stpdfs_inode));
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
stpdfs_write_inode(int fd, uint32_t inodenum, const struct stpdfs_inode *inode)
|
|
||||||
{
|
|
||||||
struct stpdfs_inode inodes[STPDFS_INODES_PER_BLOCK];
|
|
||||||
|
|
||||||
stpdfs_read(fd, 2 + inodenum / STPDFS_INODES_PER_BLOCK, (uint8_t *)&inodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
|
||||||
|
|
||||||
memcpy(&inodes[inodenum % STPDFS_INODES_PER_BLOCK], inode, sizeof(struct stpdfs_inode));
|
|
||||||
|
|
||||||
stpdfs_write(fd, 2 + inodenum / STPDFS_INODES_PER_BLOCK, (uint8_t *)&inodes, sizeof(struct stpdfs_inode) * STPDFS_INODES_PER_BLOCK);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
53
lib/stpdfs.h
53
lib/stpdfs.h
|
@ -1,53 +0,0 @@
|
||||||
/**
|
|
||||||
* \file stpdfs.h
|
|
||||||
*
|
|
||||||
* StupidFS
|
|
||||||
* ```
|
|
||||||
* ┌──────────┬───────────┬──────┬───┬──────┬────┬───┬────┐
|
|
||||||
* │Boot block│Super block│Inodes│...│Inodes│Data│...│Data│
|
|
||||||
* └──────────┴───────────┴──────┴───┴──────┴────┴───┴────┘
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
#ifndef STPDFS_H
|
|
||||||
# define STPDFS_H 1
|
|
||||||
|
|
||||||
# include <stupidfs.h>
|
|
||||||
# include <stdint.h>
|
|
||||||
# include <stddef.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* API
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t stpdfs_write(int fd, uint32_t blocknum, void *data, size_t size);
|
|
||||||
size_t stpdfs_read(int fd, uint32_t blocknum, void *data, size_t size);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mark block as available for new allocation.
|
|
||||||
*
|
|
||||||
* \param fd file descriptor.
|
|
||||||
* \param sb pointer to \ref stpdfs_sb.
|
|
||||||
* \param blocknum block to free
|
|
||||||
*/
|
|
||||||
uint32_t stpdfs_alloc_block(int fd, struct stpdfs_sb *sb);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* find a free block.
|
|
||||||
*
|
|
||||||
* \param fd file descriptor.
|
|
||||||
* \param sb pointer to \ref stpdfs_sb.
|
|
||||||
* \return block number or 0 if no block found.
|
|
||||||
*/
|
|
||||||
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
|
|
||||||
|
|
||||||
/* superblock.c */
|
|
||||||
int stpdfs_superblock_valid(const 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);
|
|
||||||
int stpdfs_read_inode(int fd, uint32_t inodenum, struct stpdfs_inode *ino);
|
|
||||||
int stpdfs_write_inode(int fd, uint32_t inodenum, const struct stpdfs_inode *inode);
|
|
||||||
|
|
||||||
#endif /* !STPDFS_H */
|
|
|
@ -1,36 +0,0 @@
|
||||||
#include "stpdfs.h"
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
stpdfs_superblock_valid(const struct stpdfs_sb *sb)
|
|
||||||
{
|
|
||||||
return (sb->magic == STPDFS_SB_MAGIC && sb->revision == STPDFS_SB_REV);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
stpdfs_read_superblock(int fd, struct stpdfs_sb *sb)
|
|
||||||
{
|
|
||||||
if (stpdfs_read(fd, 1, sb, sizeof(struct stpdfs_sb)) != sizeof(struct stpdfs_sb))
|
|
||||||
{
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stpdfs_superblock_valid(sb))
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
stpdfs_write_superblock(int fd, struct stpdfs_sb *sb)
|
|
||||||
{
|
|
||||||
sb->time = time(NULL);
|
|
||||||
|
|
||||||
if (stpdfs_write(fd, 1, sb, sizeof(struct stpdfs_sb)) != sizeof(struct stpdfs_sb))
|
|
||||||
{
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)
|
||||||
noinst_LIBRARIES = libstpdfs.a
|
noinst_LIBRARIES = libstpdfs.a
|
||||||
libstpdfs_a_SOURCES = super.c bio.c inode.c file.c dir.c
|
libstpdfs_a_SOURCES = super.c bio.c inode.c file.c dir.c
|
|
@ -97,7 +97,13 @@ stpdfs_brelse(struct stpdfs_buffer *buff)
|
||||||
struct stpdfs_buffer *tmp;
|
struct stpdfs_buffer *tmp;
|
||||||
|
|
||||||
buff->refcount--;
|
buff->refcount--;
|
||||||
if (buff->refcount <= 0)
|
if (buff->refcount > 0) return;
|
||||||
|
|
||||||
|
if (buff == head)
|
||||||
|
{
|
||||||
|
head = buff->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
for (tmp = head; tmp != NULL; tmp = tmp->next)
|
for (tmp = head; tmp != NULL; tmp = tmp->next)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <libstpdfs/stpdfs.h>
|
||||||
|
|
||||||
|
static struct stpdfs_file *head = NULL;
|
||||||
|
|
||||||
|
struct stpdfs_file *
|
||||||
|
stpdfs_file_alloc(void)
|
||||||
|
{
|
||||||
|
struct stpdfs_file *f;
|
||||||
|
|
||||||
|
f = (struct stpdfs_file *)malloc(sizeof(struct stpdfs_file));
|
||||||
|
if (f == NULL)
|
||||||
|
{
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
f->refcount = 1;
|
||||||
|
f->ip = NULL;
|
||||||
|
f->offset = 0;
|
||||||
|
f->next = head;
|
||||||
|
|
||||||
|
head = f;
|
||||||
|
|
||||||
|
return (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stpdfs_file_close(struct stpdfs_file *f)
|
||||||
|
{
|
||||||
|
struct stpdfs_file *tmp;
|
||||||
|
|
||||||
|
f->refcount--;
|
||||||
|
if (f->refcount <= 0)
|
||||||
|
{
|
||||||
|
for (tmp = head; tmp != NULL; tmp = tmp->next)
|
||||||
|
{
|
||||||
|
if (tmp->next == f)
|
||||||
|
{
|
||||||
|
tmp->next = f->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(f);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,243 @@
|
||||||
|
#include "stpdfs.h"
|
||||||
|
#include "stupidfs.h"
|
||||||
#include <libstpdfs/stpdfs.h>
|
#include <libstpdfs/stpdfs.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
# define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||||
|
#endif /* !MIN */
|
||||||
#define INODE_CACHE 50
|
#define INODE_CACHE 50
|
||||||
|
#define IBLOCK(x) (x / STPDFS_INODES_PER_BLOCK + 2)
|
||||||
|
|
||||||
struct stpdfs_inode_info icache[INODE_CACHE];
|
static struct stpdfs_inode_info icache[INODE_CACHE] = {0};
|
||||||
|
|
||||||
struct inode *
|
struct stpdfs_inode_info *
|
||||||
stpdfs_inode_get(struct stpdfs_sb *sb, uint32_t ino)
|
stpdfs_inode_get(struct stpdfs_super_info *sbi, uint32_t inum)
|
||||||
{
|
{
|
||||||
|
struct stpdfs_inode_info *empty;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
struct stpdfs_inode *dinode;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
empty = NULL;
|
||||||
|
for (idx = 0; idx < INODE_CACHE; idx++)
|
||||||
|
{
|
||||||
|
if (icache[idx].refcount > 0 && icache[idx].inum == inum)
|
||||||
|
{
|
||||||
|
icache[idx].refcount++;
|
||||||
|
return (&icache[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty == NULL && icache[idx].refcount == 0)
|
||||||
|
{
|
||||||
|
empty = &icache[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty == NULL) return (NULL);
|
||||||
|
|
||||||
|
empty->sbi = sbi;
|
||||||
|
empty->inum = inum;
|
||||||
|
empty->refcount = 1;
|
||||||
|
|
||||||
|
empty->valid = 1;
|
||||||
|
buff = stpdfs_bread(sbi->fd, IBLOCK(inum));
|
||||||
|
dinode = (struct stpdfs_inode *)buff->data + inum % STPDFS_INODES_PER_BLOCK;
|
||||||
|
memcpy(&empty->inode, dinode, sizeof(struct stpdfs_inode));
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
|
return (empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stpdfs_inode_info *
|
||||||
|
stpdfs_inode_alloc(struct stpdfs_super_info *sbi)
|
||||||
|
{
|
||||||
|
uint32_t inum;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
struct stpdfs_inode *dinode;
|
||||||
|
|
||||||
|
for (inum = 1; inum < sbi->sb.isize; inum++)
|
||||||
|
{
|
||||||
|
buff = stpdfs_bread(sbi->fd, IBLOCK(inum));
|
||||||
|
dinode = (struct stpdfs_inode *)buff->data + inum % STPDFS_INODES_PER_BLOCK;
|
||||||
|
if ((dinode->flags & STPDFS_INO_FLAG_ALOC) == 0)
|
||||||
|
{
|
||||||
|
dinode->flags = STPDFS_INO_FLAG_ALOC;
|
||||||
|
stpdfs_bwrite(buff);
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
|
return (stpdfs_inode_get(sbi, inum));
|
||||||
|
}
|
||||||
|
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
}
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stpdfs_dirent *
|
void
|
||||||
stpdfs_lookup(struct stpdfs_inode *dir, struct stpdfs_dirent *dentry, int flags)
|
stpdfs_inode_update(struct stpdfs_inode_info *ip)
|
||||||
{
|
{
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
struct stpdfs_inode *dinode;
|
||||||
|
|
||||||
|
buff = stpdfs_bread(ip->sbi->fd, IBLOCK(ip->inum));
|
||||||
|
dinode = (struct stpdfs_inode *)buff->data + ip->inum % STPDFS_INODES_PER_BLOCK;
|
||||||
|
memcpy(dinode, &ip->inode, sizeof(struct stpdfs_inode));
|
||||||
|
stpdfs_bwrite(buff);
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_inode_bmap(struct stpdfs_inode_info *ip, uint32_t blocknum)
|
||||||
|
{
|
||||||
|
uint32_t *addrs;
|
||||||
|
uint32_t index;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
|
||||||
|
if (blocknum < STPDFS_NDIR)
|
||||||
|
{
|
||||||
|
if (ip->inode.zones[blocknum] == 0)
|
||||||
|
{
|
||||||
|
ip->inode.zones[blocknum] = stpdfs_super_balloc(ip->sbi);
|
||||||
|
}
|
||||||
|
return (ip->inode.zones[blocknum]);
|
||||||
|
}
|
||||||
|
|
||||||
|
index = blocknum - STPDFS_NDIR;
|
||||||
|
if (blocknum < (STPDFS_BLOCK_SIZE/sizeof(int32_t) + STPDFS_SIND))
|
||||||
|
{
|
||||||
|
if (ip->inode.zones[STPDFS_SIND] == 0)
|
||||||
|
{
|
||||||
|
ip->inode.zones[STPDFS_SIND] = stpdfs_super_balloc(ip->sbi);
|
||||||
|
}
|
||||||
|
|
||||||
|
buff = stpdfs_bread(ip->sbi->fd, ip->inode.zones[STPDFS_SIND]);
|
||||||
|
addrs = (uint32_t *)buff->data;
|
||||||
|
if (addrs[index] == 0)
|
||||||
|
{
|
||||||
|
addrs[index] = stpdfs_super_balloc(ip->sbi);
|
||||||
|
}
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
return (addrs[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO double and triple ind */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stpdfs_inode_trunc(struct stpdfs_inode_info *ip)
|
||||||
|
{
|
||||||
|
(void)ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_inode_read(struct stpdfs_inode_info *ip, uint8_t *dest, size_t offset, size_t size)
|
||||||
|
{
|
||||||
|
size_t total;
|
||||||
|
size_t rd;
|
||||||
|
uint32_t zone;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
|
||||||
|
if (offset > ip->inode.size)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
total = 0;
|
||||||
|
while (total < size)
|
||||||
|
{
|
||||||
|
zone = stpdfs_inode_bmap(ip, offset/STPDFS_BLOCK_SIZE);
|
||||||
|
if (zone == 0) return (total);
|
||||||
|
|
||||||
|
buff = stpdfs_bread(ip->sbi->fd, zone);
|
||||||
|
|
||||||
|
rd = MIN(size - total, STPDFS_BLOCK_SIZE - offset % STPDFS_BLOCK_SIZE);
|
||||||
|
memcpy(dest, buff->data + (offset % STPDFS_BLOCK_SIZE), rd);
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
|
total += rd;
|
||||||
|
offset += rd;
|
||||||
|
dest += rd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (total);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_inode_write(struct stpdfs_inode_info *ip, const uint8_t *src, size_t offset, size_t size)
|
||||||
|
{
|
||||||
|
size_t total;
|
||||||
|
size_t rd;
|
||||||
|
uint32_t zone;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
|
||||||
|
if (offset > ip->inode.size)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
total = 0;
|
||||||
|
while (total < size)
|
||||||
|
{
|
||||||
|
zone = stpdfs_inode_bmap(ip, offset/STPDFS_BLOCK_SIZE);
|
||||||
|
if (zone == 0) break;
|
||||||
|
|
||||||
|
buff = stpdfs_bread(ip->sbi->fd, zone);
|
||||||
|
|
||||||
|
rd = MIN(size - total, STPDFS_BLOCK_SIZE - offset % STPDFS_BLOCK_SIZE);
|
||||||
|
memcpy(buff->data + (offset % STPDFS_BLOCK_SIZE), src, rd);
|
||||||
|
stpdfs_bwrite(buff);
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
|
total += rd;
|
||||||
|
offset += rd;
|
||||||
|
src += rd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset > ip->inode.size)
|
||||||
|
{
|
||||||
|
ip->inode.size = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
stpdfs_inode_update(ip);
|
||||||
|
|
||||||
|
return (total);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stpdfs_inode_info *
|
||||||
|
stpdfs_dirlookup(struct stpdfs_inode_info *dp, const char *name, size_t *offset)
|
||||||
|
{
|
||||||
|
struct stpdfs_dirent dirent;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
if (!(dp->inode.flags & STPDFS_S_IFDIR))
|
||||||
|
{
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0; idx < dp->inode.size; idx += STPDFS_DIRENT_SIZE)
|
||||||
|
{
|
||||||
|
if (stpdfs_inode_read(dp, (uint8_t *)&dirent, idx, STPDFS_DIRENT_SIZE) != STPDFS_DIRENT_SIZE)
|
||||||
|
{
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(name, dirent.filename, STPDFS_NAME_MAX))
|
||||||
|
{
|
||||||
|
*offset = idx;
|
||||||
|
return (stpdfs_inode_get(dp->sbi, dirent.inode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_dirlink(struct stpdfs_inode_info *dp, const char *name, uint32_t inum)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,21 @@ struct stpdfs_super_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stpdfs_inode_info {
|
struct stpdfs_inode_info {
|
||||||
struct stpdfs_inode ino;
|
int valid;
|
||||||
int fd;
|
|
||||||
int refcount;
|
int refcount;
|
||||||
|
uint32_t inum;
|
||||||
|
struct stpdfs_super_info *sbi;
|
||||||
|
|
||||||
|
struct stpdfs_inode inode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stpdfs_file {
|
||||||
|
int refcount;
|
||||||
|
|
||||||
|
struct stpdfs_inode_info *ip;
|
||||||
|
size_t offset;
|
||||||
|
|
||||||
|
struct stpdfs_file *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stpdfs_buffer {
|
struct stpdfs_buffer {
|
||||||
|
@ -37,11 +49,17 @@ void stpdfs_brelse(struct stpdfs_buffer *buff);
|
||||||
void stpdfs_bpin(struct stpdfs_buffer *buff);
|
void stpdfs_bpin(struct stpdfs_buffer *buff);
|
||||||
|
|
||||||
/* super.c */
|
/* super.c */
|
||||||
|
int stpdfs_super_open(struct stpdfs_super_info *sbi, const char *fname);
|
||||||
int stpdfs_read_super(struct stpdfs_super_info *sbi, int fd);
|
int stpdfs_read_super(struct stpdfs_super_info *sbi, int fd);
|
||||||
int stpdfs_super_validate(struct stpdfs_sb *sb);
|
int stpdfs_super_validate(struct stpdfs_sb *sb);
|
||||||
int stpdfs_super_kill(struct stpdfs_super_info *sbi);
|
int stpdfs_super_kill(struct stpdfs_super_info *sbi);
|
||||||
|
uint32_t stpdfs_super_balloc(struct stpdfs_super_info *sbi);
|
||||||
|
int stpdfs_super_bfreee(struct stpdfs_super_info *sbi, uint32_t blocknum);
|
||||||
|
|
||||||
uint32_t stpdfs_alloc_block(int fd, struct stpdfs_sb *sb);
|
uint32_t stpdfs_alloc_block(int fd, struct stpdfs_sb *sb);
|
||||||
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
|
int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
|
||||||
|
|
||||||
|
struct stpdfs_inode_info *stpdfs_inode_get(struct stpdfs_super_info *sbi, uint32_t inum);
|
||||||
|
int stpdfs_inode_read(struct stpdfs_inode_info *ip, uint8_t *dest, size_t offset, size_t size);
|
||||||
|
|
||||||
#endif /* !STPDFS_H */
|
#endif /* !STPDFS_H */
|
|
@ -1,4 +1,6 @@
|
||||||
|
#include "stupidfs.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -70,7 +72,78 @@ stpdfs_super_kill(struct stpdfs_super_info *sbi)
|
||||||
stpdfs_bwrite(buff);
|
stpdfs_bwrite(buff);
|
||||||
|
|
||||||
stpdfs_brelse(buff);
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
close(sbi->fd);
|
close(sbi->fd);
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
stpdfs_super_balloc(struct stpdfs_super_info *sbi)
|
||||||
|
{
|
||||||
|
uint32_t blocknum;
|
||||||
|
struct stpdfs_free freelist;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
|
||||||
|
sbi->sb.state = STPDFS_DIRTY;
|
||||||
|
redo:
|
||||||
|
sbi->sb.freelist.nfree--;
|
||||||
|
blocknum = sbi->sb.freelist.free[sbi->sb.freelist.nfree];
|
||||||
|
if (sbi->sb.freelist.nfree == 0 && blocknum != 0)
|
||||||
|
{
|
||||||
|
buff = stpdfs_bread(sbi->fd, blocknum);
|
||||||
|
memcpy(&sbi->sb.freelist, buff->data, sizeof(struct stpdfs_free));
|
||||||
|
goto redo;
|
||||||
|
}
|
||||||
|
|
||||||
|
buff = stpdfs_bread(sbi->fd, 1);
|
||||||
|
memcpy(buff->data, &sbi->sb, sizeof(struct stpdfs_sb));
|
||||||
|
stpdfs_bwrite(buff);
|
||||||
|
|
||||||
|
buff = stpdfs_bread(sbi->fd, blocknum);
|
||||||
|
memset(buff->data, 0, STPDFS_BLOCK_SIZE);
|
||||||
|
stpdfs_bwrite(buff);
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
|
sbi->sb.time = time(NULL);
|
||||||
|
|
||||||
|
return (blocknum);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_super_bfreee(struct stpdfs_super_info *sbi, uint32_t blocknum)
|
||||||
|
{
|
||||||
|
struct stpdfs_free copy;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
|
||||||
|
if (blocknum == 0 || blocknum >= sbi->sb.fsize)
|
||||||
|
{
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sbi->sb.state = STPDFS_DIRTY;
|
||||||
|
|
||||||
|
if (sbi->sb.freelist.nfree == 100)
|
||||||
|
{
|
||||||
|
buff = stpdfs_bread(sbi->fd, blocknum);
|
||||||
|
memcpy(buff->data, &sbi->sb.freelist, sizeof(struct stpdfs_free));
|
||||||
|
stpdfs_bwrite(buff);
|
||||||
|
stpdfs_brelse(buff);
|
||||||
|
sbi->sb.freelist.nfree = 1;
|
||||||
|
sbi->sb.freelist.free[0] = blocknum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sbi->sb.freelist.free[sbi->sb.freelist.nfree++] = blocknum;
|
||||||
|
}
|
||||||
|
|
||||||
|
sbi->sb.time = time(NULL);
|
||||||
|
|
||||||
|
buff = stpdfs_bread(sbi->fd, 1);
|
||||||
|
memcpy(buff->data, &sbi->sb, sizeof(struct stpdfs_sb));
|
||||||
|
stpdfs_bwrite(buff);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
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 = ../lib/libstpdfs.a
|
LDADD = ../libstpdfs/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
|
mkfs_stpd_LDADD = ../libstpdfs/libstpdfs.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
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stupidfs.h>
|
#include <libstpdfs/stpdfs.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 */
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
|
#include "stupidfs.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -9,16 +11,88 @@
|
||||||
#ifdef HAVE_GETOPT_H
|
#ifdef HAVE_GETOPT_H
|
||||||
# include <getopt.h>
|
# include <getopt.h>
|
||||||
#endif /* HAVE_GETOPT_H */
|
#endif /* HAVE_GETOPT_H */
|
||||||
|
#include <libstpdfs/stpdfs.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_OPTION
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"image", required_argument, 0, 'i'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
#endif /* HAVE_STRUCT_OPTION */
|
||||||
|
|
||||||
|
static char *path = "/";
|
||||||
|
static char *image = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(int retval)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_ls(void)
|
||||||
|
{
|
||||||
|
struct stpdfs_super_info sbi;
|
||||||
|
struct stpdfs_inode_info *ip;
|
||||||
|
struct stpdfs_dirent dirent;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
if (stpdfs_super_open(&sbi, image))
|
||||||
|
{
|
||||||
|
return (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = stpdfs_inode_get(&sbi, STPDFS_ROOTINO);
|
||||||
|
for (idx = 0; idx < ip->inode.size; idx += STPDFS_DIRENT_SIZE)
|
||||||
|
{
|
||||||
|
stpdfs_inode_read(ip, (uint8_t *)&dirent, idx, STPDFS_DIRENT_SIZE);
|
||||||
|
printf("%s\n", dirent.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stpdfs_super_kill(&sbi);
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ls(int argc, char **argv)
|
ls(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int idx;
|
||||||
return (EXIT_SUCCESS);
|
int c;
|
||||||
|
|
||||||
|
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
|
||||||
|
while ((c = getopt_long(argc, argv, "hi:", long_options, &idx)) != EOF)
|
||||||
|
#else
|
||||||
|
while ((c = getopt(argc, argv, "hi:")) != EOF)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
usage(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
image = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image == NULL)
|
||||||
|
{
|
||||||
|
return (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind < argc)
|
||||||
|
{
|
||||||
|
path = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (do_ls());
|
||||||
}
|
}
|
Loading…
Reference in a new issue