zoukankan      html  css  js  c++  java
  • 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("
    ");
    }
    
    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!
    ");
    		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
    ", l_addr, p_addr);
            	else
                		printf("out of memory
    ");
        	}
    	fclose(fp);
        	return 0;
    }
  • 相关阅读:
    linux kgdb 补丁
    linux kdb 内核调试器
    linux 使用 gdb
    linux 系统挂起
    linux oops 消息
    linux strace 命令
    linux ioctl 方法
    linux seq_file 接口
    [数据结构] 迷宫问题(栈和队列,深搜和广搜)
    简化浏览器地址栏訪问路径
  • 原文地址:https://www.cnblogs.com/deepspace/p/10260722.html
Copyright © 2011-2022 走看看