aboutsummaryrefslogtreecommitdiff
path: root/kernel/include/fs/s5fs/s5fs.h
blob: 7bde185a10a1a9652a82cd4987d4c3c10b19d1c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 *   FILE: s5fs.h
 * AUTHOR: kma
 *  DESCR: shared structures for the System V file system...
 */

#pragma once

#ifdef __FSMAKER__
#include <stdint.h>
#else

#include "config.h"

#include "drivers/blockdev.h"
#include "fs/vfs.h"
#include "fs/vnode.h"
#include "mm/page.h"
#include "proc/kmutex.h"

#endif

#define S5_SUPER_BLOCK 0 /* the blockno of the superblock */
#define S5_IS_SUPER(blkno) ((blkno) == S5_SUPER_BLOCK)

#define S5_NBLKS_PER_FNODE 30

#define S5_BLOCK_SIZE 4096
#define S5_NDIRECT_BLOCKS 28
#define S5_INODES_PER_BLOCK (S5_BLOCK_SIZE / sizeof(s5_inode_t))
#define S5_DIRENTS_PER_BLOCK (S5_BLOCK_SIZE / sizeof(s5_dirent_t))
#define S5_MAX_FILE_BLOCKS (S5_NDIRECT_BLOCKS + S5_NIDIRECT_BLOCKS)
#define S5_MAX_FILE_SIZE (S5_MAX_FILE_BLOCKS * S5_BLOCK_SIZE)
#define S5_NAME_LEN 28

#define S5_TYPE_FREE 0x0
#define S5_TYPE_DATA 0x1
#define S5_TYPE_DIR 0x2
#define S5_TYPE_CHR 0x4
#define S5_TYPE_BLK 0x8

#define S5_MAGIC 071177
#define S5_CURRENT_VERSION 3

/* Number of blocks stored in the indirect block */
#define S5_NIDIRECT_BLOCKS (S5_BLOCK_SIZE / sizeof(uint32_t))

/* Given a file offset, returns the block number that it is in */
#define S5_DATA_BLOCK(seekptr) ((seekptr) / S5_BLOCK_SIZE)

/* Given a file offset, returns the offset into the pointer's block */
#define S5_DATA_OFFSET(seekptr) ((seekptr) % S5_BLOCK_SIZE)

/* Given an inode number, tells the block that inode is stored in. */
#define S5_INODE_BLOCK(inum) ((inum) / S5_INODES_PER_BLOCK + 1)

/*
 * Given an inode number, tells the offset (in units of s5_inode_t) of
 * that inode within the block returned by S5_INODE_BLOCK.
 */
#define S5_INODE_OFFSET(inum) ((inum) % S5_INODES_PER_BLOCK)

/* Given an FS struct, get the S5FS (private data) struct. */
#define FS_TO_S5FS(fs) ((s5fs_t *)(fs)->fs_i)

/* each node of the free block list looks like this: */
/*
typedef struct s5_fbl_node {
        int free_blocks[S5_NBLKS_PER_FNODE-1];
        int more;
} s5_fbl_node_t;
*/

/* Note that all on-disk types need to have hard-coded sizes (to ensure
 * inter-machine compatibility of s5 disks) */

/* The contents of the superblock, as stored on disk. */
typedef struct s5_super
{
    uint32_t s5s_magic;      /* the magic number */
    uint32_t s5s_free_inode; /* the free inode pointer */
    uint32_t s5s_nfree;      /* number of blocks currently in
                              * s5s_free_blocks */
    /* First "node" of free block list */
    uint32_t s5s_free_blocks[S5_NBLKS_PER_FNODE];

    uint32_t s5s_root_inode; /* root inode */
    uint32_t s5s_num_inodes; /* number of inodes */
    uint32_t s5s_version;    /* version of this disk format */
} s5_super_t;

/* The contents of an inode, as stored on disk. */
typedef struct s5_inode
{
    union {
        uint32_t s5_next_free; /* inode free list ptr */
        uint32_t s5_size;      /* file size */
    } s5_un;
    uint32_t s5_number;   /* this inode's number */
    uint16_t s5_type;     /* one of S5_TYPE_{FREE,DATA,DIR,CHR,BLK} */
    int16_t s5_linkcount; /* link count of this inode */
    uint32_t s5_direct_blocks[S5_NDIRECT_BLOCKS];
    uint32_t s5_indirect_block;
} s5_inode_t;

typedef struct s5_node
{
    vnode_t vnode;
    s5_inode_t inode;
    long dirtied_inode;
} s5_node_t;

#define VNODE_TO_S5NODE(vn) CONTAINER_OF(vn, s5_node_t, vnode)

/* The contents of a directory entry, as stored on disk. */
typedef struct s5_dirent
{
    uint32_t s5d_inode;
    char s5d_name[S5_NAME_LEN];
} s5_dirent_t;

#ifndef __FSMAKER__
/* Our in-memory representation of a s5fs filesytem (fs_i points to this) */
typedef struct s5fs
{
    blockdev_t *s5f_bdev;
    s5_super_t s5f_super;
    kmutex_t s5f_mutex;
    fs_t *s5f_fs;
#ifndef OLD
    mobj_t s5f_mobj;
#endif
} s5fs_t;

long s5fs_mount(struct fs *fs);

void s5_get_meta_disk_block(s5fs_t *s5fs, uint64_t blocknum, long forwrite,
                       pframe_t **pfp);

//void s5_get_file_disk_block(vnode_t *vnode, blocknum_t blocknum, long forwrite,
//                              pframe_t **pfp);

void s5_release_disk_block(pframe_t **pfp);

#endif