📄 namei.c
字号:
<a name=L514 href="source/fs/namei.c#L514">514</a> de++;<a name=L515 href="source/fs/namei.c#L515">515</a> de->inode = dir->i_num;<a name=L516 href="source/fs/namei.c#L516">516</a> <a href="ident?i=strcpy">strcpy</a>(de->name,<i>".."</i>);<a name=L517 href="source/fs/namei.c#L517">517</a> inode->i_nlinks = 2;<a name=L518 href="source/fs/namei.c#L518">518</a> dir_block->b_dirt = 1;<a name=L519 href="source/fs/namei.c#L519">519</a> <a href="ident?i=brelse">brelse</a>(dir_block);<a name=L520 href="source/fs/namei.c#L520">520</a> inode->i_mode = <a href="ident?i=I_DIRECTORY">I_DIRECTORY</a> | (mode & 0777 & ~current-><a href="ident?i=umask">umask</a>);<a name=L521 href="source/fs/namei.c#L521">521</a> inode->i_dirt = 1;<a name=L522 href="source/fs/namei.c#L522">522</a> bh = <a href="ident?i=add_entry">add_entry</a>(dir,basename,namelen,&de);<a name=L523 href="source/fs/namei.c#L523">523</a> if (!bh) {<a name=L524 href="source/fs/namei.c#L524">524</a> <a href="ident?i=iput">iput</a>(dir);<a name=L525 href="source/fs/namei.c#L525">525</a> <a href="ident?i=free_block">free_block</a>(inode->i_dev,inode->i_zone[0]);<a name=L526 href="source/fs/namei.c#L526">526</a> inode->i_nlinks=0;<a name=L527 href="source/fs/namei.c#L527">527</a> <a href="ident?i=iput">iput</a>(inode);<a name=L528 href="source/fs/namei.c#L528">528</a> return -<a href="ident?i=ENOSPC">ENOSPC</a>;<a name=L529 href="source/fs/namei.c#L529">529</a> }<a name=L530 href="source/fs/namei.c#L530">530</a> de->inode = inode->i_num;<a name=L531 href="source/fs/namei.c#L531">531</a> bh->b_dirt = 1;<a name=L532 href="source/fs/namei.c#L532">532</a> dir->i_nlinks++;<a name=L533 href="source/fs/namei.c#L533">533</a> dir->i_dirt = 1;<a name=L534 href="source/fs/namei.c#L534">534</a> <a href="ident?i=iput">iput</a>(dir);<a name=L535 href="source/fs/namei.c#L535">535</a> <a href="ident?i=iput">iput</a>(inode);<a name=L536 href="source/fs/namei.c#L536">536</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L537 href="source/fs/namei.c#L537">537</a> return 0;<a name=L538 href="source/fs/namei.c#L538">538</a> }<a name=L539 href="source/fs/namei.c#L539">539</a> <a name=L540 href="source/fs/namei.c#L540">540</a> <b><i>/*</i></b><a name=L541 href="source/fs/namei.c#L541">541</a> <b><i> * routine to check that the specified directory is empty (for rmdir)</i></b><a name=L542 href="source/fs/namei.c#L542">542</a> <b><i> */</i></b><a name=L543 href="source/fs/namei.c#L543">543</a> static int <a href="ident?i=empty_dir">empty_dir</a>(struct <a href="ident?i=m_inode">m_inode</a> * inode)<a name=L544 href="source/fs/namei.c#L544">544</a> {<a name=L545 href="source/fs/namei.c#L545">545</a> int nr,block;<a name=L546 href="source/fs/namei.c#L546">546</a> int len;<a name=L547 href="source/fs/namei.c#L547">547</a> struct <a href="ident?i=buffer_head">buffer_head</a> * bh;<a name=L548 href="source/fs/namei.c#L548">548</a> struct <a href="ident?i=dir_entry">dir_entry</a> * de;<a name=L549 href="source/fs/namei.c#L549">549</a> <a name=L550 href="source/fs/namei.c#L550">550</a> len = inode->i_size / sizeof (struct <a href="ident?i=dir_entry">dir_entry</a>);<a name=L551 href="source/fs/namei.c#L551">551</a> if (len<2 || !inode->i_zone[0] ||<a name=L552 href="source/fs/namei.c#L552">552</a> !(bh=<a href="ident?i=bread">bread</a>(inode->i_dev,inode->i_zone[0]))) {<a name=L553 href="source/fs/namei.c#L553">553</a> <a href="ident?i=printk">printk</a>(<i>"warning - bad directory on dev %04x\n"</i>,inode->i_dev);<a name=L554 href="source/fs/namei.c#L554">554</a> return 0;<a name=L555 href="source/fs/namei.c#L555">555</a> }<a name=L556 href="source/fs/namei.c#L556">556</a> de = (struct <a href="ident?i=dir_entry">dir_entry</a> *) bh->b_data;<a name=L557 href="source/fs/namei.c#L557">557</a> if (de[0].inode != inode->i_num || !de[1].inode || <a name=L558 href="source/fs/namei.c#L558">558</a> <a href="ident?i=strcmp">strcmp</a>(<i>"."</i>,de[0].name) || <a href="ident?i=strcmp">strcmp</a>(<i>".."</i>,de[1].name)) {<a name=L559 href="source/fs/namei.c#L559">559</a> <a href="ident?i=printk">printk</a>(<i>"warning - bad directory on dev %04x\n"</i>,inode->i_dev);<a name=L560 href="source/fs/namei.c#L560">560</a> return 0;<a name=L561 href="source/fs/namei.c#L561">561</a> }<a name=L562 href="source/fs/namei.c#L562">562</a> nr = 2;<a name=L563 href="source/fs/namei.c#L563">563</a> de += 2;<a name=L564 href="source/fs/namei.c#L564">564</a> while (nr<len) {<a name=L565 href="source/fs/namei.c#L565">565</a> if ((void *) de >= (void *) (bh->b_data+<a href="ident?i=BLOCK_SIZE">BLOCK_SIZE</a>)) {<a name=L566 href="source/fs/namei.c#L566">566</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L567 href="source/fs/namei.c#L567">567</a> block=<a href="ident?i=bmap">bmap</a>(inode,nr/<a href="ident?i=DIR_ENTRIES_PER_BLOCK">DIR_ENTRIES_PER_BLOCK</a>);<a name=L568 href="source/fs/namei.c#L568">568</a> if (!block) {<a name=L569 href="source/fs/namei.c#L569">569</a> nr += <a href="ident?i=DIR_ENTRIES_PER_BLOCK">DIR_ENTRIES_PER_BLOCK</a>;<a name=L570 href="source/fs/namei.c#L570">570</a> continue;<a name=L571 href="source/fs/namei.c#L571">571</a> }<a name=L572 href="source/fs/namei.c#L572">572</a> if (!(bh=<a href="ident?i=bread">bread</a>(inode->i_dev,block)))<a name=L573 href="source/fs/namei.c#L573">573</a> return 0;<a name=L574 href="source/fs/namei.c#L574">574</a> de = (struct <a href="ident?i=dir_entry">dir_entry</a> *) bh->b_data;<a name=L575 href="source/fs/namei.c#L575">575</a> }<a name=L576 href="source/fs/namei.c#L576">576</a> if (de->inode) {<a name=L577 href="source/fs/namei.c#L577">577</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L578 href="source/fs/namei.c#L578">578</a> return 0;<a name=L579 href="source/fs/namei.c#L579">579</a> }<a name=L580 href="source/fs/namei.c#L580">580</a> de++;<a name=L581 href="source/fs/namei.c#L581">581</a> nr++;<a name=L582 href="source/fs/namei.c#L582">582</a> }<a name=L583 href="source/fs/namei.c#L583">583</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L584 href="source/fs/namei.c#L584">584</a> return 1;<a name=L585 href="source/fs/namei.c#L585">585</a> }<a name=L586 href="source/fs/namei.c#L586">586</a> <a name=L587 href="source/fs/namei.c#L587">587</a> int <a href="ident?i=sys_rmdir">sys_rmdir</a>(const char * name)<a name=L588 href="source/fs/namei.c#L588">588</a> {<a name=L589 href="source/fs/namei.c#L589">589</a> const char * basename;<a name=L590 href="source/fs/namei.c#L590">590</a> int namelen;<a name=L591 href="source/fs/namei.c#L591">591</a> struct <a href="ident?i=m_inode">m_inode</a> * dir, * inode;<a name=L592 href="source/fs/namei.c#L592">592</a> struct <a href="ident?i=buffer_head">buffer_head</a> * bh;<a name=L593 href="source/fs/namei.c#L593">593</a> struct <a href="ident?i=dir_entry">dir_entry</a> * de;<a name=L594 href="source/fs/namei.c#L594">594</a> <a name=L595 href="source/fs/namei.c#L595">595</a> if (!<a href="ident?i=suser">suser</a>())<a name=L596 href="source/fs/namei.c#L596">596</a> return -<a href="ident?i=EPERM">EPERM</a>;<a name=L597 href="source/fs/namei.c#L597">597</a> if (!(dir = <a href="ident?i=dir_namei">dir_namei</a>(name,&namelen,&basename)))<a name=L598 href="source/fs/namei.c#L598">598</a> return -<a href="ident?i=ENOENT">ENOENT</a>;<a name=L599 href="source/fs/namei.c#L599">599</a> if (!namelen) {<a name=L600 href="source/fs/namei.c#L600">600</a> <a href="ident?i=iput">iput</a>(dir);<a name=L601 href="source/fs/namei.c#L601">601</a> return -<a href="ident?i=ENOENT">ENOENT</a>;<a name=L602 href="source/fs/namei.c#L602">602</a> }<a name=L603 href="source/fs/namei.c#L603">603</a> if (!<a href="ident?i=permission">permission</a>(dir,<a href="ident?i=MAY_WRITE">MAY_WRITE</a>)) {<a name=L604 href="source/fs/namei.c#L604">604</a> <a href="ident?i=iput">iput</a>(dir);<a name=L605 href="source/fs/namei.c#L605">605</a> return -<a href="ident?i=EPERM">EPERM</a>;<a name=L606 href="source/fs/namei.c#L606">606</a> }<a name=L607 href="source/fs/namei.c#L607">607</a> bh = <a href="ident?i=find_entry">find_entry</a>(&dir,basename,namelen,&de);<a name=L608 href="source/fs/namei.c#L608">608</a> if (!bh) {<a name=L609 href="source/fs/namei.c#L609">609</a> <a href="ident?i=iput">iput</a>(dir);<a name=L610 href="source/fs/namei.c#L610">610</a> return -<a href="ident?i=ENOENT">ENOENT</a>;<a name=L611 href="source/fs/namei.c#L611">611</a> }<a name=L612 href="source/fs/namei.c#L612">612</a> if (!(inode = <a href="ident?i=iget">iget</a>(dir->i_dev, de->inode))) {<a name=L613 href="source/fs/namei.c#L613">613</a> <a href="ident?i=iput">iput</a>(dir);<a name=L614 href="source/fs/namei.c#L614">614</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L615 href="source/fs/namei.c#L615">615</a> return -<a href="ident?i=EPERM">EPERM</a>;<a name=L616 href="source/fs/namei.c#L616">616</a> }<a name=L617 href="source/fs/namei.c#L617">617</a> if ((dir->i_mode & <a href="ident?i=S_ISVTX">S_ISVTX</a>) && <a href="ident?i=current">current</a>->euid &&<a name=L618 href="source/fs/namei.c#L618">618</a> inode->i_uid != <a href="ident?i=current">current</a>->euid) {<a name=L619 href="source/fs/namei.c#L619">619</a> <a href="ident?i=iput">iput</a>(dir);<a name=L620 href="source/fs/namei.c#L620">620</a> <a href="ident?i=iput">iput</a>(inode);<a name=L621 href="source/fs/namei.c#L621">621</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L622 href="source/fs/namei.c#L622">622</a> return -<a href="ident?i=EPERM">EPERM</a>;<a name=L623 href="source/fs/namei.c#L623">623</a> }<a name=L624 href="source/fs/namei.c#L624">624</a> if (inode->i_dev != dir->i_dev || inode->i_count>1) {<a name=L625 href="source/fs/namei.c#L625">625</a> <a href="ident?i=iput">iput</a>(dir);<a name=L626 href="source/fs/namei.c#L626">626</a> <a href="ident?i=iput">iput</a>(inode);<a name=L627 href="source/fs/namei.c#L627">627</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L628 href="source/fs/namei.c#L628">628</a> return -<a href="ident?i=EPERM">EPERM</a>;<a name=L629 href="source/fs/namei.c#L629">629</a> }<a name=L630 href="source/fs/namei.c#L630">630</a> if (inode == dir) { <b><i>/* we may not delete ".", but "../dir" is ok */</i></b><a name=L631 href="source/fs/namei.c#L631">631</a> <a href="ident?i=iput">iput</a>(inode);<a name=L632 href="source/fs/namei.c#L632">632</a> <a href="ident?i=iput">iput</a>(dir);<a name=L633 href="source/fs/namei.c#L633">633</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L634 href="source/fs/namei.c#L634">634</a> return -<a href="ident?i=EPERM">EPERM</a>;<a name=L635 href="source/fs/namei.c#L635">635</a> }<a name=L636 href="source/fs/namei.c#L636">636</a> if (!<a href="ident?i=S_ISDIR">S_ISDIR</a>(inode->i_mode)) {<a name=L637 href="source/fs/namei.c#L637">637</a> <a href="ident?i=iput">iput</a>(inode);<a name=L638 href="source/fs/namei.c#L638">638</a> <a href="ident?i=iput">iput</a>(dir);<a name=L639 href="source/fs/namei.c#L639">639</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L640 href="source/fs/namei.c#L640">640</a> return -<a href="ident?i=ENOTDIR">ENOTDIR</a>;<a name=L641 href="source/fs/namei.c#L641">641</a> }<a name=L642 href="source/fs/namei.c#L642">642</a> if (!<a href="ident?i=empty_dir">empty_dir</a>(inode)) {<a name=L643 href="source/fs/namei.c#L643">643</a> <a href="ident?i=iput">iput</a>(inode);<a name=L644 href="source/fs/namei.c#L644">644</a> <a href="ident?i=iput">iput</a>(dir);<a name=L645 href="source/fs/namei.c#L645">645</a> <a href="ident?i=brelse">brelse</a>(bh);<a name=L646 href="source/fs/namei.c#L646">646</a> return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -