surfing the directory;
This commit is contained in:
1 parent
599d04c280
commit
cd65bd626a
3 files changed
+111
-26
No files matched your search
+35
-13
@@ -47,9 +47,10 @@ void EXT2_FS::printFS() {
|
||||
}
|
||||
}
|
||||
|
||||
void EXT2_FS::printInode(Inode* i) {
|
||||
void EXT2_Inode::print() {
|
||||
|
||||
using namespace std;
|
||||
cout << "\nInode:" << endl;
|
||||
cout << "\nInode: " << inode_n << endl;
|
||||
cout << "文件类型和访问权限 " << i->mode << mode_to_str(i->mode) << endl;
|
||||
cout << "拥有者 " << i->uid << endl;
|
||||
cout << "文件长度 " << i->size << endl;
|
||||
@@ -76,6 +77,19 @@ int EXT2_FS::block_to_pos(int block) {
|
||||
return (block - 1) * block_size + 1024;
|
||||
}
|
||||
|
||||
int EXT2_FS::inode_to_pos(int inode_n) {
|
||||
int max_inodes_in_group = 8 * block_size;
|
||||
auto it = gdt_list.begin();
|
||||
while (it != gdt_list.end() && inode_n > max_inodes_in_group) {
|
||||
inode_n -= max_inodes_in_group;
|
||||
it++;
|
||||
}
|
||||
_error(it == gdt_list.end());
|
||||
_error(inode_n > max_inodes_in_group);
|
||||
|
||||
return block_to_pos((*it)->inode_table) + inode_n * sizeof(Inode);
|
||||
}
|
||||
|
||||
void EXT2_FS::mount() {
|
||||
sb = new SuperBlock();
|
||||
dev->seek(1024); // 跳过引导块
|
||||
@@ -113,15 +127,15 @@ void EXT2_FS::mount() {
|
||||
// dev->read(sb_buf, sizeof(Inode));
|
||||
// Inode* root_inode = new Inode();
|
||||
// memmove(root_inode, sb_buf.data, sizeof(Inode));
|
||||
_u32 root_inode_pos = block_to_pos(gdt_list.front()->inode_table) + sizeof(Inode);
|
||||
_u32 root_inode_pos = gdt_list.front()->inode_table;
|
||||
EXT2_DEntry* ext2_entry;
|
||||
ext2_entry = new EXT2_DEntry(this, nullptr, root_inode_pos, VFS::Directory, "/");
|
||||
ext2_entry = new EXT2_DEntry(this, nullptr, 1, VFS::Directory, "/");
|
||||
root = ext2_entry;
|
||||
// ext2_entry->inflate();
|
||||
// ext2_entry->load_children();
|
||||
|
||||
// _sa(sb_buf.data, 1024);
|
||||
//printFS();
|
||||
printFS();
|
||||
//printInode(ext2_entry->ext2_inode->i);
|
||||
status = VFS::FS_mounted;
|
||||
}
|
||||
@@ -133,7 +147,7 @@ EXT2_FS::~EXT2_FS() {
|
||||
delete sb;
|
||||
}
|
||||
|
||||
EXT2_Inode::EXT2_Inode(EXT2_FS *fs, EXT2::Inode *i): VFS::Inode(fs) {
|
||||
EXT2_Inode::EXT2_Inode(EXT2_FS *fs, _u32 n, EXT2::Inode *i): VFS::Inode(fs) {
|
||||
this->i = i;
|
||||
ino = 0;
|
||||
counter = 0;
|
||||
@@ -151,6 +165,7 @@ EXT2_Inode::EXT2_Inode(EXT2_FS *fs, EXT2::Inode *i): VFS::Inode(fs) {
|
||||
blocks = i->blocks;
|
||||
bytes = 0;
|
||||
sock = 1;
|
||||
inode_n = n;
|
||||
}
|
||||
|
||||
EXT2_DEntry::EXT2_DEntry(EXT2_FS* fs1, VFS::DEntry* parent1,
|
||||
@@ -166,9 +181,9 @@ EXT2_DEntry::EXT2_DEntry(EXT2_FS* fs1, VFS::DEntry* parent1,
|
||||
}
|
||||
|
||||
void EXT2_DEntry::load_children() {
|
||||
if (ext2_inode == nullptr || sync == 1) {
|
||||
inflate();
|
||||
}
|
||||
if (ext2_inode != nullptr && sync == 0)
|
||||
return ;
|
||||
inflate();
|
||||
_log_info("load children");
|
||||
|
||||
_error(ext2_inode == nullptr);
|
||||
@@ -185,6 +200,8 @@ void EXT2_DEntry::load_children() {
|
||||
_u32 s_pos = 0;
|
||||
_u32 next_length = 12;
|
||||
DirEntry *temp_str = new DirEntry();
|
||||
for (auto x: children)
|
||||
delete x;
|
||||
children.clear();
|
||||
while (true) {
|
||||
// _sa(buf.data + s_pos, 20);
|
||||
@@ -192,7 +209,7 @@ void EXT2_DEntry::load_children() {
|
||||
if (temp_str->rec_len == 0)
|
||||
break;
|
||||
EXT2_DEntry *sub = new EXT2_DEntry(ext2_fs, this,
|
||||
temp_str->inode, temp_str->file_type,
|
||||
temp_str->inode - 1, temp_str->file_type,
|
||||
std::string((char*)temp_str->name, temp_str->name_len));
|
||||
children.push_back(sub);
|
||||
// std::cout << sub->name << " " << sub->inode_n << std::endl;
|
||||
@@ -206,12 +223,13 @@ void EXT2_DEntry::inflate() {
|
||||
_log_info("inflate");
|
||||
EXT2::Inode* disk_inode = new Inode();
|
||||
MM::Buf buf(sizeof(Inode));
|
||||
_u32 inode_pos = inode_n;
|
||||
// _si(inode_pos);
|
||||
_u32 inode_pos = ext2_fs->inode_to_pos(inode_n);
|
||||
_si(inode_pos);
|
||||
fs->dev->seek(inode_pos);
|
||||
fs->dev->read(buf, sizeof(Inode));
|
||||
memcpy(disk_inode, buf.data, sizeof(Inode));
|
||||
ext2_inode = new EXT2_Inode(ext2_fs, disk_inode);
|
||||
ext2_inode = new EXT2_Inode(ext2_fs, inode_n, disk_inode);
|
||||
ext2_inode->print();
|
||||
inode = ext2_inode;
|
||||
sync = 0;
|
||||
}
|
||||
@@ -219,4 +237,8 @@ void EXT2_DEntry::inflate() {
|
||||
|
||||
EXT2_DEntry::~EXT2_DEntry() {
|
||||
delete inode;
|
||||
}
|
||||
|
||||
EXT2_Inode::~EXT2_Inode() {
|
||||
delete i;
|
||||
}
|
||||
+9
-4
@@ -8,13 +8,15 @@ namespace EXT2 {
|
||||
|
||||
|
||||
class EXT2_FS: public VFS::FS {
|
||||
std::list<GroupDescriptor*> gdt_list;
|
||||
SuperBlock* sb;
|
||||
|
||||
void printFS();
|
||||
void printInode(Inode*);
|
||||
public:
|
||||
int block_to_pos(int block);
|
||||
int inode_to_pos(int inode_n);
|
||||
|
||||
SuperBlock* sb;
|
||||
std::list<GroupDescriptor*> gdt_list;
|
||||
|
||||
_u32 block_size;
|
||||
EXT2_FS(Dev::BlockDevice* dev);
|
||||
@@ -24,9 +26,12 @@ public:
|
||||
|
||||
class EXT2_Inode: public VFS::Inode {
|
||||
public:
|
||||
EXT2_Inode(EXT2_FS*, EXT2::Inode*);
|
||||
EXT2_Inode(EXT2_FS*, _u32 n, EXT2::Inode*);
|
||||
_u32 inode_n;
|
||||
EXT2::Inode* i;
|
||||
void print_Inode();
|
||||
void print();
|
||||
|
||||
~EXT2_Inode();
|
||||
|
||||
};
|
||||
|
||||
|
||||
+67
-9
@@ -1,17 +1,70 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "ext2/ext2_fs.h"
|
||||
#include "dev/block_dev.h"
|
||||
#include "dev/mock_disk.h"
|
||||
|
||||
void ls(VFS::DEntry *cwd) {
|
||||
std::vector<std::string> split(const std::string& s, char sp) {
|
||||
int i = 0, l = 0;
|
||||
std::vector<std::string> res;
|
||||
while (i < s.size()) {
|
||||
if (s[i] == sp) {
|
||||
if (i != l)
|
||||
res.push_back(s.substr(l, i - l));
|
||||
l = i + 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i != l)
|
||||
res.push_back(s.substr(l, i - l));
|
||||
return res;
|
||||
}
|
||||
|
||||
void ls(VFS::DEntry *cwd, std::vector<std::string> cmdd) {
|
||||
using namespace std;
|
||||
cwd->load_children();
|
||||
for (auto& x: cwd->children) {
|
||||
cout << x->name << " ";
|
||||
if (cmdd.size() == 2 && cmdd[1] == "l")
|
||||
cout << x->name << " " << x->inode_n << endl;
|
||||
else
|
||||
cout << x->name << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
VFS::DEntry *cd(VFS::DEntry *cwd, const std::vector<std::string>& cmdd) {
|
||||
using namespace std;
|
||||
cwd->load_children();
|
||||
list<VFS::DEntry*>::iterator it = cwd->children.begin();
|
||||
VFS::DEntry *ans = cwd;
|
||||
if (cmdd[1] == ".")
|
||||
;
|
||||
else if (cmdd[1] == "..") {
|
||||
|
||||
if (cwd->parent != nullptr)
|
||||
ans = cwd->parent;
|
||||
} else {
|
||||
while(it != cwd->children.end()) {
|
||||
if (cmdd[1] == (*it)->name) {
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
if (it == cwd->children.end()) {
|
||||
cout << "No such directory " << cmdd[1] << endl;
|
||||
} else {
|
||||
if ((*it)->type != VFS::Directory) {
|
||||
cout << cmdd[1] << " is not a directory." << endl;
|
||||
}
|
||||
ans = *it;
|
||||
}
|
||||
}
|
||||
// if (cwd != ans)
|
||||
// delete cwd;
|
||||
return ans;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
using namespace std;
|
||||
|
||||
@@ -23,19 +76,24 @@ int main(void) {
|
||||
string cmd;
|
||||
VFS::DEntry *cwd = nullptr;
|
||||
|
||||
cout << "$ ";
|
||||
cout << "[umount]$ ";
|
||||
while (getline(cin, cmd)) {
|
||||
vector<string> cmdd = split(cmd, ' ');
|
||||
if (cmd == "mount") {
|
||||
fs->mount();
|
||||
cwd = fs->root;
|
||||
cout << "mount disk at /" << endl;
|
||||
} else if (fs->status == VFS::FS_unmounted) {
|
||||
cout << "Please mount fs first." << endl;
|
||||
} else if (cmd == "ls") {
|
||||
cwd->load_children();
|
||||
ls(cwd);
|
||||
} else if (cmdd[0] == "ls") {
|
||||
ls(cwd, cmdd);
|
||||
} else if (cmdd[0] == "cd") {
|
||||
cwd = cd(cwd, cmdd);
|
||||
}
|
||||
|
||||
cout << "$ ";
|
||||
|
||||
if (cwd != nullptr)
|
||||
cout << cwd->name << "$ ";
|
||||
else
|
||||
cout << "[umount]$ ";
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user