- goto Err_Exit;
- }
- else if (isDotDot) {
- retval = VFS_VGET(parent_vp->v_mount, &nodeID, &target_vp);
- if (retval)
- goto Err_Exit;
- }
- else {
- /* If then name differs in case, then act like it does not exist
- * This allows renaming foo->Foo
- * Exclude length difference due to compose/decompe issues.
- */
- if ((cnp->cn_namelen == catInfo.nodeData.cnm_length) &&
- strncmp(cnp->cn_nameptr, catInfo.nodeData.cnm_nameptr, targetLen)) {
- if (!lockparent)
- VOP_UNLOCK(parent_vp, 0, p);
- retval = EJUSTRETURN;
- goto Err_Exit;
- };
-
- retval = hfs_vget_catinfo(parent_vp, &catInfo, kAnyFork, &target_vp);
- if (retval)
- goto Err_Exit;
-
- CLEAN_CATALOGDATA(&catInfo.nodeData); /* Should do nothing */
- };
-
- cnp->cn_flags |= SAVENAME;
- if (!lockparent)
- VOP_UNLOCK(parent_vp, 0, p);
-
- goto Err_Exit;
- /* Finished...all is well, goto the end */
- };
-
- /*
- * Step through the translation in the name. We do not `vput' the
- * directory because we may need it again if a symbolic link
- * is relative to the current directory. Instead we save it
- * unlocked as "tparent_vp". We must get the target hfsnode before unlocking
- * the directory to insure that the hfsnode will not be removed
- * before we get it. We prevent deadlock by always fetching
- * inodes from the root, moving down the directory tree. Thus
- * when following backward pointers ".." we must unlock the
- * parent directory before getting the requested directory.
- * There is a potential race condition here if both the current
- * and parent directories are removed before the VFS_VGET for the
- * hfsnode associated with ".." returns. We hope that this occurs
- * infrequently since we cannot avoid this race condition without
- * implementing a sophisticated deadlock detection algorithm.
- * Note also that this simple deadlock detection scheme will not
- * work if the file system has any hard links other than ".."
- * that point backwards in the directory structure.
- */
-
- tparent_vp = parent_vp;
- if (isDotDot) {
- VOP_UNLOCK(tparent_vp, 0, p); /* race to get the inode */
- if ((retval = VFS_VGET(parent_vp->v_mount, &nodeID, &target_vp))) {
- vn_lock(tparent_vp, LK_EXCLUSIVE | LK_RETRY, p);
- goto Err_Exit;
- }
- if (lockparent && (flags & ISLASTCN) && (tparent_vp != target_vp) &&
- (retval = vn_lock(tparent_vp, LK_EXCLUSIVE, p))) {
- vput(target_vp);
- goto Err_Exit;