MIT_6.828_2018_Homework:bigger files for xv6

地址:bigger files for xv6
题目要求:原来的一个文件的最大大小为12+128=140个blocks,现在将前12个直接块取一个出来存放另一个“doubly-indirect”块,这样就新增了128*128-1个块了。有点类似与计算机组成原理里面的存储器间接寻址。

准备工作

首先修改Makefile:

CPUS := 1

加入

QEMUEXTRA = -snapshot

修改param.h:

    #define FSSIZE       20000  // size of file system in blocks
    

开始

修改fs.h

修改NDIRECT:

#define NDIRECT 11
#define MAXFILE (NDIRECT + NINDIRECT + NINDIRECT*NINDIRECT)

同时修改dinode中addrs定义:

// On-disk inode structure
struct dinode {
  short type;           // File type
  short major;          // Major device number (T_DEV only)
  short minor;          // Minor device number (T_DEV only)
  short nlink;          // Number of links to inode in file system
  uint size;            // Size of file (bytes)
  uint addrs[NDIRECT+2];   // Data block addresses
};

最后修改fs.c中的bmap()函数:

static uint
bmap(struct inode *ip, uint bn)
{
  uint addr, *a;
  struct buf *bp;
  struct buf *dp;

  if(bn < NDIRECT){
    if((addr = ip->addrs[bn]) == 0)
      ip->addrs[bn] = addr = balloc(ip->dev);
    return addr;
  }
  bn -= (NDIRECT);

  if(bn < NINDIRECT){
    // Load indirect block, allocating if necessary.
    if((addr = ip->addrs[NDIRECT]) == 0)
      ip->addrs[NDIRECT] = addr = balloc(ip->dev);
    bp = bread(ip->dev, addr);
    a = (uint*)bp->data;
    if((addr = a[bn]) == 0){
      a[bn] = addr = balloc(ip->dev);
      log_write(bp);
    }
    brelse(bp);
    return addr;
  }
	
  bn -= NINDIRECT; 

  uint DBNINDIRECT = NINDIRECT*NINDIRECT;

  if (bn < DBNINDIRECT)
  {
  	//在第一级中的位置
  	uint which_block = bn/NINDIRECT;
	//在第二级中的位置
	uint final_location = bn - which_block*NINDIRECT;
	
	if ((addr = ip->addrs[NDIRECT+1]) == 0)
		ip->addrs[NDIRECT+1] = addr = balloc(ip->dev);
	bp = bread(ip->dev,addr);
	a = (uint*)bp->data;
	
	if ((addr= a[which_block]) == 0)
	{
		a[which_block] = addr = balloc(ip->dev);
		log_write(bp);
	}

	dp = bread(ip->dev,addr);
	a = (uint*)dp->data;

	if ((addr = a[final_location]) == 0)
	{
		a[final_location] = addr = balloc(ip->dev);
		log_write(dp);
	}

	brelse(bp);
	brelse(dp);
	return addr;
	
  }
  panic("bmap: out of range");
}

运行结果

运行make;make qemu,在shell里面输入big,得到如下结果:

qemu -serial mon:stdio -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp 1 -m 512 -snapshot
xv6...
cpu0: starting 0
sb: size 20000 nblocks 19937 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
init: starting sh
$ big
.....................................................................................................................................................................
wrote 16523 sectors

总结:注意体会xv6中的分层思想,各个层的作用。

END.

当在编译 `SingleCrack_UEL_PS.obj` 时出现 `'Variable kuser too large for NTCOFF. Bigger than 2GB. Use heap instead'` 错误,意味着变量 `kuser` 的大小超过了 NTCOFF(New Technology COFF,一种可执行文件和目标文件格式)所能处理的 2GB 限制,解决方法如下: #### 1. 使用堆内存 将 `kuser` 变量从栈内存移到堆内存。在 C/C++ 中,可以使用 `malloc` 或 `new` 来动态分配堆内存。 ```c #include <stdio.h> #include <stdlib.h> // 假设 kuser 是一个数组 // 原栈内存定义方式 // int kuser[1000000000]; // 可能会超 2GB // 使用堆内存分配 int main() { int* kuser = (int*)malloc(1000000000 * sizeof(int)); if (kuser == NULL) { printf("Memory allocation failed\n"); return 1; } // 使用 kuser 数组 // 释放堆内存 free(kuser); return 0; } ``` 在 C++ 中,使用 `new` 和 `delete` 进行堆内存管理: ```cpp #include <iostream> int main() { int* kuser = new int[1000000000]; if (kuser == nullptr) { std::cout << "Memory allocation failed" << std::endl; return 1; } // 使用 kuser 数组 // 释放堆内存 delete[] kuser; return 0; } ``` #### 2. 分割大变量 如果 `kuser` 是一个大数组,可以将其分割成多个较小的数组。 ```c #include <stdio.h> #define PART_SIZE 1000000 #define NUM_PARTS 1000 int main() { int kuser_parts[NUM_PARTS][PART_SIZE]; // 使用 kuser_parts 数组 return 0; } ``` #### 3. 检查编译选项 确保使用支持处理大文件和大变量的编译选项。例如,在使用 GCC 编译时,可以使用 `-mcmodel=medium` 或 `-mcmodel=large` 选项。 ```sh gcc -mcmodel=medium your_file.c -o your_program ``` #### 4. 检查数据类型 检查 `kuser` 变量的数据类型是否过大。如果可以,尝试使用更小的数据类型来存储数据。例如,如果存储的数据范围较小,可以使用 `short` 代替 `int`。 ```c #include <stdio.h> // 使用 short 类型 short kuser[1000000000]; int main() { // 使用 kuser 数组 return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值