\documentclass[a4paper, 12pt, openright, english]{scrbook} \usepackage{graphicx} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{babel} \usepackage{lmodern} \usepackage{listings} \usepackage{xcolor} \usepackage[ pdftitle={StupidFS}, pdfauthor={\@author}, ]{hyperref} \definecolor{codegreen}{rgb}{0,0.6,0} \definecolor{codegray}{rgb}{0.5,0.5,0.5} \definecolor{codepurple}{rgb}{0.58,0,0.82} \definecolor{backcolour}{rgb}{0.95,0.95,0.92} \lstdefinestyle{mystyle}{ backgroundcolor=\color{backcolour}, commentstyle=\color{codegreen}, keywordstyle=\color{magenta}, numberstyle=\tiny\color{codegray}, stringstyle=\color{codepurple}, basicstyle=\ttfamily\footnotesize, breakatwhitespace=false, breaklines=true, captionpos=b, keepspaces=true, numbers=left, numbersep=5pt, showspaces=false, showstringspaces=false, showtabs=false, tabsize=2 } \lstset{style=mystyle} \date{\today} \title{% StupidFS Algorithm \& Data Structure \\ \large 1st Edition} \author{d0p1} \lowertitleback{Copyright \copyright{} 2022 d0p1 \medskip\\ \begin{tabular}{lp{.8\textwidth}} \raisebox{-12pt}{\includegraphics[height=18pt]{fig/gfdl}} & Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. \\ \end{tabular} } \begin{document} \frontmatter \maketitle \tableofcontents \mainmatter \chapter{File, file system, and memory size limits} \chapter{Magic Numbers} \begin{center} \begin{tabular}{ |c|c|c|c| } \hline \textbf{Flag} & \textbf{Hexadecimal} & \textbf{ASCII} & \textbf{Data structure} \\ \hline STPDFS\_SB\_MAGIC & 0x44505453 & STPD & Superblock \\ STDFS\_BLOCK\_SIZE & 512 & & Block size\\ \hline \end{tabular} \end{center} \chapter{Structures} \section{Superblock} \subsection{free list} \begin{lstlisting}[language=C] struct stpdfs_free { uint32_t free[100]; uint8_t nfree; }; \end{lstlisting} \subsection{superblock} \begin{lstlisting}[language=C] #define STPDFS_SB_MAGIC 0x44505453 #define STPDFS_REV STPDFS_REV_1 #define STPDFS_REV_1 0x1 struct stpdfs_sb { uint32_t magic; uint32_t isize; uint32_t fsize; uint32_t free[100]; uint8_t nfree; uint8_t revision; uint16_t state; uint64_t time; }; \end{lstlisting} \section{INodes} \begin{lstlisting}[language=C] struct inode { uint16_t mode; uint16_t nlink; uint16_t uid; uint16_t gid; uint16_t flags; uint32_t size; uint32_t zones[10]; uint64_t actime; uint64_t modtime; }; \end{lstlisting} \subsection{flags} \begin{center} \begin{tabular}{ |c|c|c|c| } \hline \textbf{flags} & \textbf{value} & \textbf{Description} \\ \hline STPDFS\_INODE\_ALLOCATED & 1 << 15 & if set inode is allocated \\ STPDFS\_INODE\_LZP & 1 << 0 & if set data are compressed \\ STPDFS\_INODE\_ENC & 1 << 1 & if set data are encrypted \\ \hline \end{tabular} \end{center} \begin{center} \begin{tabular}{ |c|c| } zone 0-6 & direct \\ zone 7 & indirect \\ zone 8 & double indirect \\ zone 9 & triple indirect \\ \end{tabular} \end{center} \subsection{mode} \begin{center} \begin{tabular}{ |c|c|c|c| } \hline \textbf{mode} & \textbf{value} & \textbf{Description} \\ STPDFS\_S\_IFSOCK & 0xA000 & \\ STPDFS\_S\_IFLNK & 0xC000 & \\ STPDFS\_S\_IFREG & 0x8000 & \\ STPDFS\_S\_IFBLK & 0x6000 & \\ STPDFS\_S\_IFDIR & 0x4000 & \\ \hline \end{tabular} \end{center} \section{Dirent} \begin{lstlisting}[language=C] struct stpdfs_dirent { ino_t inode; char filename[STPDFS_NAME_MAX]; }; \end{lstlisting} \appendix \chapter{LZP implementation} \section{Compression} \begin{lstlisting}[language=C] #include #include #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}