-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLocalFileSystem.h
More file actions
160 lines (144 loc) · 5.8 KB
/
Copy pathLocalFileSystem.h
File metadata and controls
160 lines (144 loc) · 5.8 KB
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
#ifndef _LOCAL_FILE_SYSTEM_H_
#define _LOCAL_FILE_SYSTEM_H_
#include <string>
#include "Disk.h"
#include "ufs.h"
/**
* The local file system interface.
*
* Implement this class so that your server can access the local file system that
* you will implement. This class uses our Disk class for accessing disk blocks
* on the underlying storage stack.
*
* One important aspect of this interface is that the buffers and sizes that
* callers operate will not align on disk block boundaries, so your job is
* to manage the interactions with the underlying storage to provide a higher
* level of abstraction for any code that uses this class.
*/
// Note: If a function invocation has more than one error, return
// whichever error makes the most sense in your implementation and
// it will be considered correct.
// the operation failed because there wasn't enough space on the disk
#define ENOTENOUGHSPACE (1)
// Unlinking a directory that is _not_ empty
#define EDIRNOTEMPTY (2)
// The inode number is invalid
#define EINVALIDINODE (3)
// The inode is valid but not allocated
#define ENOTALLOCATED (4)
// The `size` for a read or write is invalid
#define EINVALIDSIZE (5)
// Attempting to write to a directory
#define EWRITETODIR (6)
// Lookup an entity that does not exist
#define ENOTFOUND (7)
// Invalid name
#define EINVALIDNAME (8)
// Creating an entity that exists with a different type or writing to a directory
#define EINVALIDTYPE (9)
// Unlinking '.' or '..'
#define EUNLINKNOTALLOWED (10)
class LocalFileSystem {
public:
LocalFileSystem(Disk *disk);
/**
* Lookup an inode.
*
* Takes the parent inode number (which should be the inode number
* of a directory) and looks up the entry name in it. The inode
* number of name is returned.
*
* Success: return inode number of name
* Failure: return -ENOTFOUND, -EINVALIDINODE.
* Failure modes: invalid parentInodeNumber, name does not exist.
*/
int lookup(int parentInodeNumber, std::string name);
/**
* Read an inode.
*
* Given an inodeNumber this function will fill in the `inode` struct with
* the type of the entry and the size of the data, in bytes, and direct blocks.
*
* Success: return 0
* Failure: return -EINVALIDINODE
* Failure modes: invalid inodeNumber
*/
int stat(int inodeNumber, inode_t *inode);
/**
* Makes a file or directory.
*
* Makes a file (type == UFS_REGULAR_FILE) or directory (type == UFS_DIRECTORY)
* in the parent directory specified by parentInodeNumber of name name.
*
* Success: return the inode number of the new file or directory
* Failure: -EINVALIDINODE, -EINVALIDNAME, -EINVALIDTYPE, -ENOTENOUGHSPACE.
* Failure modes: parentInodeNumber does not exist, or name is too long.
* If name already exists and is of the correct type, return success, but
* if the name already exists and is of the wrong type, return an error.
*/
int create(int parentInodeNumber, int type, std::string name);
/**
* Write the contents of a file.
*
* Writes a buffer of size to the file, replacing any content that
* already exists.
*
* Success: number of bytes written
* Failure: -EINVALIDINODE, -EINVALIDSIZE, -EINVALIDTYPE, -ENOTENOUGHSPACE.
* Failure modes: invalid inodeNumber, invalid size, not a regular file
* (because you can't write to directories).
*/
int write(int inodeNumber, const void *buffer, int size);
/**
* Read the contents of a file or directory.
*
* Reads up to `size` bytes of data into the buffer from file specified by
* inodeNumber. The routine should work for either a file or directory;
* directories should return data in the format specified by dir_ent_t.
*
* Success: number of bytes read
* Failure: -EINVALIDINODE, -EINVALIDSIZE.
* Failure modes: invalid inodeNumber, invalid size.
*/
int read(int inodeNumber, void *buffer, int size);
/**
* Remove a file or directory.
*
* Removes the file or directory name from the directory specified by
* parentInodeNumber.
*
* Success: 0
* Failure: -EINVALIDINODE, -EDIRNOTEMPTY, -EINVALIDNAME, -ENOTENOUGHSPACE,
* -EUNLINKNOTALLOWED
* Failure modes: parentInodeNumber does not exist, directory is NOT
* empty, or the name is invalid. Note that the name not existing is NOT
* a failure by our definition. You can't unlink '.' or '..'
*/
int unlink(int parentInodeNumber, std::string name);
/**
* Some helper functions that you need to implement and use in your
* implementation of the higher-level functions. When you operate on
* file system metadata, you must read/write the entire structure instead
* of trying to identify individual disk blocks and accessing only these.
*/
void readSuperBlock(super_t *super);
/**
* numDataBytesNeeded is converted to blocks and added to numDataBlocksNeeded
* Having two separate arguments for data helps for operations that write
* new data to two separate entities. If you don't need a value
* you can set the number needed to 0.
*/
bool diskHasSpace(super_t *super, int numInodesNeeded, int numDataBytesNeeded, int numDataBlocksNeeded=0);
// Helper functions, you should read/write the entire inode and bitmap regions
void readInodeBitmap(super_t *super, unsigned char *inodeBitmap);
void writeInodeBitmap(super_t *super, unsigned char *inodeBitmap);
void readDataBitmap(super_t *super, unsigned char *dataBitmap);
void writeDataBitmap(super_t *super, unsigned char *dataBitmap);
void readInodeRegion(super_t *super, inode_t *inodes);
void writeInodeRegion(super_t *super, inode_t *inodes);
// Normally we'd mark this as private but we expose it so that you can access
// it in a function you add that is not part of the LocalFileSystem object but
// can still access the disk.
Disk *disk;
};
#endif