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

📄 igetput.c

📁 设计并实现一个多用户多级目录结构的文件系统
💻 C
字号:
/************************************************/
/*												*/
/*					igetput.c					*/					// 该文件已经完成
/*												*/
/************************************************/

#include <stdio.h>
#include "filsys.h"

/* 内存i节点分配函数 */
struct inode * iget( unsigned int dinodeid )
{
//	int existed = 0, inodeid;
//	long addr;
//	struct inode * temp, * newinode;

//	for( temp = &inode[0]; temp < &inode[NICINOD]; temp++ )
//	{
//		if( temp->i_ino == dinodeid )			/* 该文件已被打开 */
//		{
//			temp->i_count++;
//			return temp;
//		}
//	}

	int inodeid;
	long addr;
	struct inode * temp, * newinode;

	inodeid = dinodeid % NHINO;					/* 用Hash查找法查找内存i节点时用 */

	/* 用Hash法查找内存i节点 */
	for( temp = hinode[inodeid].i_forw; temp != NULL; temp = temp->i_forw )								
	{
		if( temp->i_ino == dinodeid )			/* 该文件已被打开 */
		{
			temp->i_count++;					/* 引用计数加1 */
			return temp;						/* 可以退出 */
		}
	}

	/* 文件还没有被打开,以下步骤为之分配内存i节点 */

	/* 1. 计算该文件的磁盘i节点所在实际地址 */
	addr = DINODESTART + dinodeid * DINODESIZ;

	/* 2. 为之分配一新内存i节点 */
	newinode = ( struct inode * )malloc( sizeof( struct inode ));

	/* 3. 把磁盘i节点内容复制到内存i节点上 */
	fseek( fd, addr, SEEK_SET );
	fread( &( newinode->i_number ), DINODESIZ, 1, fd );

	/* 4. 把内存i节点插入到Hash列表hinode上,以便查找 */
	if( hinode[inodeid].i_forw != NULL )
	{
		newinode->i_forw = hinode[inodeid].i_forw;
		newinode->i_back = NULL;
		hinode[inodeid].i_forw->i_back = newinode;
		hinode[inodeid].i_forw = newinode;
	}
	else
	{
		newinode->i_back = NULL;
		hinode[inodeid].i_forw = newinode;
		newinode->i_forw = NULL;
	}

	/* 5. 设置内存i节点各数据 */
	newinode->i_count = 1;
//	newinode->i_flag = 0;					/* flag for not update */
	newinode->i_ino = dinodeid;

	return newinode;						/* 返回为之分配的内存i节点 */
}

/* 内存i节点回收函数 */
iput( struct inode * pinode )
{
	long addr;
	unsigned int block_num;
	int i;

	pinode->i_count--;						/* 引用计数减1 */
	if( pinode->i_count > 0 )				/* 还有进程打开该文件 */
	{
		return;								/* 不用回收内存i节点 */
	}
	else
	{
		if( pinode->i_number != 0 )			/* 磁盘i节点连接计数不为0 */
		{
			/* 修改磁盘i节点,即把内存i节点的数据写回到磁盘i节点 */
			addr = DINODESTART + pinode->i_ino * DINODESIZ;
			fseek( fd, addr, SEEK_SET );
			fwrite( &pinode->i_number, 1, sizeof( struct dinode ), fd );
		}
		else
		{
			/* 磁盘i节点连接计数为0,删除文件并回收盘块和磁盘i节点 */
			block_num = pinode->i_size / BLOCKSIZ;		/* 这里有缺陷,即文件必须是一次寻址 */
			if( pinode->i_size % BLOCKSIZ == 0 )
			{
				for( i = 0; i < block_num; i++ )
					bfree( pinode->i_addr[i] );			/* 回收盘块 */
			}
			else
			{
				for( i = 0; i <= block_num; i++ )
					bfree( pinode->i_addr[i] );			/* 回收盘块 */
			}
			ifree( pinode->i_ino );						/* 回收磁盘i节点 */
		}

		/* 回收内存i节点 */
		if( pinode->i_back == NULL )
		{
			if( pinode->i_forw != NULL )
			{
				hinode[pinode->i_ino % NHINO].i_forw = pinode->i_forw;
				pinode->i_forw->i_back = NULL;
			}
			else 
				hinode[pinode->i_ino % NHINO].i_forw = NULL;
		}
		else
		{
			if( pinode->i_forw != NULL )
			{
				pinode->i_forw->i_back = pinode->i_back;
				pinode->i_back->i_forw = pinode->i_forw;
			}
			else
				pinode->i_back->i_forw = NULL;
		}
		free( pinode );
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -