Cleanups for 4.4BSD-Lite
[unix-history] / usr / src / sys / kern / vfs_lookup.c
index b69ea9f..5330a8a 100644 (file)
@@ -1,25 +1,25 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)vfs_lookup.c        7.43 (Berkeley) %G%
+ *     @(#)vfs_lookup.c        8.1 (Berkeley) %G%
  */
 
  */
 
-#include "param.h"
-#include "syslimits.h"
-#include "time.h"
-#include "namei.h"
-#include "vnode.h"
-#include "mount.h"
-#include "errno.h"
-#include "malloc.h"
-#include "filedesc.h"
-#include "proc.h"
+#include <sys/param.h>
+#include <sys/syslimits.h>
+#include <sys/time.h>
+#include <sys/namei.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/filedesc.h>
+#include <sys/proc.h>
 
 #ifdef KTRACE
 
 #ifdef KTRACE
-#include "ktrace.h"
+#include <sys/ktrace.h>
 #endif
 
 /*
 #endif
 
 /*
@@ -194,7 +194,6 @@ namei(ndp)
  * the target is returned locked, otherwise it is returned unlocked.
  * When creating or renaming and LOCKPARENT is specified, the target may not
  * be ".".  When deleting and LOCKPARENT is specified, the target may be ".".
  * the target is returned locked, otherwise it is returned unlocked.
  * When creating or renaming and LOCKPARENT is specified, the target may not
  * be ".".  When deleting and LOCKPARENT is specified, the target may be ".".
- * NOTE: (LOOKUP | LOCKPARENT) currently returns the parent vnode unlocked.
  * 
  * Overall outline of lookup:
  *
  * 
  * Overall outline of lookup:
  *
@@ -256,7 +255,7 @@ dirloop:
        for (cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
                cnp->cn_hash += (unsigned char)*cp;
        cnp->cn_namelen = cp - cnp->cn_nameptr;
        for (cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
                cnp->cn_hash += (unsigned char)*cp;
        cnp->cn_namelen = cp - cnp->cn_nameptr;
-       if (cnp->cn_namelen >= NAME_MAX) {
+       if (cnp->cn_namelen > NAME_MAX) {
                error = ENAMETOOLONG;
                goto bad;
        }
                error = ENAMETOOLONG;
                goto bad;
        }
@@ -288,7 +287,7 @@ dirloop:
         * e.g. like "/." or ".".
         */
        if (cnp->cn_nameptr[0] == '\0') {
         * e.g. like "/." or ".".
         */
        if (cnp->cn_nameptr[0] == '\0') {
-               if (cnp->cn_nameiop != LOOKUP || wantparent) {
+               if (cnp->cn_nameiop != LOOKUP) {
                        error = EISDIR;
                        goto bad;
                }
                        error = EISDIR;
                        goto bad;
                }
@@ -296,9 +295,13 @@ dirloop:
                        error = ENOTDIR;
                        goto bad;
                }
                        error = ENOTDIR;
                        goto bad;
                }
-               if (!(cnp->cn_flags & LOCKLEAF))
-                       VOP_UNLOCK(dp);
+               if (wantparent) {
+                       ndp->ni_dvp = dp;
+                       vref(dp);
+               }
                ndp->ni_vp = dp;
                ndp->ni_vp = dp;
+               if (!(cnp->cn_flags & (LOCKPARENT | LOCKLEAF)))
+                       VOP_UNLOCK(dp);
                if (cnp->cn_flags & SAVESTART)
                        panic("lookup: SAVESTART");
                return (0);
                if (cnp->cn_flags & SAVESTART)
                        panic("lookup: SAVESTART");
                return (0);
@@ -307,6 +310,7 @@ dirloop:
        /*
         * Handle "..": two special cases.
         * 1. If at root directory (e.g. after chroot)
        /*
         * Handle "..": two special cases.
         * 1. If at root directory (e.g. after chroot)
+        *    or at absolute root directory
         *    then ignore it so can't get out.
         * 2. If this vnode is the root of a mounted
         *    filesystem, then replace it with the
         *    then ignore it so can't get out.
         * 2. If this vnode is the root of a mounted
         *    filesystem, then replace it with the
@@ -315,7 +319,7 @@ dirloop:
         */
        if (cnp->cn_flags & ISDOTDOT) {
                for (;;) {
         */
        if (cnp->cn_flags & ISDOTDOT) {
                for (;;) {
-                       if (dp == ndp->ni_rootdir) {
+                       if (dp == ndp->ni_rootdir || dp == rootdir) {
                                ndp->ni_dvp = dp;
                                ndp->ni_vp = dp;
                                VREF(dp);
                                ndp->ni_dvp = dp;
                                ndp->ni_vp = dp;
                                VREF(dp);