Steve,
请见答复。
From: quntmec@hotmail.com
To: qf.hao@hotmail.com
Subject: 关于《UNIX技术内幕》的勘误及遇到的问题_17
Date: Sun, 18 Dec 2011 18:24:23 +0800
郝先生,
我碰到的问题如下:
1、307页,ialloc()函数的第51、52行代码,即:
if (fp->s_ninode > 0)
goto loop;
问题:ialloc()为何会有上面这个判断?ialloc()是“后台自动运行的“还是”手工执行的“?
[郝]:首先我想,先要弄清楚代码何时会执行到底51行,也就是内存里面记录的节点已经用完了(fp->s_ninode =0),这样从第27行开始读取磁盘上的可用节点到内存中,
但问题在于磁盘上的节点也有可能分配光了,所以到第51行依然要判断是否内存中有可用节点。如果有,则跳回到loop继续分配。ialloc是被其他函数所调用的,比如创建文件creat,具体你可以检查代码。我不明白“手工”和“自动”的意思?
2、308页,第3行:”...除i_atime[2]和i_mtime[2]是应为...“。这里的解释似乎有点不太恰当,因为iget()已将节点读入内存,所以ip使用的应是第253页里的inode结构,但该结构里没有i_atime[]和i_mtime[]。
[郝]:非常好,这里确实是缓存节点结构!我会在下一版加以更正。
3、311页,iupdat()函数第15行代码,即:
while(ip2 i_addr[8])
问题:这是应是指数组的最后一个元素,即应是 i_addr[7]。难道我记错了?(同样的问题在307页第3行(即第15行代码处))。
[郝]:这是C语言中的一个基本概念,如果用i_addr[7],那就应该写成 ip2i_addr[7],不是吗?
4、317页,readi()函数的37行,即
iomove(bp,on,n,B_READ);
问题:我不太明白这句代码的必要性,即为何需要将数据复制到 u.u_base缓存中?
[郝]: 事实上这个函数独来看确实有点不太好懂,因为它是系统调用read的内核实现部分(具体参照12.3.1节),iomove的必要性在于把读取出来的数据 拷贝到u.u_base通常是用户空间中,也就是read(fd, buf, len)中的buf指针。因为readi运行在内核空间,它所读出的数据也在内核空间中。没有这一步操作,用户根本无法获得数据。
5、325页,第2段第1行:“...所有的块设备也被作为字符设备列入...“。不太明白这里的意思。因为如果所有的块设备都按字符设备处理,那为何还需要 bdevsw[](里包含了所有的块设备驱动) ?
[郝]:rk11磁盘既可以作为块设备也可以作为字符设备 访问,用块设备访问的好处在于性能比较好。作为字符设备访问的好处在于可以顺序按字节流读写。
6、建议:可否增加minix3文件系统或EXT3文件系统的介绍(类似FAT16的介绍)?
[郝]:好建议。甚至IBM的JFS文件系统。我可以考虑在下一版中加入,如果你有什么好的材料或者代码可以告诉我。谢谢!
此外,勘误如下:
[郝]:是的,谢谢!
最后,对于你所发现的这么多问题,我会尽快在我的博客上发表注解(chinaunix.com),再一次感谢你的辛勤劳动和帮助!
Steve
请见答复。
From: quntmec@hotmail.com
To: qf.hao@hotmail.com
Subject: 关于《UNIX技术内幕》的勘误及遇到的问题_17
Date: Sun, 18 Dec 2011 18:24:23 +0800
郝先生,
我碰到的问题如下:
1、307页,ialloc()函数的第51、52行代码,即:
if (fp->s_ninode > 0)
goto loop;
问题:ialloc()为何会有上面这个判断?ialloc()是“后台自动运行的“还是”手工执行的“?
[郝]:首先我想,先要弄清楚代码何时会执行到底51行,也就是内存里面记录的节点已经用完了(fp->s_ninode =0),这样从第27行开始读取磁盘上的可用节点到内存中,
但问题在于磁盘上的节点也有可能分配光了,所以到第51行依然要判断是否内存中有可用节点。如果有,则跳回到loop继续分配。ialloc是被其他函数所调用的,比如创建文件creat,具体你可以检查代码。我不明白“手工”和“自动”的意思?
2、308页,第3行:”...除i_atime[2]和i_mtime[2]是应为...“。这里的解释似乎有点不太恰当,因为iget()已将节点读入内存,所以ip使用的应是第253页里的inode结构,但该结构里没有i_atime[]和i_mtime[]。
[郝]:非常好,这里确实是缓存节点结构!我会在下一版加以更正。
3、311页,iupdat()函数第15行代码,即:
while(ip2 i_addr[8])
问题:这是应是指数组的最后一个元素,即应是 i_addr[7]。难道我记错了?(同样的问题在307页第3行(即第15行代码处))。
[郝]:这是C语言中的一个基本概念,如果用i_addr[7],那就应该写成 ip2i_addr[7],不是吗?
4、317页,readi()函数的37行,即
iomove(bp,on,n,B_READ);
问题:我不太明白这句代码的必要性,即为何需要将数据复制到 u.u_base缓存中?
[郝]: 事实上这个函数独来看确实有点不太好懂,因为它是系统调用read的内核实现部分(具体参照12.3.1节),iomove的必要性在于把读取出来的数据 拷贝到u.u_base通常是用户空间中,也就是read(fd, buf, len)中的buf指针。因为readi运行在内核空间,它所读出的数据也在内核空间中。没有这一步操作,用户根本无法获得数据。
5、325页,第2段第1行:“...所有的块设备也被作为字符设备列入...“。不太明白这里的意思。因为如果所有的块设备都按字符设备处理,那为何还需要 bdevsw[](里包含了所有的块设备驱动) ?
[郝]:rk11磁盘既可以作为块设备也可以作为字符设备 访问,用块设备访问的好处在于性能比较好。作为字符设备访问的好处在于可以顺序按字节流读写。
6、建议:可否增加minix3文件系统或EXT3文件系统的介绍(类似FAT16的介绍)?
[郝]:好建议。甚至IBM的JFS文件系统。我可以考虑在下一版中加入,如果你有什么好的材料或者代码可以告诉我。谢谢!
此外,勘误如下:
313 | 倒数第3段第1行:“...在6.2节...“,应是8.2.2 |
[郝]:是的,谢谢!
最后,对于你所发现的这么多问题,我会尽快在我的博客上发表注解(chinaunix.com),再一次感谢你的辛勤劳动和帮助!
Steve