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;
}
Linux文件寻址算法:逻辑地址到物理地址的转换的更多相关文章
- Linux从逻辑地址到物理地址
转自:http://blog.chinaunix.net/uid-24774106-id-3427836.html 我们都知道,动态共享库里面的函数的共享的,这也是动态库的优势所在,就是节省内存.C ...
- Linux文件系统性能优化 (转)
http://blog.chinaunix.net/uid-7530389-id-2050116.html 由于各种的I/O负载情形各异,Linux系统中文件系统的缺省配置一般来说都比较中庸,强调普遍 ...
- Linux内存寻址之分页机制
在上一篇文章Linux内存寻址之分段机制中,我们了解逻辑地址通过分段机制转换为线性地址的过程.下面,我们就来看看更加重要和复杂的分页机制. 分页机制在段机制之后进行,以完成线性—物理地址的转换过程.段 ...
- Linux内存寻址之分段机制
前言 最近在学习Linux内核,读到<深入理解Linux内核>的内存寻址一章.原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解.于是,查找了很多资料,最终理顺了内存寻址的知识. ...
- Linux内存寻址之分段机制及分页机制【转】
前言 本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制: 最近在学习Linux内核,读到<深入理解Linux内核>的内存寻址一章.原本以为 ...
- Linux文件系统性能优化
本文绝大部分是转载自CSDN刘爱贵专栏: http://blog.csdn.net/liuben/archive/2010/04/13/5482167.aspx另外根据参考文档增补了一部分内容. 由于 ...
- Linux实战教学笔记08:Linux 文件的属性(上半部分)
第八节 Linux 文件的属性(上半部分) 标签(空格分隔):Linux实战教学笔记 第1章 Linux中的文件 1.1 文件属性概述(ls -lhi) linux里一切皆文件 Linux系统中的文件 ...
- Linux 文件压缩与归档
.note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...
- linux 文件系统结构及命令
1.linux 文件系统结构 / 根目录 root |--mnt/ | |--sdcard/ 挂载点 | |--usb0 | |--cdrom |--home | |--soft01 <- 用 ...
随机推荐
- JAVA通过网站域名URL获取该网站的源码(2018
import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnect ...
- A计划(三维dfs)
可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验.魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老.年迈的国王正是心急如焚,告招天下 ...
- wzoi(栈模拟)
链接:https://ac.nowcoder.com/acm/contest/332/I 来源:牛客网 题目描述 bleaves 最近在 wzoi 上面做题. wzoi 的题目有两种,一种是 noip ...
- c# 动态生成继承类并实现序列化特性
项目来源 App传过来的字段是动态的,希望能保证扩展性,返回时,把所需要的字段与数据融合后再返回过去 数据是第3方来源的,但是序列化后的结果又希望能并列返回 如:App传过来 一个设备Id,客户Id等 ...
- 在Eclipse中添加Servlet-api.jar的方法
方法一: 正确的加载servlet-api.jar的方法如下: 1:右击项目工程名称 2:Properties 3: Jvav Build Path 4: Libraries 5: Add Ex ...
- CAPL编程实现诊断刷写,车联网FOTA流程自动化测试(代码篇)
原创内容,转载请注明出处 接上篇,本文主要讲CAPL编程详细实现,软件环境CANoe 11.0 一.Simulation Setup 1.建模之前,首先创建一个.DBC文件.如果不会,可以用一个 ...
- IE9以下程序开发不兼容项目罗列
1. 提前关闭iframe,脚本将不再执行 IE下的js不是缓存在站点系统中,而是缓存在每个单独页面系统中的,当关闭页面,对应引入的脚本将不再执行. 可能出现两种情况: iframe引入的html页面 ...
- ModelSim使用教程
参考[百度文库]
- 向一个GitHub repository添加协作者
第一步: 在协作者的机器(就是你的电脑啦)上创建一个ssh key (使用命令ssh-keygen) 第二步: 创建一个github账户 第三步: 把public-key添加到你的github用户账户 ...
- 几个免费 IP 归属地查询 API
1.淘宝:同个IP不能连续查询,需要时间间隔 http://ip.taobao.com/service/getIpInfo.php?ip=114.114.114.114 返回结果 { "co ...