?? yafs_op.h
字號:
/*!
* \file
* \brief 各種內存數據結構以及磁盤數據結構的操作函數
*
* 各種內存數據結構以及磁盤數據結構的操作函數的定義 */
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <ctime>
#include <cmath>
#include <list>
#include <string.h>
#include <memory.h>
#include "yafs.h"
#include "yafs_mem.h"
using std::list;
struct super_block initSuperBlock; //!<內存中的超級塊
struct group_desc initGroupDesc; //!<內存中的塊組描述符
struct dir_entry_mem result; //!<目錄結構的根目錄
/*!
* \brief 將內存中的超級塊結構寫入磁盤中 * @param initSuperBlock 內存中的超級塊結構 */
void writeSuperBlock( struct super_block initSuperBlock )
{
FILE *file = fopen( "disk.img", "r+" );
fseek( file, 0, SEEK_SET );
fwrite( &initSuperBlock, sizeof( struct super_block ), 1, file );
fclose( file );
}
/*!
* \brief 將磁盤上的超級塊結構讀取到內存中 */
void getSuperBlock()
{
FILE *file = fopen ( "disk.img", "r+" );
fseek( file, 0, SEEK_SET );
fread( &initSuperBlock, sizeof( super_block ), 1, file );
fclose( file );
}
/*!
* \brief 將磁盤中的塊組描述符讀取到內存中 */
void getGroupDesc()
{
FILE *file = fopen( "disk.img", "r+" );
fseek( file, 1 * 1024, SEEK_SET );
fread( &initGroupDesc, sizeof( group_desc ), 1, file );
fclose( file );
}
/*!
* \brief 將內存中的塊組描述符寫入到磁盤中 * @param initGroupDesc 內存中的塊組描述符 */
void writeGroupDesc( struct group_desc initGroupDesc )
{
FILE *file = fopen( "disk.img", "r+" );
fseek( file, 1024, SEEK_SET );
fwrite( &initGroupDesc, sizeof( group_desc ), 1, file );
fclose( file );
}
/*!
* \brief 將內存中的塊“位圖”寫入到磁盤中 * @param blockBitmap 內存的中塊“位圖” */
void writeBlockBitmap( char blockBitmap[] )
{
FILE *file = fopen( "disk.img", "r+" );
fseek( file, 2 * 1024, SEEK_SET );
fwrite( blockBitmap, sizeof( char ) * 1024, 1, file );
fclose( file );
}
/*!
* \brief 更新磁盤中的塊“位圖”中特定”位“的值,將特定的數據塊標記為已使用或者為使用 * @param offset 需要標記的數據塊的塊號 * @param c “位”修改后的值,'0'表示未被使用,'1'表示正在使用 */
void updateBlockBitmap( int offset, char c )
{
FILE *file = fopen( "disk.img", "r+" );
fseek( file, initGroupDesc.block_bitmap * 1024 + offset * sizeof( char ), SEEK_SET );
fwrite( &c, sizeof( char ), 1, file );
fclose( file );
}
/*!
* \brief 將內存中的結點“位圖”寫入到磁盤中 * @param inodeBitmap 內存中的結點“位圖” */
void writeInodeBitmap( char inodeBitmap[] )
{
FILE *file = fopen ( "disk.img", "r+" );
fseek( file, initGroupDesc.inode_bitmap * 1024, SEEK_SET );
fwrite( inodeBitmap, sizeof( char ) * 1024, 1, file );
fclose ( file );
}
/*!
* \brief 更新磁盤中的索引結點"位圖"的特定“位”的值,將特定的索引結點標記為已使用或者未使用 * @param offset 需要更新的索引結點的結點號 * @param c “位”修改后的值,'0'表示未被使用,'1'表示正在使用 */
void updateInodeBitmap( int offset, char c )
{
FILE *file= fopen ( "disk.img", "r+" );
fseek( file, initGroupDesc.inode_bitmap * 1024 + sizeof( char ) * offset, SEEK_SET );
fwrite( &c, sizeof( char ), 1, file );
fclose( file );
}
/*!
* \brief 將索引結點寫入到磁盤中 * @param initInode 需要寫入的索引結點 * @param offset 索引結點的結點號 */
void writeInode( struct inode initInode, int offset )
{
FILE *file = fopen ( "disk.img", "r+" );
char i = '1';
fseek( file, 4 * 1024 + offset * sizeof( struct inode ), SEEK_SET );
fwrite( &initInode, sizeof( struct inode ), 1, file );
fseek( file, 3 * 1024 + offset * sizeof( char ), SEEK_SET );
fwrite( &i, sizeof( char ), 1, file );
fclose( file );
initSuperBlock.free_inodes_count--;
initGroupDesc.free_inodes_count--;
writeSuperBlock( initSuperBlock );
writeGroupDesc( initGroupDesc );
}
/*!
* \brief 從磁盤中獲取索引結點 * @param offset 索引結點的結點號 * @return 返回一個索引結點 */
struct inode getInode( int offset )
{
FILE *file = fopen ( "disk.img", "r+" );
struct inode result;
fseek( file, 4 * 1024 + offset * sizeof( struct inode ), SEEK_SET );
fread( &result, sizeof( struct inode ), 1, file );
fclose( file );
return result;
}
/*!
* \brief 將索引結點轉為內存索引結點 * @param node 被轉換的索引結點 * @return 返回一個內存索引結點 */
struct inode_mem inode2InodeMem( struct inode node)
{
struct inode_mem result;
result.node = node;
return result;
}
/*!
* \brief 將目錄項寫入到磁盤中 * @param dir 被寫入的目錄項 * @param offset 寫入位置相對于寫入塊的起始地址的偏移量 * @param block 目錄項將被寫入的塊的塊號 */
void writeDirEntry( struct dir_entry dir, int offset, int block )
{
FILE *file = fopen( "disk.img", "r+" );
fseek( file, block * 1024 + offset, SEEK_SET );
fwrite( &dir, sizeof( struct dir_entry ), 1, file );
fclose( file );
return;
}
/*!
* \brief 從磁盤中讀取一個目錄項 * @param offset 需要讀的目錄項相對于目錄項所在塊的起始地址的偏移量 * @param block 目錄項所在的塊的塊號 * @return */
struct dir_entry getDirEntry( int offset, int block )
{
FILE *file = fopen( "disk.img", "r+" );
struct dir_entry result;
fseek( file, block * 1024 + offset, SEEK_SET );
fread( &result, sizeof( struct dir_entry ), 1, file );
fclose( file );
return result;
}
/*!
* \brief 將目錄項寫入到磁盤中
*
* 將目錄項寫入到磁盤中,寫入的位置為目錄項的父目錄的子目錄的結尾 * @param father 目錄項的父目錄 * @param dir 需要被寫入的目錄項 */
void addDirEntry( struct dir_entry_mem* father, struct dir_entry dir )
{
int block = father->inode.node.i_block[ 0 ];
int offset = 0;
struct dir_entry tmpDir = getDirEntry( offset, block );
while( tmpDir.rec_len != 0 )
{
offset += tmpDir.rec_len;
tmpDir = getDirEntry( offset, block );
}
tmpDir.rec_len = sizeof( struct dir_entry );
writeDirEntry( tmpDir, offset, block );
offset += tmpDir.rec_len;
writeDirEntry( dir, offset, block );
}
/*!
*\brief 分配一個空的索引結點 * @return 返回被分配的索引結點的結點號 */
int alloInodeNum()
{
if( initSuperBlock.free_inodes_count == 0 )
{
printf( "%s", "已經沒有空的結點了\n" );
return -1;
}
FILE *file = fopen( "disk.img", "r+" );
int result = 0;
fseek( file, initGroupDesc.inode_bitmap * 1024 + result * sizeof( char ), SEEK_SET );
char c;
fread( &c, sizeof( char ), 1, file );
while ( c == '1' )
{
result++;
fseek( file, initGroupDesc.inode_bitmap * 1024 + result * sizeof( char ), SEEK_SET );
fread( &c, sizeof( char ), 1, file );
}
fclose( file );
return result;
}
/*!
* \brief 分配一個空的塊 * @return 返回被分配的塊的塊號 */
int alloBlockNum()
{
if( initSuperBlock.free_blocks_count == 0 )
{
printf( "%s", "已經沒有空的塊了\n");
return -1;
}
FILE *file = fopen( "disk.img", "r+" );
int result = 18;
fseek( file, initGroupDesc.block_bitmap * 1024 + result * sizeof( char ), SEEK_SET );
char c;
fread( &c, sizeof( char ), 1, file );
while ( c == '1' )
{
result ++;
fseek( file, initGroupDesc.block_bitmap * 1024 + result * sizeof( char ), SEEK_SET );
fread( &c, sizeof( char ), 1, file );
}
char i = '1';
fseek( file, initGroupDesc.block_bitmap * 1024 + result * sizeof( char ), SEEK_SET );
fwrite( &i, sizeof( char ), 1, file );
fclose( file );
initSuperBlock.free_blocks_count--;
initGroupDesc.free_blocks_count--;
writeSuperBlock( initSuperBlock );
writeGroupDesc( initGroupDesc );
return result;
}
/*!
* \brief 檢查指定目錄下是否存在指定名字的文件或者文件夾 * @param father 檢查的目錄 * @param name 檢查的文件名 * @return 返回一個布爾值,若為真,則不存在這樣的文件或文件夾,若否,則存在 */
bool checkName( struct dir_entry_mem father, char* name )
{
list<dir_entry_mem>::iterator iter = father.children.begin();
while( iter != father.children.end() )
{
if( strcmp( (*iter).dir.name, name ) == 0 )
return false;
iter++;
}
return true;
}
/*!
* \brief 檢查在目錄下的添加文件或者文件夾操作是否合法 * @param father 需要被檢查的目錄 * @param name 需要被檢查的文件名 * @return 返回一個布爾值,若為真,則表示目錄的操作可行,若否,則表示不可行 */
bool isValidOp( struct dir_entry_mem father, char* name )
{
if( father.children.size() >= 10 )
{
printf( "%s", "目錄下的文件和文件夾已滿\n" );
return false;
}
if( ! checkName( father, name ) )
{
printf( "%s", "目錄下存在同名的文件或者文件夾\n" );
return false;
}
return true;
}
/*!
* \brief 格式化磁盤 */
void format()
{
FILE *file = fopen( "disk.img", "r+" );
char i = 0;
rewind( file );
while( ftell( file ) != feof( file ) )
fwrite( &i, sizeof( char ), 1, file );
fclose( file );
initSuperBlock.blocks_count = 1024;
initSuperBlock.inodes_count = 128;
initSuperBlock.free_blocks_count = 1006;
initSuperBlock.free_inodes_count = 128;
initSuperBlock.log_blocks_size = 1024;
initSuperBlock.blocks_per_group = 1024;
initSuperBlock.inodes_per_group = 128;
memset( initSuperBlock.fill, 0, sizeof( initSuperBlock.fill) );
initGroupDesc.free_blocks_count = 1024;
initGroupDesc.free_inodes_count = 128;
initGroupDesc.block_bitmap = 0x02;
initGroupDesc.inode_bitmap = 0x03;
initGroupDesc.inode_table = 0x04;
char blockBitmap[1024];
char inodeBitmap[1024];
memset( blockBitmap, '0', sizeof( blockBitmap ) );
memset( inodeBitmap, '0', sizeof( inodeBitmap ) );
struct inode inodeRoot;
inodeRoot.i_size = 1024;
inodeRoot.i_blocks = 1;
inodeRoot.i_ctime = time( NULL );
inodeRoot.i_atime = inodeRoot.i_ctime;
inodeRoot.i_mtime = inodeRoot.i_ctime;
inodeRoot.i_block[ 0 ] = 18;
for ( int i = 1; i < YAFS_N_BLOCKS; i ++ )
inodeRoot.i_block[ i ] = 0;
struct dir_entry rootDir;
rootDir.inode = 0;
rootDir.file_type = 2;
rootDir.rec_len = 0;
memset( rootDir.name, 0, sizeof( char ) * YAFS_NAME_LEN );
strcpy( rootDir.name, "." );
struct dir_entry rootFather;
rootFather = rootDir;
memset( rootFather.name, 0, sizeof( char ) * YAFS_NAME_LEN );
strcpy( rootFather.name, ".." );
rootDir.rec_len = sizeof( struct dir_entry );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -