-
- /*
- * Handle "..": two special cases.
- * 1. If at root directory (e.g. after chroot)
- * then ignore it so can't get out.
- * 2. If this vnode is the root of a mounted
- * file system, then replace it with the
- * vnode which was mounted on so we take the
- * .. in the other file system.
- */
- if (ndp->ni_isdotdot) {
- for (;;) {
- if (dp == rootdir) {
- ndp->ni_dvp = dp;
- dp->v_count++;
- goto nextname;
- }
- if ((dp->v_flag & VROOT) == 0)
- break;
- tdp = dp;
- dp = dp->v_mount->m_vnodecovered;
- vput(tdp);
- if ((dp->v_mount->m_flag & M_EXPORTED) == 0)
- return (EACCES);
- VOP_LOCK(dp);
- dp->v_count++;
- if (rootflg)
- ndp->ni_cred->cr_uid = dp->v_mount->m_exroot;
- }
- }
-
- /*
- * We now have a segment name to search for, and a directory to search.
- */
- if (error = VOP_LOOKUP(dp, ndp)) {
- if (ndp->ni_vp != NULL)
- panic("leaf should be empty");
- /*
- * If creating and at end of pathname, then can consider
- * allowing file to be created.
- */
- if (ndp->ni_dvp->v_mount->m_flag & (M_RDONLY | M_EXRDONLY))
- error = EROFS;
- if (flag == LOOKUP || flag == DELETE || error != ENOENT)
- goto bad;
- /*
- * We return with ni_vp NULL to indicate that the entry
- * doesn't currently exist, leaving a pointer to the
- * (possibly locked) directory inode in ndp->ni_dvp.
- */
- return (0); /* should this be ENOENT? */