14.html
来自「linux 0.11中文版 有注释」· HTML 代码 · 共 693 行 · 第 1/5 页
HTML
693 行
<a name='L527'> <b>struct</b> m_inode *dir, *inode;
<a name='L528'> <b>struct</b> buffer_head *bh;
<a name='L529'> <b>struct</b> dir_entry *de;
<a name='L530'>
<a name='L531'><i><font color='green'>// 如果文件访问许可模式标志是只读(0),但文件截0 标志O_TRUNC 却置位了,则改为只写标志。</font></i>
<a name='L532'> <b>if</b> ((flag & <a href='../S/29.html#L17' title='Defined at 17 in include/fcntl.h.'>O_TRUNC</a>) && !(flag & <a href='../S/29.html#L8' title='Defined at 8 in include/fcntl.h.'>O_ACCMODE</a>))
<a name='L533'> flag |= <a href='../S/29.html#L11' title='Defined at 11 in include/fcntl.h.'>O_WRONLY</a>;
<a name='L534'><i><font color='green'>// 使用进程的文件访问许可屏蔽码,屏蔽掉给定模式中的相应位,并添上普通文件标志。</font></i>
<a name='L535'> mode &= 0777 & ~current->umask;
<a name='L536'> mode |= <a href='../S/26.html#L9' title='Defined at 9 in include/const.h.'>I_REGULAR</a>;
<a name='L537'><i><font color='green'>// 根据路径名寻找到对应的i 节点,以及最顶端文件名及其长度。</font></i>
<a name='L538'> <b>if</b> (!(dir = <a href='../S/14.html#L434' title='Defined at 434 in fs/namei.c.'>dir_namei</a> (pathname, &namelen, &basename)))
<a name='L539'> <b>return</b> -<a href='../S/28.html#L31' title='Defined at 31 in include/errno.h.'>ENOENT</a>;
<a name='L540'><i><font color='green'>// 如果最顶端文件名长度为0(例如'/usr/'这种路径名的情况),那么若打开操作不是创建、截0,</font></i>
<a name='L541'><i><font color='green'>// 则表示打开一个目录名,直接返回该目录的i 节点,并退出。</font></i>
<a name='L542'> <b>if</b> (!namelen)
<a name='L543'> <font color='red'>{</font> <i><font color='green'>/* special case: '/usr/' etc */</font></i>
<a name='L544'> <b>if</b> (!(flag & (<a href='../S/29.html#L8' title='Defined at 8 in include/fcntl.h.'>O_ACCMODE</a> | <a href='../S/29.html#L14' title='Defined at 14 in include/fcntl.h.'>O_CREAT</a> | <a href='../S/29.html#L17' title='Defined at 17 in include/fcntl.h.'>O_TRUNC</a>)))
<a name='L545'> <font color='red'>{</font>
<a name='L546'> *res_inode = dir;
<a name='L547'> <b>return</b> 0;
<a name='L548'> <font color='red'>}</font>
<a name='L549'><i><font color='green'>// 否则释放该i 节点,返回出错码。</font></i>
<a name='L550'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L551'> <b>return</b> -<a href='../S/28.html#L50' title='Defined at 50 in include/errno.h.'>EISDIR</a>;
<a name='L552'> <font color='red'>}</font>
<a name='L553'><i><font color='green'>// 在dir 节点对应的目录中取文件名对应的目录项结构de 和该目录项所在的高速缓冲区。</font></i>
<a name='L554'> bh = <a href='../S/14.html#L141' title='Defined at 141 in fs/namei.c.'>find_entry</a> (&dir, basename, namelen, &de);
<a name='L555'><i><font color='green'>// 如果该高速缓冲指针为NULL,则表示没有找到对应文件名的目录项,因此只可能是创建文件操作。</font></i>
<a name='L556'> <b>if</b> (!bh)
<a name='L557'> <font color='red'>{</font>
<a name='L558'><i><font color='green'>// 如果不是创建文件,则释放该目录的i 节点,返回出错号退出。</font></i>
<a name='L559'> <b>if</b> (!(flag & <a href='../S/29.html#L14' title='Defined at 14 in include/fcntl.h.'>O_CREAT</a>))
<a name='L560'> <font color='red'>{</font>
<a name='L561'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L562'> <b>return</b> -<a href='../S/28.html#L31' title='Defined at 31 in include/errno.h.'>ENOENT</a>;
<a name='L563'> <font color='red'>}</font>
<a name='L564'><i><font color='green'>// 如果用户在该目录没有写的权力,则释放该目录的i 节点,返回出错号退出。</font></i>
<a name='L565'> <b>if</b> (!<a href='../S/14.html#L58' title='Defined at 58 in fs/namei.c.'>permission</a> (dir, <a href='../S/14.html#L39' title='Defined at 39 in fs/namei.c.'>MAY_WRITE</a>))
<a name='L566'> <font color='red'>{</font>
<a name='L567'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L568'> <b>return</b> -<a href='../S/28.html#L42' title='Defined at 42 in include/errno.h.'>EACCES</a>;
<a name='L569'> <font color='red'>}</font>
<a name='L570'><i><font color='green'>// 在目录节点对应的设备上申请一个新i 节点,若失败,则释放目录的i 节点,并返回没有空间出错码。</font></i>
<a name='L571'> inode = <a href='../S/4.html#L185' title='Defined at 185 in fs/bitmap.c.'>new_inode</a> (dir->i_dev);
<a name='L572'> <b>if</b> (!inode)
<a name='L573'> <font color='red'>{</font>
<a name='L574'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L575'> <b>return</b> -<a href='../S/28.html#L57' title='Defined at 57 in include/errno.h.'>ENOSPC</a>;
<a name='L576'> <font color='red'>}</font>
<a name='L577'><i><font color='green'>// 否则使用该新i 节点,对其进行初始设置:置节点的用户id;对应节点访问模式;置已修改标志。</font></i>
<a name='L578'> inode->i_uid = current->euid;
<a name='L579'> inode->i_mode = mode;
<a name='L580'> inode->i_dirt = 1;
<a name='L581'><i><font color='green'>// 然后在指定目录dir 中添加一新目录项。</font></i>
<a name='L582'> bh = <a href='../S/14.html#L258' title='Defined at 258 in fs/namei.c.'>add_entry</a> (dir, basename, namelen, &de);
<a name='L583'><i><font color='green'>// 如果返回的应该含有新目录项的高速缓冲区指针为NULL,则表示添加目录项操作失败。于是将该</font></i>
<a name='L584'><i><font color='green'>// 新i 节点的引用连接计数减1;并释放该i 节点与目录的i 节点,返回出错码,退出。</font></i>
<a name='L585'> <b>if</b> (!bh)
<a name='L586'> <font color='red'>{</font>
<a name='L587'> inode->i_nlinks--;
<a name='L588'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (inode);
<a name='L589'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L590'> <b>return</b> -<a href='../S/28.html#L57' title='Defined at 57 in include/errno.h.'>ENOSPC</a>;
<a name='L591'> <font color='red'>}</font>
<a name='L592'><i><font color='green'>// 初始设置该新目录项:置i 节点号为新申请到的i 节点的号码;并置高速缓冲区已修改标志。然后</font></i>
<a name='L593'><i><font color='green'>// 释放该高速缓冲区,释放目录的i 节点。返回新目录项的i 节点指针,退出。</font></i>
<a name='L594'> de->inode = inode->i_num;
<a name='L595'> bh->b_dirt = 1;
<a name='L596'> <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);
<a name='L597'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L598'> *res_inode = inode;
<a name='L599'> <b>return</b> 0;
<a name='L600'> <font color='red'>}</font>
<a name='L601'><i><font color='green'>// 若上面在目录中取文件名对应的目录项结构操作成功(也即bh 不为NULL),取出该目录项的i 节点号</font></i>
<a name='L602'><i><font color='green'>// 和其所在的设备号,并释放该高速缓冲区以及目录的i 节点。</font></i>
<a name='L603'> inr = de->inode;
<a name='L604'> <a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a> = dir->i_dev;
<a name='L605'> <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);
<a name='L606'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L607'><i><font color='green'>// 如果独占使用标志O_EXCL 置位,则返回文件已存在出错码,退出。</font></i>
<a name='L608'> <b>if</b> (flag & <a href='../S/29.html#L15' title='Defined at 15 in include/fcntl.h.'>O_EXCL</a>)
<a name='L609'> <b>return</b> -<a href='../S/28.html#L46' title='Defined at 46 in include/errno.h.'>EEXIST</a>;
<a name='L610'><i><font color='green'>// 如果取该目录项对应i 节点的操作失败,则返回访问出错码,退出。</font></i>
<a name='L611'> <b>if</b> (!(inode = <a href='../S/12.html#L355' title='Defined at 355 in fs/inode.c.'>iget</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>, inr)))
<a name='L612'> <b>return</b> -<a href='../S/28.html#L42' title='Defined at 42 in include/errno.h.'>EACCES</a>;
<a name='L613'><i><font color='green'>// 若该i 节点是一个目录的节点并且访问模式是只读或只写,或者没有访问的许可权限,则释放该i</font></i>
<a name='L614'><i><font color='green'>// 节点,返回访问权限出错码,退出。</font></i>
<a name='L615'> <b>if</b> ((<a href='../S/43.html#L35' title='Defined at 35 in include/sys/stat.h.'>S_ISDIR</a> (inode->i_mode) && (flag & <a href='../S/29.html#L8' title='Defined at 8 in include/fcntl.h.'>O_ACCMODE</a>)) ||
<a name='L616'> !<a href='../S/14.html#L58' title='Defined at 58 in fs/namei.c.'>permission</a> (inode, <a href='../S/14.html#L27' title='Defined at 27 in fs/namei.c.'>ACC_MODE</a> (flag)))
<a name='L617'> <font color='red'>{</font>
<a name='L618'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (inode);
<a name='L619'> <b>return</b> -<a href='../D/112.html' title='Multiple defined in 2 places.'>EPERM</a>;
<a name='L620'> <font color='red'>}</font>
<a name='L621'><i><font color='green'>// 更新该i 节点的访问时间字段为当前时间。</font></i>
<a name='L622'> inode->i_atime = <a href='../S/36.html#L234' title='Defined at 234 in include/linux/sched.h.'>CURRENT_TIME</a>;
<a name='L623'><i><font color='green'>// 如果设立了截0 标志,则将该i 节点的文件长度截为0。</font></i>
<a name='L624'> <b>if</b> (flag & <a href='../S/29.html#L17' title='Defined at 17 in include/fcntl.h.'>O_TRUNC</a>)
<a name='L625'> <a href='../S/20.html#L81' title='Defined at 81 in fs/truncate.c.'>truncate</a> (inode);
<a name='L626'><i><font color='green'>// 最后返回该目录项i 节点的指针,并返回0(成功)。</font></i>
<a name='L627'> *res_inode = inode;
<a name='L628'> <b>return</b> 0;
<a name='L629'><font color='red'>}</font>
<a name='L630'>
<a name='L631'><i><font color='green'>//// 系统调用函数 - 创建一个特殊文件或普通文件节点(node)。</font></i>
<a name='L632'><i><font color='green'>// 创建名称为filename,由mode 和dev 指定的文件系统节点(普通文件、设备特殊文件或命名管道)。</font></i>
<a name='L633'><i><font color='green'>// 参数:filename - 路径名;mode - 指定使用许可以及所创建节点的类型;dev - 设备号。</font></i>
<a name='L634'><i><font color='green'>// 返回:成功则返回0,否则返回出错码。</font></i>
<a name='L635'><b>int</b>
<a name='L636'><a href='../R/659.html' title='Multiple refered from 2 places.'>sys_mknod</a> (<b>const</b> <b>char</b> *filename, <b>int</b> mode, <b>int</b> dev)
<a name='L637'><font color='red'>{</font>
<a name='L638'> <b>const</b> <b>char</b> *basename;
<a name='L639'> <b>int</b> namelen;
<a name='L640'> <b>struct</b> m_inode *dir, *inode;
<a name='L641'> <b>struct</b> buffer_head *bh;
<a name='L642'> <b>struct</b> dir_entry *de;
<a name='L643'>
<a name='L644'><i><font color='green'>// 如果不是超级用户,则返回访问许可出错码。</font></i>
<a name='L645'> <b>if</b> (!<a href='../S/34.html#L37' title='Defined at 37 in include/linux/kernel.h.'>suser</a> ())
<a name='L646'> <b>return</b> -<a href='../D/112.html' title='Multiple defined in 2 places.'>EPERM</a>;
<a name='L647'><i><font color='green'>// 如果找不到对应路径名目录的i 节点,则返回出错码。</font></i>
<a name='L648'> <b>if</b> (!(dir = <a href='../S/14.html#L434' title='Defined at 434 in fs/namei.c.'>dir_namei</a> (filename, &namelen, &basename)))
<a name='L649'> <b>return</b> -<a href='../S/28.html#L31' title='Defined at 31 in include/errno.h.'>ENOENT</a>;
<a name='L650'><i><font color='green'>// 如果最顶端的文件名长度为0,则说明给出的路径名最后没有指定文件名,释放该目录i 节点,返回</font></i>
<a name='L651'><i><font color='green'>// 出错码,退出。</font></i>
<a name='L652'> <b>if</b> (!namelen)
<a name='L653'> <font color='red'>{</font>
<a name='L654'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L655'> <b>return</b> -<a href='../S/28.html#L31' title='Defined at 31 in include/errno.h.'>ENOENT</a>;
<a name='L656'> <font color='red'>}</font>
<a name='L657'><i><font color='green'>// 如果在该目录中没有写的权限,则释放该目录的i 节点,返回访问许可出错码,退出。</font></i>
<a name='L658'> <b>if</b> (!<a href='../S/14.html#L58' title='Defined at 58 in fs/namei.c.'>permission</a> (dir, <a href='../S/14.html#L39' title='Defined at 39 in fs/namei.c.'>MAY_WRITE</a>))
<a name='L659'> <font color='red'>{</font>
<a name='L660'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (dir);
<a name='L661'> <b>return</b> -<a href='../D/112.html' title='Multiple defined in 2 places.'>EPERM</a>;
<a name='L662'> <font color='red'>}</font>
<a name='L663'><i><font color='green'>// 如果对应路径名上
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?