Path init
Retired DISLab
http://lxr.free-electrons.com/source/fs/namei.c#L1808
1808 static int path_init(int dfd, const char *name, unsigned int flags, 1809 struct nameidata *nd, struct file **fp) 1810 { 1811 int retval = 0; 1812 1813 nd->last_type = LAST_ROOT; /* if there are only slashes... */ 1814 nd->flags = flags | LOOKUP_JUMPED; 1815 nd->depth = 0; 1816 if (flags & LOOKUP_ROOT) { 1817 struct dentry *root = nd->root.dentry; 1818 struct inode *inode = root->d_inode; 1819 if (*name) { 1820 if (!d_is_directory(root)) 1821 return -ENOTDIR; 1822 retval = inode_permission(inode, MAY_EXEC); 1823 if (retval) 1824 return retval; 1825 } 1826 nd->path = nd->root; 1827 nd->inode = inode; 1828 if (flags & LOOKUP_RCU) { 1829 rcu_read_lock(); 1830 nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); 1831 nd->m_seq = read_seqbegin(&mount_lock); 1832 } else { 1833 path_get(&nd->path); 1834 } 1835 return 0; 1836 } 1837 1838 nd->root.mnt = NULL; 1839 1840 nd->m_seq = read_seqbegin(&mount_lock); 1841 if (*name=='/') { 1842 if (flags & LOOKUP_RCU) { 1843 rcu_read_lock(); 1844 set_root_rcu(nd); 1845 } else { 1846 set_root(nd); 1847 path_get(&nd->root); 1848 } 1849 nd->path = nd->root; 1850 } else if (dfd == AT_FDCWD) { 1851 if (flags & LOOKUP_RCU) { 1852 struct fs_struct *fs = current->fs; 1853 unsigned seq; 1854 1855 rcu_read_lock(); 1856 1857 do { 1858 seq = read_seqcount_begin(&fs->seq); 1859 nd->path = fs->pwd; 1860 nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); 1861 } while (read_seqcount_retry(&fs->seq, seq)); 1862 } else { 1863 get_fs_pwd(current->fs, &nd->path); 1864 } 1865 } else { 1866 /* Caller must check execute permissions on the starting path component */ 1867 struct fd f = fdget_raw(dfd); 1868 struct dentry *dentry; 1869 1870 if (!f.file) 1871 return -EBADF; 1872 1873 dentry = f.file->f_path.dentry; 1874 1875 if (*name) { 1876 if (!d_is_directory(dentry)) { 1877 fdput(f); 1878 return -ENOTDIR; 1879 } 1880 } 1881 1882 nd->path = f.file->f_path; 1883 if (flags & LOOKUP_RCU) { 1884 if (f.flags & FDPUT_FPUT) 1885 *fp = f.file; 1886 nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); 1887 rcu_read_lock(); 1888 } else { 1889 path_get(&nd->path); 1890 fdput(f); 1891 } 1892 } 1893 1894 nd->inode = nd->path.dentry->d_inode; 1895 return 0; 1896 }