Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Эмулятор файловой системы на С++

55K
14 октября 2012 года
g00dv1n
22 / / 28.11.2010
Здравствуйте, пишу курсовую, некое подобие эмулятора файловой системы.

За основу взял ext2. Понятное дело у меня все намного проще.

Делаю в текстовом редакторе, а компилирую на g++. Еще и на линуксе работаю)


В общем написал уже немного кода. Вроде все работает. Но есть некоторые проблемы, не могу понять в чем ошибка..

Пока у меня реализованы простые функции, создание ФС(запись суперблока, битовой карты инодов и свободных блоков, и самих инодов), записи файла по иноду и чтнение по иноду.

Так вот при чтении возникают проблемы, и я не могу понять совершенно в чем дело.

Читаю один раз, все нормально, читаю 2 раза, пишет ошибка сегментации.

Ниже приведу код, специалистам прошу указать на мои ошибки, наверняка они глупые.

FileSystem.cpp


Код:
#pragma once

#include <cstdio>
#include <iostream>
#include <fstream>
#include <string.h>
#include "SuperBlock.cpp"
#include <string>
using namespace std;

#define MAININODE 0
#define HOMEINODE 1

class FileSystem
{
private:
    int _CURRENT_INODE;
    int _LAST_INODE;
    int _superBlockSize;
    int _BlockSize;
    long int _DiskSize;
    int _inodeSize;
    int _maxInodeCount;
    int _BlockCount;
    int _BlBitmapSize;
    int _InBitmapSize;
    SuperBlock _superblock;
    Inode *INODES;
    fstream fsys;
    int *BLOCKSBITMAP;
    int *INODESBITMAP;
    int _InodesOfset;
    int _InodesBitmapOfset;
    int _BlocksBitmapOfset;
    int _BlocksOfset;
public:
    FileSystem();
    void _Create();
    void _CreateHomeDir();
    void _PrepareInodes();
    void WriteInode(int number, Inode inode);
    void ReadInode(int number, Inode inode);
    void WriteFile (char *file, Inode inode, int numberInode);
    char* ReadFile (Inode _inode);
    int FindFreeBloks(int *bloks,int count);
    void _PrepareBlocksBitmap();
    void Test(Inode in)
    {
        cout << ReadFile(in);
        cout << ReadFile(in);
        cout << ReadFile(in);
        cout << ReadFile(in);
    }
    ~FileSystem();
};

FileSystem::FileSystem()
{
    _CURRENT_INODE = HOMEINODE;
    _LAST_INODE = MAININODE;

    Inode _in;

    _maxInodeCount = 200;
    _DiskSize = 1024*1024; // 1mb
    _superBlockSize = sizeof(_superblock);
    _BlockSize = 512;
    _inodeSize = sizeof(_in);
    INODES = new Inode[_maxInodeCount];
    INODESBITMAP = new int[_maxInodeCount];
    _InBitmapSize = sizeof(int)*_maxInodeCount;
    _BlockCount = (_DiskSize - (_superBlockSize + (_inodeSize*_maxInodeCount) + 4*_maxInodeCount ) ) / (_BlockSize+sizeof(int));
    BLOCKSBITMAP = new int[_BlockCount];
    _BlBitmapSize = sizeof(int) * _BlockCount;
    printf("Debug^ _BlockCount::: %d\n",_BlockCount );
    _superblock.SetSuperBlock(_maxInodeCount,_BlockCount,_maxInodeCount,_BlockCount,_BlockSize,1);
    _InodesOfset = _superBlockSize;
    _InodesBitmapOfset = _InodesOfset +_inodeSize*_maxInodeCount;
    _BlocksBitmapOfset = _InodesBitmapOfset + _InBitmapSize;
    _BlocksOfset = _BlocksBitmapOfset + _BlBitmapSize;
    _Create();
}

FileSystem::~FileSystem()
{

}

void FileSystem::_Create()
{
    //fstream fsys("fileSystem.bin", ios::in | ios::out | ios::binary | ios::trunc);
    //fstream fsys("fileSystem.bin", ios::in | ios::out | ios::binary ) ;
    fstream fl("fileSystem.bin", ios::in | ios::out | ios::binary );
    if(!fl.is_open())
    {
        //fsys.close();
        fsys.open("fileSystem.bin", ios::in | ios::out | ios::binary | ios::trunc);
        fsys.seekg(0, ios::beg);
        char * buf = new char [_DiskSize];
        fsys.write(buf,_DiskSize);
        fsys.seekg(0, ios::beg);
        fsys.write((char*) &_superblock, _superBlockSize);
        _PrepareInodes();
        _PrepareBlocksBitmap();
        fsys.seekg(_BlocksBitmapOfset, ios::beg);
        fsys.write((char*) BLOCKSBITMAP, _BlBitmapSize);
        fsys.seekg(_InodesBitmapOfset, ios::beg);
        fsys.write((char*) INODESBITMAP, _InBitmapSize);
        fsys.seekg(0, ios::end);
        /*int *a = new int [2];
        a[0]=666;
        a[1]=777;
        fsys.write((char*) a, 8);
        fsys.seekg(0, ios::end);*/


        cout << "Size of File system " << fsys.tellg()<<endl;
        fsys.close();
        _CreateHomeDir();

    }
    else
    {  
        fl.close();
        fsys.open("fileSystem.bin", ios::in | ios::out | ios::binary);
        fsys.seekg(0, ios::beg);
        fsys.read((char*) &_superblock, _superBlockSize);
        fsys.seekg(_BlocksBitmapOfset, ios::beg);
        fsys.read((char*) BLOCKSBITMAP, _BlBitmapSize);
        fsys.seekg(_InodesBitmapOfset, ios::beg);
        fsys.read((char*) INODESBITMAP, _InBitmapSize);
        fsys.seekg(0, ios::end);
        cout << "Size of File system " << fsys.tellg()<<endl;
        Inode in;
        Inode in1;
        fsys.seekg(_InodesOfset + _inodeSize,ios::beg);
        fsys.read((char*) &in, _inodeSize);
        fsys.seekg(_InodesOfset,ios::beg);
        fsys.read((char*) &in1, _inodeSize);
        fsys.close();
        cout << ReadFile(in);
        cout << ReadFile(in1);



    }
    /*SuperBlock superblock;
    fsys.seekg(0, ios::beg);
    char * buf = new char [_DiskSize];
    fsys.write(buf,_DiskSize);
    fsys.seekg(0, ios::end);
    cout << fsys.tellg()<<endl;
    fsys.seekg(0, ios::beg);
    _superblock.SetFrBl(666);
    //fsys.write((char*) &_superblock, _superBlockSize);
    fsys.seekg(0, ios::beg);
    fsys.read((char*) &superblock, _superBlockSize);
    cout << superblock.getFrBl() << endl;
    cout << fsys.tellg()<<endl;
    fsys.seekg(0, ios::end);
    cout << fsys.tellg()<<endl;
    fsys.close();

    fsys.seekg(0,ios::beg);
    fsys.write((char *) &BLOCKSBITMAP, _BlBitmapSize);
    cout << fsys.tellg()<<endl;*/


    //fsys.close();

    /*int *a = new int [4];
    a[1]=666;
    int *b = a;
    cout << b[1];*/

}

void FileSystem::_PrepareInodes()
{
    //fsys.open("fileSystem.bin", ios::in | ios::out | ios::binary ) ;
    fsys.seekg(_superBlockSize, ios::beg);
    for(int i=0; i< _maxInodeCount; i++)
    {
        INODESBITMAP[i] = 0;
        Inode _ind;
        //fsys.write((char *) &_ind, _inodeSize);
    }
    //fsys.close();
}

void FileSystem::_PrepareBlocksBitmap()
{
    for(int i=0; i< _BlockCount;i++)
    {
        BLOCKSBITMAP [i] = 0;
    }

}
void FileSystem::WriteFile (char *file, Inode inode, int numberInode)
{
    fsys.open("fileSystem.bin", ios::in | ios::out | ios::binary);

    int countBloks=strlen(file)/_BlockSize ;
    if(strlen(file)%_BlockSize)
    {
    countBloks+=1;
    }
    cout << "countBloks " << countBloks <<endl;
    //system("PAUSE");
    int Up = _BlockSize;
    int Down = 0;
    int *bloks = new int [countBloks];
    if(FindFreeBloks(bloks,countBloks))
    {
        //system("PAUSE");
        for(int i=0;i<countBloks;i++)
        {
            char *t = new char [_BlockSize];
            int k=0;
            //system("PAUSE");
            for (int j= Down;i<Up;j++)
            {
                if(j>strlen(file))
                {
                    break;
                }
                t[k] = file[j];
                k++;
                //cout << "J " << j << endl;
                //system("PAUSE");
            }
            //cout << "1" << endl;
            ///cout << t << endl;
            //system("PAUSE");
            // write data
            //cout << "2" <<  endl;
            //cout << i << endl;
            //system("PAUSE");
            //cout << "WRITE BUF \n"  << strlen(file) << endl << "~ WRITE BUF" << endl;
            fsys.seekg(_BlocksOfset + _BlockSize*bloks[i],ios::beg);
            //cout << "3" << endl;
            //system("PAUSE");
            fsys.write(t,_BlockSize);
            inode.setAdr(i,bloks[i]);
            //cout << "T=== "  << t << endl;
            fsys.seekg(_InodesOfset + _inodeSize*numberInode ,ios::beg);
            fsys.write((char*) &inode, _inodeSize);
            BLOCKSBITMAP[bloks[i]] = 1;
            fsys.seekg(_BlocksBitmapOfset, ios::beg);
            fsys.write((char *) BLOCKSBITMAP, _BlBitmapSize);
            /*//
            char *a = new char [512];
            fsys.seekg(_BlocksOfset + _BlockSize*bloks[i],ios::beg);
            fsys.read(a,512);
            cout << " READ TEST   " << a << endl;
            //*/


            bloks[i] = 1;
            Down =Up;
            Up +=_BlockSize;

        }
    }
    else
    {
        printf("SYSTEM^ _TOO BIG FILE::: ");   
    }

    fsys.close();

}


int FileSystem::FindFreeBloks(int *bloks,int count)
{
    //cout << "BLOCKSBITMAP [0]=" << BLOCKSBITMAP[0] << endl;
    int _c=0;
    for(int i=0; i< _BlockCount;i++)
    {
        if(BLOCKSBITMAP[i]==0)
        {
            if(_c<count)
            {
                //cout <<"C " << _c << endl;
                //system("PAUSE");
                bloks[_c]=i;
                //cout << "BLOKS : MAs" << BLOCKSBITMAP[i];
                _c++;
                //cout <<"Bl" << bloks[0] << endl;
                //system("PAUSE");
            }
            else
            {
                return 1;
            }
        }
    }
    if (_c==count)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

void FileSystem::_CreateHomeDir()
{
    fsys.open("fileSystem.bin", ios::in | ios::out | ios::binary);
    INODESBITMAP[MAININODE] = 1;
    INODESBITMAP[HOMEINODE] = 1;
    char *MainDir = "0 .\n0 ..\n1 home\n";
    //
    char *HomeDir = "1 .\n0 ..\n";
    cout << "Debug::TEST DIR FILE^ " << MainDir << HomeDir;
    fsys.seekg(_InodesBitmapOfset,ios::beg);
    fsys.write((char *) &INODESBITMAP, _InBitmapSize);
    fsys.close();
    Inode mainIn;
    Inode homeIn;
    WriteFile(MainDir,mainIn,MAININODE);
    WriteFile(HomeDir,homeIn,HOMEINODE);
}

char* FileSystem::ReadFile(Inode _inode)
{

    int _count = _inode.getBlocks();
    fsys.open("fileSystem.bin", ios::in | ios::out | ios::binary);
    char *file;
    string str = "";
    //cout << "READ_FILE^ \n" << inode.getAdr(0) << endl << inode.getAdr(i) << endl<< "redaasdasd";
    /*while(adrs>=0)
    {

        char *buf;
        fsys.seekg(_BlocksOfset + _BlockSize*adrs, ios::beg);
        fsys.read(buf, _BlockSize);
        str += buf;
        adrs = _inode.getAdr(i);
        i++;
        cout << "TEST\n" << _inode.getAdr(i) << "~TEST\n";

    }*/

    /*for(int i=0; ; i++)
    {

        char *buf;
        fsys.seekg(_BlocksOfset + _BlockSize*_inode.getAdr(0), ios::beg);
        fsys.read(buf, _BlockSize);
        str += buf;
        //adrs = ;
        if (_inode.getAdr(i)==-1)
        {
            break;
        }
        cout <<  "I = " << i << endl;
    }*/

    for(int i=0;i<_count;i++)
    {
        char *buf;
        fsys.seekg(_BlocksOfset + _BlockSize*_inode.getAdr(i), ios::beg);
        fsys.read(buf, _BlockSize);
        str += buf;
    }

    fsys.close();
    cout << "Count " << _count << endl;
    file = new char[str.length()+1];
    strcpy(file,str.c_str());

    return file;
}
Inode.cpp

Код:
#pragma once

#define CLEAR 0x0
#define FILE  0x1
#define DIR   0x2

#define USER  0x00
#define ROOT  0x11

#define MAX_BLOKS_FOR_FILE 100

#include "Time.cpp"

class Inode
{

private:
int i_uid;
int i_flags;
int i_bloks;
int i_links_count;
int i_gid;
Time i_ctime; // Create time
Time i_atime; // Last using time
Time i_mtime; // Last change time
Time i_dtime; // Last delete time
int adrBloks[MAX_BLOKS_FOR_FILE];

public:
    int getUid();
    int getFlags();
    int getBlocks();
    int getLinksCount();
    int getGid();
    Time getCtime();
    Time getAtime();
    Time getMtime();
    Time getDtime();
    void setUid(int _uid);
    void setFlags(int _flags);
    void setBlocks(int _bloks);
    void setCtime (Time _ctime);
    void setAtime(Time _atime);
    void setMtime(Time _mtime);
    void setDtime(Time _dtime);
    void setCountLinks(int _countLinks);
    void setAdr(int nubmer, int adr);
    int getAdr(int nubmer);
    Inode();
    ~Inode();
};


void Inode::setAdr(int nubmer, int adr)
{
    adrBloks[nubmer] = adr;
}

int Inode::getAdr(int nubmer)
{
    return adrBloks[nubmer];
}

Inode::Inode()
{
    i_bloks = 0;
    i_uid = 0;
    i_flags = CLEAR;
    i_links_count = 0;
    i_gid = ROOT;
    for (int i=0 ; i< MAX_BLOKS_FOR_FILE;i++)
    {
        adrBloks[i] = -1;
    }
   

}

Inode::~Inode()
{

}

Time Inode::getDtime()
{
    return i_dtime;
}

Time Inode::getAtime()
{
    return i_atime;
}

Time Inode::getCtime()
{
    return i_ctime;
}

Time Inode::getMtime()
{
    return i_mtime;
}

int Inode::getGid()
{
    return i_gid;
}

int Inode::getUid()
{
    return i_uid;
}

int Inode::getFlags()
{
    return i_flags;
}

int Inode::getBlocks()
{
    i_bloks = 0;
    for (int i=0; i<MAX_BLOKS_FOR_FILE;i++)
    {
        if(adrBloks[i]>=0)
        {
            i_bloks+=1;
        }
    }
    return i_bloks;
}

int Inode::getLinksCount()
{
    return i_links_count;
}

void Inode::setDtime(Time _dtime)
{
    i_dtime = _dtime;
}

void Inode::setAtime(Time _atime)
{
    i_atime = _atime;
}

void Inode::setCtime(Time _ctime)
{
    i_ctime = _ctime;
}

void Inode::setMtime(Time _mtime)
{
    i_mtime = _mtime;
}

void Inode::setUid(int _uid)
{
    i_uid = _uid;
}

void Inode::setBlocks(int _bloks)
{
    i_bloks = _bloks;
}

void Inode::setFlags(int _flags)
{
    i_flags = _flags;
}

void Inode::setCountLinks(int _countLinks)
{
    i_links_count = _countLinks;
}

Заранее благодарен!!!
297
14 октября 2012 года
koodeer
1.2K / / 02.05.2009
Цитата:
C++

Угу.
Тут же в коде вижу:

Цитата:
#include <cstdio>

Вздрагиваю, чувствуя недоброе.
Смотрю код дальше, так и есть: смесь C++ и C. Может для начала всё переписать на одном языке, не используя другой?

В коде используются сырые указатели. Это не путь C++!
Вижу много выделений памяти с помощью new, и не вижу ни одного delete. Утечки памяти налицо.

Саму логику кода не разбирал, поэтому не скажу, есть ли в ней ошибки.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог