Linux文件寻址算法:逻辑地址到物理地址的转换

题目描述:

 

编写一个函数实现Linux文件寻址的算法,即读取文件当前位置到物理存储位置的转换函数,需要给出运行的测试数据,可以假设和模拟需要的数据和结构。即编写一个函数unsigned long ltop(unsigned long logblkNum). 计算逻辑块号logblkNum所对应的物理块的块号。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define index (12) //直接索引块数目
#define first_index (1 << 7) // 一级索引块数目
#define second_index (1 << 14)
#define third_index (1 << 21)
#define blksize 512 //物理块大小
#define blknumsize 4 //索引块大小
#define index_blk_sum (15 + first_index + second_index + third_index) //索引块总数

struct inode
{
    unsigned long i_block[15];
}inode;



FILE *fp;
int bitmap[index_blk_sum] = {0};


int find_bitmap(int curpos)
{
	int j, k;
	for(j = k = curpos; bitmap[j] == 1 && bitmap[k] == 1 && k >= 0 && j < index_blk_sum; ++j, --k);
	if(j < index_blk_sum && bitmap[j] == 0) 
		return j;
	else if(k >= 0 && bitmap[k] == 0)
		return k;
}

void print(int buf[])
{
	for(int i = 0; i < first_index; ++i)
		printf("%d ", buf[i]);
	printf("\n");
}

void dirty(int pos)
{
	bitmap[pos] = 1;
}

void init_inode()
{
    	for(int i = 0; i < 15; ++i)
    	{
		int tmp = rand() % index_blk_sum;
		if(bitmap[tmp] == 1)
		{
			int j = find_bitmap(tmp);
			inode.i_block[i] = j;
			dirty(j);
		}
		else
		{
			inode.i_block[i] = tmp;
			dirty(tmp);
		}		
    	}
}

void init_filesys()
{
	long long bufsize = index_blk_sum * blksize;
	char *buf = malloc(sizeof(char) * bufsize);
   	fwrite(buf, sizeof(buf), 1, fp);
    	free(buf);
}

void do_random(int buf[], int n)
{
	for(int i = 0; i < n; ++i)
	{
		int tmp = rand() % index_blk_sum;
		if(bitmap[tmp] == 1)
		{
			int j = find_bitmap(tmp);
			buf[i] = j;
			dirty(j);
		}
		else
		{
			buf[i] = tmp;
			dirty(tmp);	
		}
	}
}

void put_inode()
{
	fseek(fp, 0, SEEK_SET);
	fwrite(&inode, sizeof(inode), 1, fp);
}

void put_direct_index(unsigned long offset)
{
	int buf[first_index] = {0};
    	do_random(buf, first_index);
	fseek(fp, offset, SEEK_SET);
   	fwrite(buf, sizeof(int), first_index, fp);
}

void put_first_index()
{
	unsigned int buf_1[first_index];
	put_direct_index(inode.i_block[13] * blksize);
	fseek(fp, inode.i_block[13] * blksize, SEEK_SET);
	fread(buf_1, sizeof(int), first_index, fp);
	
	for(int i = 0; i < first_index; ++i)
		put_direct_index(buf_1[i] * blksize);
}

void put_second_index() 
{
    	unsigned int buf_1[first_index] = {0};
	unsigned int buf_2[first_index] = {0};

	put_direct_index(inode.i_block[14] * blksize);
	fseek(fp, inode.i_block[14] * blksize, SEEK_SET);
	fread(buf_1, sizeof(int), first_index, fp);
	
	for(int i = 0; i < first_index; ++i)
	{	
		put_direct_index(buf_1[i] * blksize);
		fseek(fp, buf_1[i] * blksize, SEEK_SET);
		fread(buf_2, sizeof(int), first_index, fp);
		for(int j = 0; j < first_index; ++j)
		{
			put_direct_index(buf_2[j] * blksize);
		}
	}
}


unsigned long ltop(unsigned long l_addr)
{
    	unsigned int buf_1[first_index] = {0};
    	unsigned int buf_2[first_index] = {0};
    	unsigned int buf_3[first_index] = {0};

    	if(l_addr < 0 || l_addr > index_blk_sum - 1)
		return index_blk_sum;
    	else
    	{
		if(l_addr < index)
		{
           		return inode.i_block[l_addr];
		}
		else if(l_addr < (index + first_index))
		{
			fseek(fp, inode.i_block[12] * blksize, SEEK_SET);
			fread(buf_1, sizeof(int), first_index, fp);
		    	return buf_1[l_addr - index];
		}
		else if(l_addr < (index + first_index + second_index))
		{
			fseek(fp, inode.i_block[13] * blksize, SEEK_SET);
			fread(buf_1, sizeof(int), first_index, fp);
			fseek(fp, buf_1[(l_addr - (index + first_index)) / first_index] * blksize, SEEK_SET);
			fread(buf_2, sizeof(int), first_index, fp);
		    	return buf_2[(l_addr - (index + first_index)) % first_index];
		}
		else if(l_addr < (index_blk_sum))
		{
		    	fseek(fp, inode.i_block[14] * blksize, SEEK_SET);
			fread(buf_1, sizeof(int), first_index, fp);
			fseek(fp, buf_1[(l_addr - (index + first_index + second_index)) / second_index] * blksize, SEEK_SET);
			fread(buf_2, sizeof(int), first_index, fp);
			fseek(fp, buf_2[(l_addr - (index + first_index + second_index)) % second_index / first_index] * blksize, SEEK_SET);
			fread(buf_3, sizeof(int), first_index, fp);
		    	return buf_3[(l_addr - (index + first_index + second_index)) % second_index % first_index];
		}
   	 }
}

int main()
{
    	srand((unsigned)time(NULL));
    	unsigned long l_addr;

    	fp = fopen("ext2", "w+");
    	if(fp == NULL)
    	{
  		printf("create filesys error!\n");
		exit(0);
    	}
	
	init_inode();
	init_filesys();

	put_inode();
	put_direct_index(inode.i_block[12] * blksize);
	put_first_index();
	put_second_index();

    	while(scanf("%ld", &l_addr) != EOF)
    	{
        	unsigned long p_addr = ltop(l_addr);
        	if(p_addr < index_blk_sum)
       	    		printf("logical blknum %ld to physical blknum %ld\n", l_addr, p_addr);
        	else
            		printf("out of memory\n");
    	}
	fclose(fp);
    	return 0;
}

 

 

 

 

 

转载于:https://www.cnblogs.com/lj95/p/10260722.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值