📄 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 + -