-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathOpenFileManager.cpp
156 lines (135 loc) · 3.79 KB
/
OpenFileManager.cpp
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
#include "Utility.h"
#include "OpenFileManager.h"
#include "User.h"
extern BufferManager g_BufferManager;
extern FileSystem g_FileSystem;
extern INodeTable g_INodeTable;
extern User g_User;
OpenFileTable::OpenFileTable() {
}
OpenFileTable::~OpenFileTable() {
}
void OpenFileTable::Format() {
File emptyFile;
for (int i = 0; i < OpenFileTable::MAX_FILES; ++i) {
Utility::memcpy(m_File + i, &emptyFile, sizeof(File));
}
}
/*作用:进程打开文件描述符表中找的空闲项之下标写入 ar0[EAX]*/
File* OpenFileTable::FAlloc() {
User& u = g_User;
int fd = u.ofiles.AllocFreeSlot();
if (fd < 0) {
return NULL;
}
for (int i = 0; i < OpenFileTable::MAX_FILES; ++i) {
/* count==0表示该项空闲 */
if (this->m_File[i].count == 0) {
u.ofiles.SetF(fd, &this->m_File[i]);
this->m_File[i].count++;
this->m_File[i].offset = 0;
return (&this->m_File[i]);
}
}
u.u_error = User::U_ENFILE;
return NULL;
}
/* 对打开文件控制块File结构的引用计数count减1,若引用计数count为0,则释放File结构。*/
void OpenFileTable::CloseF(File* pFile) {
pFile->count--;
if (pFile->count <= 0) {
g_INodeTable.IPut(pFile->inode);
}
}
INodeTable::INodeTable() {
fileSystem = &g_FileSystem;
}
INodeTable::~INodeTable() {
}
void INodeTable::Format() {
INode emptyINode;
for (int i = 0; i < INodeTable::NINODE; ++i) {
Utility::memcpy(m_INode + i, &emptyINode, sizeof(INode));
}
}
/*
* 检查编号为inumber的外存INode是否有内存拷贝,
* 如果有则返回该内存INode在内存INode表中的索引
*/
int INodeTable::IsLoaded(int inumber) {
for (int i = 0; i < NINODE; ++i) {
if (m_INode[i].i_number == inumber&&m_INode[i].i_count) {
return i;
}
}
return -1;
}
/* 在内存INode表中寻找一个空闲的内存INode */
INode* INodeTable::GetFreeINode() {
for (int i = 0; i < INodeTable::NINODE; i++) {
if (this->m_INode[i].i_count == 0) {
return m_INode + i;
}
}
return NULL;
}
/*
* 根据外存INode编号获取对应INode。
* 如果该INode已经在内存中,返回该内存INode;
* 如果不在内存中,则将其读入内存后上锁并返回该内存INode
* 返回NULL:INode Table OverFlow!
*/
INode* INodeTable::IGet(int inumber) {
INode* pINode;
int index = IsLoaded(inumber);
if (index >= 0) {
pINode = m_INode + index;
++pINode->i_count;
return pINode;
}
pINode = GetFreeINode();
if (NULL == pINode) {
cout << "INode Table Overflow !" << endl;
g_User.u_error = User::U_ENFILE;
return NULL;
}
pINode->i_number = inumber;
pINode->i_count++;
BufferManager& bmg = g_BufferManager;
Buffer* pBuffer = bmg.Bread(FileSystem::INODE_ZONE_START_SECTOR + inumber / FileSystem::INODE_NUMBER_PER_SECTOR);
pINode->ICopy(pBuffer, inumber);
bmg.Brelse(pBuffer);
return pINode;
}
/*
* 减少该内存INode的引用计数,如果此INode已经没有目录项指向它,
* 且无进程引用该INode,则释放此文件占用的磁盘块。
*/
void INodeTable::IPut(INode* pINode) {
/* 当前进程为引用该内存INode的唯一进程,且准备释放该内存INode */
if (pINode->i_count == 1) {
/* 该文件已经没有目录路径指向它 */
if (pINode->i_nlink <= 0) {
/* 释放该文件占据的数据盘块 */
pINode->ITrunc();
pINode->i_mode = 0;
/* 释放对应的外存INode */
this->fileSystem->IFree(pINode->i_number);
}
/* 更新外存INode信息 */
pINode->IUpdate((int)Utility::time(NULL));
/* 清除内存INode的所有标志位 */
pINode->i_flag = 0;
/* 这是内存inode空闲的标志之一,另一个是i_count == 0 */
pINode->i_number = -1;
}
pINode->i_count--;
}
/* 将所有被修改过的内存INode更新到对应外存INode中 */
void INodeTable::UpdateINodeTable() {
for (int i = 0; i < INodeTable::NINODE; ++i) {
if (this->m_INode[i].i_count) {
this->m_INode[i].IUpdate((int)Utility::time(NULL));
}
}
}