forked from hjl0505/FileSystem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FileTable.java
165 lines (150 loc) · 5.09 KB
/
FileTable.java
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
// Edited By Chris Knakal and Hyungjin Lee
// CSS 430 Program 5
// 5/30/2016
import java.util.Vector;
public class FileTable
{
private final static int UNUSED = 0;
private final static int USED = 1;
private final static int READ = 2;
private final static int WRITE = 3;
private final static int PENDING_DELETE = 4;
private Vector table; // the actual entity of this file table
private Directory dir; // the root directory
private Vector<Inode> inodeList; // maintains all inode on MEMORY
public FileTable(Directory directory) // constructor
{
table = new Vector(); // instantiate a file (structure) table
dir = directory; // receive a reference to the Director
} // from the file system
// major public methods
// Allocates new file table entry for the filename
// Allocate and retrieve the corresponding inode
// Returns reference to the file table entry
public synchronized FileTableEntry falloc(String filename, String mode)
{
short inumber = -1;
Inode node = null;
// loop for synchronized threads
while(true)
{
// allocate/retrieve and register the corresponding inode using dir
inumber = dir.namei(filename);
// if the file doesn't exist in the directory and mode isn't read
if (inumber == -1 && !mode.equals("r"))
{
// allocate an inumber for the file
inumber = dir.ialloc(filename);
// create an inode for the file
node = new Inode();
}
// if the file does exist in the directory
else if (inumber >= 0)
{
// get the file from disk
node = new Inode(inumber);
SysLib.cout("Inumber: " + inumber + "\n");
SysLib.cout("Inode count: " + node.count + "\n");
// if the inode is set to be deleted
if (node.flag == PENDING_DELETE)
{
// no other threads may access the inode
return null;
}
// if the request mode is read
if (mode.equals("r"))
{
// if no other threads are writing, or the inode is pendingDelete
if (node.flag != WRITE)
{
node.flag = READ;
break;
}
// else other threads are writing to the inode
else
{
try
{
// wait for writing thread to get done
wait();
}
catch (Exception e){}
}
}
// if the request mode is write, write/read, or append
else
{
if (node.flag == USED || node.flag == UNUSED)
{
node.flag = WRITE;
break;
}
else
{
try
{
wait();
}
catch (Exception e) {}
}
}
}
else
{
return null;
}
}
FileTableEntry ftEnt = new FileTableEntry(node, inumber, mode);
// allocate a new file (structure) table entry for this file name
table.addElement(ftEnt);
// increment this inode's count
ftEnt.inode.count++;
// immediately write back this inode to the disk
ftEnt.inode.toDisk(inumber);
// add inode to the inodeList
//inodeList.addElement(ftEnt.inode);
// return a reference to this file (structure) table entry
return ftEnt;
}
public synchronized boolean ffree(FileTableEntry e)
{
// if you can remove the file table entry from the file table
if (table.removeElement(e))
{
// decrement inode count
e.inode.count--;
// set the inode flag
e.inode.flag = UNUSED;
// save the corresponding inode to the disk
e.inode.toDisk(e.iNumber);
// free this file table entry.
table.remove(e);
// notify all threads waiting for access to this inode
notifyAll();
// return true if this file table entry found in my table
return true;
}
// file table entry not removed
return false;
}
// return if table is empty
// should be called before starting a format
public synchronized boolean fempty()
{
return table.isEmpty( );
}
// Gets the specified Inode via iNumber lookup through FileTableEntries
public synchronized Inode getInode(int iNumber)
{
for (int i = 0; i < table.size(); i++)
{
FileTableEntry temp = (FileTableEntry) table.elementAt(i);
if (temp.iNumber == (short) i)
{
return temp.inode;
}
}
// error
return null;
}
}