(1) 分解前:最少访问1次,最多访问32次,平均访问16.5次
分解后:最少访问2次,最后访问6次,平均访问4次
(2) 分解前平均访问(n + 1 )/2,分解后平均访问(m + 3) / 2,所以m 要小于 n-2
1、从分区的根目录/目录表中查到home得到i节点号x;
2、读取i节点区第x项内容 ,从中得到/home内容盘块号a;
3、读取a号磁盘块到内存得到/home目录表,搜索/home目录得到can的i节点号y;
4、读取i节点第y项内容,得到/home/can内容盘块号为b;
5、读取b号磁盘块到内存得到/home/can目录表。搜索/home/can目录得到/hello的i节点号z
6、最后,读取i节点第z项内容获取/home/can/hello 文件基本目录。
1、采用分解式目录管理、,分为符号目录项和基本目录项,减少读盘次数
2、为进程设置一个当前目录、并将改目录的内容读入到内存
(1)读入的第 1 个字节文件起始位置的字节距离 ⌊ p o s B S I Z E ⌋ × B S I Z E \lfloor\frac{pos}{BSIZE} \rfloor \times BSIZE ⌊BSIZEpos⌋×BSIZE
答案:① 要读入的第一个字节距文件起始位置的字节距离为 pos, 要读入的最后一个字节距文件起始位置的字节距离为 pos+len-1
笔记:其实一开始我写的答案也是这个,但是后来是我是这样想的,读入数据的时候不是一个数据块读进来吗,那要读入的第一个字节不应该是pos位置所在的数据块开头吗。
最后一个字节 ⌈ p o s + l e n B S I Z E ⌉ × B S I Z E \lceil \frac{pos + len}{BSIZE} \rceil \times BSIZE ⌈BSIZEpos+len⌉×BSIZE
(2)需读数据块数量: ⌈ p o s % B S I Z E + l e n B S I Z E ⌉ \lceil \frac{pos \% BSIZE + len}{BSIZE} \rceil ⌈BSIZEpos%BSIZE+len⌉
逻辑块号的范围 : ⌊ p o s B S I Z E ⌋ 到 ⌊ p o s + l e n B S I Z E ⌋ \lfloor\frac{pos}{BSIZE} \rfloor到 \lfloor\frac{pos + len}{BSIZE} \rfloor ⌊BSIZEpos⌋到⌊BSIZEpos+len⌋
答案 ② 数据块的数量:
⌊
(
p
o
s
+
l
e
n
−
1
)
/
B
S
I
Z
E
⌋
−
⌊
(
p
o
s
)
/
B
S
I
Z
E
⌋
+
1
⌊(pos+len-1)/BSIZE⌋-⌊(pos)/BSIZE⌋+1
⌊(pos+len−1)/BSIZE⌋−⌊(pos)/BSIZE⌋+1
范围:
⌊
(
p
o
s
)
/
B
S
I
Z
E
−
⌊
(
p
o
s
+
l
e
n
−
1
)
/
B
S
I
Z
E
⌋
⌊(pos)/BSIZE-⌊(pos+len-1)/BSIZE⌋
⌊(pos)/BSIZE−⌊(pos+len−1)/BSIZE⌋
(3)
int read(fd,void *buf,size_t len) {
int block_start, block_end;
off_set pos;
pos = lseek(fd, 0, SEEK_CUR); //get current position
block_start = pos / BSIZE;
block_end = (pos + len)/BSIZE;
char *block_buf = malloc(BSIZE) * (block_end - block_start + 1); //prepare buffer
for (i = block_start; i <= block_end; i++){
ReadBlock(fd,i, block_buf + (i-block_start) * BSIZE]);
}
off_set offset_start = pos % BSIZE;
memcpy(block_buf + offset_start, buf, len); //copy data from block buf to buffer
return len;
}
(1)写入的首字节距离文件起始位置的字节距离 ⌊ p o s B S I Z E ⌋ × B S I Z E \lfloor\frac{pos}{BSIZE} \rfloor \times BSIZE ⌊BSIZEpos⌋×BSIZE
末字节 ⌈ p o s + l e n B S I Z E ⌉ × B S I Z E \lceil \frac{pos + len}{BSIZE} \rceil \times BSIZE ⌈BSIZEpos+len⌉×BSIZE
答案: 要读入的第一个字节距文件起始位置的字节距离为 pos, 要读入的最后一个字节距文件起始位置的字节距离为 pos+len-1
(2)读数据块块数:如果 p o s % B S I Z E > 0 pos \% BSIZE>0 pos%BSIZE>0,读一次数据块;如果 p o s + l e n % B S I Z E > 0 pos + len \% BSIZE >0 pos+len%BSIZE>0,再读一次数据块。
需写入的数据块数量: ⌈ p o s % B S I Z E + l e n B S I Z E ⌉ \lceil \frac{pos \% BSIZE + len}{BSIZE} \rceil ⌈BSIZEpos%BSIZE+len⌉
逻辑块号的范围 :
⌊
p
o
s
B
S
I
Z
E
⌋
到
⌊
p
o
s
+
l
e
n
B
S
I
Z
E
⌋
−
1
\lfloor\frac{pos}{BSIZE} \rfloor到 \lfloor\frac{pos + len}{BSIZE} \rfloor- 1
⌊BSIZEpos⌋到⌊BSIZEpos+len⌋−1 (数据块从0开始算)
答案:② 数据块的数量:
⌊
(
p
o
s
+
l
e
n
−
1
)
/
B
S
I
Z
E
⌋
−
⌊
(
p
o
s
)
/
B
S
I
Z
E
⌋
+
1
⌊(pos+len-1)/BSIZE⌋-⌊(pos)/BSIZE⌋+1
⌊(pos+len−1)/BSIZE⌋−⌊(pos)/BSIZE⌋+1
范围:
⌊
(
p
o
s
)
/
B
S
I
Z
E
⌋
−
⌊
(
p
o
s
+
l
e
n
−
1
)
/
B
S
I
Z
E
⌋
⌊(pos)/BSIZE⌋-⌊(pos+len-1)/BSIZE⌋
⌊(pos)/BSIZE⌋−⌊(pos+len−1)/BSIZE⌋
int write(fd,void *buf,size_t len) {
int block_start, block_end;
off_set pos;
pos = lseek(fd, 0, SEEK_CUR); //get current position
block_start = pos / BSIZE;
block_end = (pos + len)/BSIZE;
block_start_offset = pos % BSIZE; //if 0, no need to read the block
block_end_offset = (pos+len) % BSIZE; //if =0, noeed to read the block
char *block_buf = malloc(BSIZE) * (block_end - block_start + 1); //prepare buffer
//save the first and last block if required
if(block_start_offset!=0)
ReadBlock(fd, block_start, block_buf + (i-block_start) * BSIZE]);
if(block_end_offset!=0)
ReadBlock(fd, block_end, block_buf + (block_end-block_start) * BSIZE]); //copy data from block buf to buffer
off_set offset_start = pos % BSIZE;
memcpy(block_buf + offset_start, buf, len); //write to disk
for (i = block_start; i <= block_end; i++){
write(fd,i, block_buf + (i-block_start) * BSIZE]);
}
return len;
}