-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoufs.h
190 lines (139 loc) · 4.79 KB
/
oufs.h
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*******
* Low-level file system definitions
*
* DO NOT CHANGE THIS DATA STRUCTURE
*
* CS 3113
*
*
*/
// Only evaluate these definitions once, even if included multiple times
#ifndef FILE_STRUCTS_H
#define FILE_STRUCTS_H
#include <string.h>
#include <limits.h>
// Implementation of min operator
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
/**********************************************************************/
// Default virtual disk parameters (used if they are not yet defined)
#ifndef BLOCK_SIZE
// Number of bytes in a disk block
#define BLOCK_SIZE 256
// Total number of blocks
#define N_BLOCKS 128
// Number of inode blocks on the virtual disk
#define N_INODE_BLOCKS 4
#endif
/**********************************************************************/
/*
File system layout onto disk blocks:
Block 0: Master block
Blocks 1 ... N_INODE_BLOCKS: inodes
Blocks N_INODE_BLOCKS+1 ... N_BLOCKS_ON_DISK-1: data for files and directories
(Block N_BLOCKS+1 is allocated for the root directory)
*/
/**********************************************************************/
// Basic types and sizes
// Chosen carefully so that all block types pack nicely into a full block
// An index for a block (0, 1, 2, ...)
typedef unsigned short BLOCK_REFERENCE;
// Value used as an index when it does not refer to a block
#define UNALLOCATED_BLOCK (USHRT_MAX-1)
// An index that refers to an inode
typedef unsigned short INODE_REFERENCE;
// Value used as an index when it does not refer to an inode
#define UNALLOCATED_INODE (USHRT_MAX)
// Number of bytes available for block data
#define DATA_BLOCK_SIZE ((int)(BLOCK_SIZE-sizeof(BLOCK_REFERENCE)))
// The block on the virtual disk containing the root directory
#define ROOT_DIRECTORY_BLOCK (N_INODE_BLOCKS + 1)
// The Inode for the root directory
#define ROOT_DIRECTORY_INODE 0
// Size of file/directory name
#define FILE_NAME_SIZE ((int)(16 - sizeof(INODE_REFERENCE)))
/**********************************************************************/
// Data block: storage for file contents (project 4!)
typedef struct data_block_s
{
unsigned char data[DATA_BLOCK_SIZE];
} DATA_BLOCK;
/**********************************************************************/
// Inode Types
typedef enum {UNUSED_TYPE=0, DIRECTORY_TYPE, FILE_TYPE} INODE_TYPE;
// Single inode
typedef struct inode_s
{
// Type of INODE
INODE_TYPE type;
// Number of directory references to this inode
unsigned char n_references;
// Contents. UNALLOCATED_BLOCK means that this entry is not used
BLOCK_REFERENCE content;
// File: size in bytes; Directory: number of directory entries
// (including . and ..)
unsigned int size;
} INODE;
// Number of inodes stored in each block
#define N_INODES_PER_BLOCK ((int)(DATA_BLOCK_SIZE/sizeof(INODE)))
// Total number of inodes in the file system
#define N_INODES (((N_INODES_PER_BLOCK * N_INODE_BLOCKS)>>3)<<3)
// Block of inodes
typedef struct inode_block_s
{
INODE inode[N_INODES_PER_BLOCK];
} INODE_BLOCK;
/**********************************************************************/
// Block 0
#define MASTER_BLOCK_REFERENCE 0
typedef struct master_block_s
{
// 8 inodes per byte: One inode per bit: 1 = allocated, 0 = free
// Inode 0 (zero) is byte 0, bit 7
// 1 is byte 0, bit 6
// 8 is byte 1, bit 7
unsigned char inode_allocated_flag[N_INODES >> 3];
// Double-ended linked list representation for unallocated blocks
BLOCK_REFERENCE unallocated_front;
BLOCK_REFERENCE unallocated_end;
} MASTER_BLOCK;
/**********************************************************************/
// Single directory element
typedef struct directory_entry_s
{
// Name of file/directory
char name[FILE_NAME_SIZE];
// UNALLOCATED_INODE if this directory entry is non-existent
INODE_REFERENCE inode_reference;
} DIRECTORY_ENTRY;
// Number of directory entries stored in one data block
#define N_DIRECTORY_ENTRIES_PER_BLOCK ((int)(DATA_BLOCK_SIZE / sizeof(DIRECTORY_ENTRY)))
// Directory block
typedef struct directory_block_s
{
DIRECTORY_ENTRY entry[N_DIRECTORY_ENTRIES_PER_BLOCK];
} DIRECTORY_BLOCK;
/**********************************************************************/
// All-encompassing structure for a disk block
// The union says that all 4 of these elements occupy overlapping bytes in
// memory (hence, a block will only be one of these 4 at any given time)
typedef struct
{
BLOCK_REFERENCE next_block;
union {
DATA_BLOCK data;
MASTER_BLOCK master;
INODE_BLOCK inodes;
DIRECTORY_BLOCK directory;
} content;
} BLOCK;
/**********************************************************************/
// Representing files (project 4!)
#define MAX_BLOCKS_IN_FILE 100
typedef struct oufile_s
{
INODE_REFERENCE inode_reference;
char mode;
int offset;
BLOCK_REFERENCE block_reference_cache[MAX_BLOCKS_IN_FILE];
} OUFILE;
#endif