+ brelse(nbp);
+ /*
+ * We return with the directory locked, so that
+ * the parameters we set up above will still be
+ * valid if we actually decide to do a direnter().
+ * We return NULL to indicate that the entry doesn't
+ * currently exist, leaving a pointer to the (locked)
+ * directory inode in u.u_pdir.
+ */
+ u.u_pdir = dp;
+ return (NULL);
+ }
+ u.u_error = ENOENT;
+ goto bad;
+found:
+ /*
+ * Check that directory length properly reflects presence
+ * of this entry.
+ */
+ if (entryoffsetinblock + DIRSIZ(ep) > dp->i_size) {
+ dirbad(dp, "i_size too small");
+ dp->i_size = entryoffsetinblock + DIRSIZ(ep);
+ dp->i_flag |= IUPD|ICHG;
+ }
+
+ /*
+ * Found component in pathname; save directory
+ * entry in u.u_dent, and release directory buffer.
+ */
+ bcopy((caddr_t)ep, (caddr_t)&u.u_dent, (u_int)DIRSIZ(ep));
+ brelse(bp);
+ bp = NULL;
+
+ /*
+ * If deleting, and at end of pathname, return
+ * parameters which can be used to remove file.
+ * Note that in this case we return the directory
+ * inode, not the inode of the file being deleted.
+ */
+ if (flag == 2 && *cp == 0) {
+ /*
+ * Write access to directory required to delete files.
+ */
+ if (access(dp, IWRITE))
+ goto bad;
+ /*
+ * Return pointer to current entry in u.u_offset,
+ * and distance past previous entry (if there
+ * is a previous entry in this block) in u.u_count.
+ * Save directory inode pointer in u.u_pdir for dirremove().
+ */
+ if ((u.u_offset&(DIRBLKSIZ-1)) == 0)
+ u.u_count = 0;
+ else
+ u.u_count = u.u_offset - prevoff;
+ brelse(nbp);
+ u.u_pdir = dp; /* for dirremove() */
+ return (dp);
+ }
+
+ /*
+ * Special handling for ".." allowing chdir out of mounted
+ * file system: indirect .. in root inode to reevaluate
+ * in directory file system was mounted on.
+ */
+ if (u.u_dent.d_name[0] == '.' && u.u_dent.d_name[1] == '.' &&
+ u.u_dent.d_name[2] == '\0') {
+ if (dp == u.u_rdir)
+ u.u_dent.d_ino = dp->i_number;
+ else if (u.u_dent.d_ino == ROOTINO &&
+ dp->i_number == ROOTINO) {
+ for (i = 1; i < NMOUNT; i++)
+ if (mount[i].m_bufp != NULL &&
+ mount[i].m_dev == dp->i_dev) {
+ iput(dp);
+ dp = mount[i].m_inodp;