⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yafs_op.h

📁 简单模拟了操作系统文件系统的操作
💻 H
📖 第 1 页 / 共 2 页
字号:
/*!
 * \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 + -