14.html
来自「linux 0.11中文版 有注释」· HTML 代码 · 共 693 行 · 第 1/5 页
HTML
693 行
<a name='L249'><i><font color='green'>*</font></i>
<a name='L250'><i><font color='green'>* 注意!!'de'(指定目录项结构指针)的i 节点部分被设置为0 - 这表示</font></i>
<a name='L251'><i><font color='green'>* 在调用该函数和往目录项中添加信息之间不能睡眠,因为若睡眠那么其它</font></i>
<a name='L252'><i><font color='green'>* 人(进程)可能会已经使用了该目录项。</font></i>
<a name='L253'><i><font color='green'>*/</font></i>
<a name='L254'><i><font color='green'>//// 根据指定的目录和文件名添加目录项。</font></i>
<a name='L255'><i><font color='green'>// 参数:dir - 指定目录的i 节点;name - 文件名;namelen - 文件名长度;</font></i>
<a name='L256'><i><font color='green'>// 返回:高速缓冲区指针;res_dir - 返回的目录项结构指针;</font></i>
<a name='L257'><b>static</b> <b>struct</b> buffer_head *
<a name='L258'><a href='../R/381.html' title='Multiple refered from 4 places.'>add_entry</a> (<b>struct</b> m_inode *dir,
<a name='L259'> <b>const</b> <b>char</b> *name, <b>int</b> namelen, <b>struct</b> dir_entry **res_dir)
<a name='L260'><font color='red'>{</font>
<a name='L261'> <b>int</b> block, <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L262'> <b>struct</b> buffer_head *bh;
<a name='L263'> <b>struct</b> dir_entry *de;
<a name='L264'>
<a name='L265'> *res_dir = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L266'><i><font color='green'>// 如果定义了NO_TRUNCATE,则若文件名长度超过最大长度NAME_LEN,则返回。</font></i>
<a name='L267'><font color='darkred'>#ifdef</font> NO_TRUNCATE
<a name='L268'> <b>if</b> (namelen > <a href='../S/31.html#L52' title='Defined at 52 in include/linux/fs.h.'>NAME_LEN</a>)
<a name='L269'> <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L270'><i><font color='green'>//如果没有定义NO_TRUNCATE,则若文件名长度超过最大长度NAME_LEN,则截短之。</font></i>
<a name='L271'><font color='darkred'>#else</font>
<a name='L272'> <b>if</b> (namelen > <a href='../S/31.html#L52' title='Defined at 52 in include/linux/fs.h.'>NAME_LEN</a>)
<a name='L273'> namelen = <a href='../S/31.html#L52' title='Defined at 52 in include/linux/fs.h.'>NAME_LEN</a>;
<a name='L274'><font color='darkred'>#endif</font>
<a name='L275'><i><font color='green'>// 如果文件名长度等于0,则返回NULL,退出。</font></i>
<a name='L276'> <b>if</b> (!namelen)
<a name='L277'> <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L278'><i><font color='green'>// 如果该目录i 节点所指向的第一个直接磁盘块号为0,则返回NULL 退出。</font></i>
<a name='L279'> <b>if</b> (!(block = dir->i_zone[0]))
<a name='L280'> <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L281'><i><font color='green'>// 如果读取该磁盘块失败,则返回NULL 并退出。</font></i>
<a name='L282'> <b>if</b> (!(bh = <a href='../S/6.html#L397' title='Defined at 397 in fs/buffer.c.'>bread</a> (dir->i_dev, block)))
<a name='L283'> <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L284'><i><font color='green'>// 在目录项数据块中循环查找最后未使用的目录项。首先让目录项结构指针de 指向高速缓冲的数据块</font></i>
<a name='L285'><i><font color='green'>// 开始处,也即第一个目录项。</font></i>
<a name='L286'> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0;
<a name='L287'> de = (<b>struct</b> dir_entry *) bh->b_data;
<a name='L288'> <b>while</b> (1)
<a name='L289'> <font color='red'>{</font>
<a name='L290'><i><font color='green'>// 如果当前判别的目录项已经超出当前数据块,则释放该数据块,重新申请一块磁盘块block。如果</font></i>
<a name='L291'><i><font color='green'>// 申请失败,则返回NULL,退出。</font></i>
<a name='L292'> <b>if</b> ((<b>char</b> *) de >= <a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a> + bh->b_data)
<a name='L293'> <font color='red'>{</font>
<a name='L294'> <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);
<a name='L295'> bh = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L296'> block = <a href='../S/12.html#L214' title='Defined at 214 in fs/inode.c.'>create_block</a> (dir, <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> / <a href='../S/31.html#L74' title='Defined at 74 in include/linux/fs.h.'>DIR_ENTRIES_PER_BLOCK</a>);
<a name='L297'> <b>if</b> (!block)
<a name='L298'> <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L299'><i><font color='green'>// 如果读取磁盘块返回的指针为空,则跳过该块继续。</font></i>
<a name='L300'> <b>if</b> (!(bh = <a href='../S/6.html#L397' title='Defined at 397 in fs/buffer.c.'>bread</a> (dir->i_dev, block)))
<a name='L301'> <font color='red'>{</font>
<a name='L302'> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> += <a href='../S/31.html#L74' title='Defined at 74 in include/linux/fs.h.'>DIR_ENTRIES_PER_BLOCK</a>;
<a name='L303'> <b>continue</b>;
<a name='L304'> <font color='red'>}</font>
<a name='L305'><i><font color='green'>// 否则,让目录项结构指针de 志向该块的高速缓冲数据块开始处。</font></i>
<a name='L306'> de = (<b>struct</b> dir_entry *) bh->b_data;
<a name='L307'> <font color='red'>}</font>
<a name='L308'><i><font color='green'>// 如果当前所操作的目录项序号i*目录结构大小已经超过了该目录所指出的大小i_size,则说明该第i</font></i>
<a name='L309'><i><font color='green'>// 个目录项还未使用,我们可以使用它。于是对该目录项进行设置(置该目录项的i 节点指针为空)。并</font></i>
<a name='L310'><i><font color='green'>// 更新该目录的长度值(加上一个目录项的长度,设置目录的i 节点已修改标志,再更新该目录的改变时</font></i>
<a name='L311'><i><font color='green'>// 间为当前时间。</font></i>
<a name='L312'> <b>if</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> * <b>sizeof</b> (<b>struct</b> dir_entry) >= dir->i_size)
<a name='L313'> <font color='red'>{</font>
<a name='L314'> de->inode = 0;
<a name='L315'> dir->i_size = (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> + 1) * <b>sizeof</b> (<b>struct</b> dir_entry);
<a name='L316'> dir->i_dirt = 1;
<a name='L317'> dir->i_ctime = <a href='../S/36.html#L234' title='Defined at 234 in include/linux/sched.h.'>CURRENT_TIME</a>;
<a name='L318'> <font color='red'>}</font>
<a name='L319'><i><font color='green'>// 若该目录项的i 节点为空,则表示找到一个还未使用的目录项。于是更新目录的修改时间为当前时间。</font></i>
<a name='L320'><i><font color='green'>// 并从用户数据区复制文件名到该目录项的文件名字段,置相应的高速缓冲块已修改标志。返回该目录</font></i>
<a name='L321'><i><font color='green'>// 项的指针以及该高速缓冲区的指针,退出。</font></i>
<a name='L322'> <b>if</b> (!de->inode)
<a name='L323'> <font color='red'>{</font>
<a name='L324'> dir->i_mtime = <a href='../S/36.html#L234' title='Defined at 234 in include/linux/sched.h.'>CURRENT_TIME</a>;
<a name='L325'> <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> < <a href='../S/31.html#L52' title='Defined at 52 in include/linux/fs.h.'>NAME_LEN</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L326'> de->name[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] = (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> < namelen) ? <a href='../D/821.html' title='Multiple defined in 2 places.'>get_fs_byte</a> (name + <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>) : 0;
<a name='L327'> bh->b_dirt = 1;
<a name='L328'> *res_dir = de;
<a name='L329'> <b>return</b> bh;
<a name='L330'> <font color='red'>}</font>
<a name='L331'><i><font color='green'>// 如果该目录项已经被使用,则继续检测下一个目录项。</font></i>
<a name='L332'> de++;
<a name='L333'> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++;
<a name='L334'> <font color='red'>}</font>
<a name='L335'><i><font color='green'>// 执行不到这里。也许Linus 在写这段代码时是先复制了上面find_entry()的代码,而后修改的?。</font></i>
<a name='L336'> <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);
<a name='L337'> <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L338'><font color='red'>}</font>
<a name='L339'>
<a name='L340'><i><font color='green'>/*</font></i>
<a name='L341'><i><font color='green'>* get_dir()</font></i>
<a name='L342'><i><font color='green'>*</font></i>
<a name='L343'><i><font color='green'>* Getdir traverses the pathname until it hits the topmost directory.</font></i>
<a name='L344'><i><font color='green'>* It returns NULL on failure.</font></i>
<a name='L345'><i><font color='green'>*/</font></i>
<a name='L346'><i><font color='green'>/*</font></i>
<a name='L347'><i><font color='green'>* get_dir()</font></i>
<a name='L348'><i><font color='green'>* 该函数根据给出的路径名进行搜索,直到达到最顶端的目录。</font></i>
<a name='L349'><i><font color='green'>* 如果失败则返回NULL。</font></i>
<a name='L350'><i><font color='green'>*/</font></i>
<a name='L351'><i><font color='green'>//// 搜寻指定路径名的目录。</font></i>
<a name='L352'><i><font color='green'>// 参数:pathname - 路径名。</font></i>
<a name='L353'><i><font color='green'>// 返回:目录的i 节点指针。失败时返回NULL。</font></i>
<a name='L354'><b>static</b> <b>struct</b> m_inode *
<a name='L355'><a href='../S/14.html#L441' title='Refered from 441 in fs/namei.c.'>get_dir</a> (<b>const</b> <b>char</b> *pathname)
<a name='L356'><font color='red'>{</font>
<a name='L357'> <b>char</b> c;
<a name='L358'> <b>const</b> <b>char</b> *thisname;
<a name='L359'> <b>struct</b> m_inode *inode;
<a name='L360'> <b>struct</b> buffer_head *bh;
<a name='L361'> <b>int</b> namelen, inr, idev;
<a name='L362'> <b>struct</b> dir_entry *de;
<a name='L363'>
<a name='L364'><i><font color='green'>// 如果进程没有设定根i 节点,或者该进程根i 节点的引用为0,则系统出错,死机。</font></i>
<a name='L365'> <b>if</b> (!current->root || !current->root->i_count)
<a name='L366'> <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("No root inode");
<a name='L367'><i><font color='green'>// 如果进程的当前工作目录指针为空,或者该当前目录i 节点的引用计数为0,也是系统有问题,死机。</font></i>
<a name='L368'> <b>if</b> (!current->pwd || !current->pwd->i_count)
<a name='L369'> <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("No cwd inode");
<a name='L370'><i><font color='green'>// 如果用户指定的路径名的第1 个字符是'/',则说明路径名是绝对路径名。则从根i 节点开始操作。</font></i>
<a name='L371'> <b>if</b> ((c = <a href='../D/821.html' title='Multiple defined in 2 places.'>get_fs_byte</a> (pathname)) == '/')
<a name='L372'> <font color='red'>{</font>
<a name='L373'> inode = current->root;
<a name='L374'> pathname++;
<a name='L375'><i><font color='green'>// 否则若第一个字符是其它字符,则表示给定的是相对路径名。应从进程的当前工作目录开始操作。</font></i>
<a name='L376'><i><font color='green'>// 则取进程当前工作目录的i 节点。</font></i>
<a name='L377'> <font color='red'>}</font>
<a name='L378'> <b>else</b> <b>if</b> (c)
<a name='L379'> inode = current->pwd;
<a name='L380'><i><font color='green'>// 否则表示路径名为空,出错。返回NULL,退出。</font></i>
<a name='L381'> <b>else</b>
<a name='L382'> <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>; <i><font color='green'>/* empty name is bad */</font></i><i><font color='green'>/* 空的路径名是错误的 */</font></i>
<a name='L383'><i><font color='green'>// 将取得的i 节点引用计数增1。</font></i>
<a name='L384'> inode->i_count++;
<a name='L385'> <b>while</b> (1)
<a name='L386'> <font color='red'>{</font>
<a name='L387'><i><font color='green'>// 若该i 节点不是目录节点,或者没有可进入的访问许可,则释放该i 节点,返回NULL,退出。</font></i>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?