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 &amp; <a href='../S/29.html#L17' title='Defined at 17 in include/fcntl.h.'>O_TRUNC</a>) &amp;&amp; !(flag &amp; <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 &amp;= 0777 &amp; ~current-&gt;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, &amp;namelen, &amp;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 &amp; (<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> (&amp;dir, basename, namelen, &amp;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 &amp; <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-&gt;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-&gt;i_uid = current-&gt;euid;
<a name='L579'>      inode-&gt;i_mode = mode;
<a name='L580'>      inode-&gt;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, &amp;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-&gt;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-&gt;inode = inode-&gt;i_num;
<a name='L595'>      bh-&gt;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-&gt;inode;
<a name='L604'>  <a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a> = dir-&gt;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 &amp; <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-&gt;i_mode) &amp;&amp; (flag &amp; <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-&gt;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 &amp; <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, &amp;namelen, &amp;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 + -
显示快捷键?