by cszhao1980
熟悉unix/linux的同学都听说过硬链接的概念,老实说,在阅读源码之前,对硬链接的理解总
是模模糊糊的。现在,我们已经了解了inode、目录,是时候对硬链接有个清楚的了解了。
我们知道,新建一个文件时,需要申请很多资源,如:
(1)申请磁盘盘块用于写文件的内容;
(2)申请inode资源,存放文件inode;
(3)在父目录文件中添加一目录项,记录该文件名称、inode。
所谓建立“硬链接”就是为已存在的文件添加一个新名字——即在某目录新建一目录项,其
inode指向该文件的inode,而名称为其新名字。当然,该文件inode中的硬链接计数(i_nlink)也应该加1。
link()函数为硬链接的建立函数,它是一个系统调用,两个参数都由u_arg[]数组传递进来:
(1) u_arg[0]——原文件名(path);
(2) u_arg[1]——新文件名(path)
这个函数并不复杂,我只谈几点:
(1) 5921行的判断说明了两点
i. 对特殊块设备(IFBLK)无法建立硬链接;
ii. 只有super用户才能执行该操作;
(2) 5928行以添加新目录项为目的调用namei后:
1) u_pdir设置为父目录的inode;
2) u_offset[1]设置为文件内容的displacement,可以作为目录项起始地址来设置新加目录项;
(3) 5935行硬链接不可以跨越文件系统疆界;
(4) 5940行调用wdir(ip)——在父目录建立目录项;
wdir调用writei()完成真正的写操作,在此之前的操作是为了设置writei()函数所需的u参数。
i. u_dent用作用户地址(存放要写入的目录项,使u_base指向它);
ii. u_segflg设为1,表示是kernel对kernel的数据传递;
iii. u_count = DIRSIZ+2,即目录项长度(要写入的长度)
【注】:其他的u参数已经设置好了。
(5) 5941行增加文件硬链接计数。
unlink()可看作是link()的“反”函数,它删除inode的一个文件名字(若为该inode唯一的文件名,
则整个inode指向的文件也会被删除)。
3515: pp = namei(&uchar, 2); //获取父目录的inode;
3519: ip = iget(pp->i_dev, u.u_dent.u_ino); //获取文件inode
3524: u.u_offset[1] =- DIRSIZ+2; //u_offset执行文件名目录项起始地址;
3525: u.u_base = &u.u_dent; //用户地址设置为u_dent;
3526: u.u_count = DIRSIZ+2; //长度为目录项长度;
3527: u.u_dent.u_ino = 0; //inode指针置0,即此目录项设置为空;
3528: writei(pp); //更新父目录(该文件名的目录项置为空);
3529: ip->i_nlink--; //文件硬链接计数减一;
3534: iput(ip); //释放文件inode(如硬链接计数为0,会造成文件的删除)
博客地址:http://blog.csdn.net/cszhao1980
博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html