Link path walk

Retired DISLab
이동: 둘러보기, 찾기

http://lxr.free-electrons.com/source/fs/namei.c#L1728

1720 /*
1721  * Name resolution.
1722  * This is the basic name resolution function, turning a pathname into
1723  * the final dentry. We expect 'base' to be positive and a directory.
1724  *
1725  * Returns 0 and nd will have valid dentry and mnt on success.
1726  * Returns error and drops reference to input namei data on failure.
1727  */
1728 static int link_path_walk(const char *name, struct nameidata *nd)
1729 {
1730         struct path next;
1731         int err;
1732         
1733         while (*name=='/')
1734                 name++;
1735         if (!*name)
1736                 return 0;
1737 
1738         /* At this point we know we have a real path component. */
1739         for(;;) {
1740                 struct qstr this;
1741                 long len;
1742                 int type;
1743 
1744                 err = may_lookup(nd);
1745                 if (err)
1746                         break;
1747 
1748                 len = hash_name(name, &this.hash);
1749                 this.name = name;
1750                 this.len = len;
1751 
1752                 type = LAST_NORM;
1753                 if (name[0] == '.') switch (len) {
1754                         case 2:
1755                                 if (name[1] == '.') {
1756                                         type = LAST_DOTDOT;
1757                                         nd->flags |= LOOKUP_JUMPED;
1758                                 }
1759                                 break;
1760                         case 1:
1761                                 type = LAST_DOT;
1762                 }
1763                 if (likely(type == LAST_NORM)) {
1764                         struct dentry *parent = nd->path.dentry;
1765                         nd->flags &= ~LOOKUP_JUMPED;
1766                         if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
1767                                 err = parent->d_op->d_hash(parent, &this);
1768                                 if (err < 0)
1769                                         break;
1770                         }
1771                 }
1772 
1773                 nd->last = this;
1774                 nd->last_type = type;
1775 
1776                 if (!name[len])
1777                         return 0;
1778                 /*
1779                  * If it wasn't NUL, we know it was '/'. Skip that
1780                  * slash, and continue until no more slashes.
1781                  */
1782                 do {
1783                         len++;
1784                 } while (unlikely(name[len] == '/'));
1785                 if (!name[len])
1786                         return 0;
1787 
1788                 name += len;
1789 
1790                 err = walk_component(nd, &next, LOOKUP_FOLLOW);
1791                 if (err < 0)
1792                         return err;
1793 
1794                 if (err) {
1795                         err = nested_symlink(&next, nd);
1796                         if (err)
1797                                 return err;
1798                 }
1799                 if (!d_is_directory(nd->path.dentry)) {
1800                         err = -ENOTDIR; 
1801                         break;
1802                 }
1803         }
1804         terminate_walk(nd);
1805         return err;
1806 }
개인 도구
이름공간
변수
행위
둘러보기
구성원
연구
연구실
기타
도구모음
인쇄/내보내기