⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfs_lookup.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			goto bad;		}		if (wantparent) {			ndp->ni_dvp = dp;			VREF(dp);		}		ndp->ni_vp = dp;		if (!(cnp->cn_flags & (LOCKPARENT | LOCKLEAF)))			VOP_UNLOCK(dp);		if (cnp->cn_flags & SAVESTART)			panic("lookup: SAVESTART");		return (0);	}	/*	 * 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	 *    vnode which was mounted on so we take the	 *    .. in the other file system.	 */	if (cnp->cn_flags & ISDOTDOT) {		for (;;) {			if (dp == ndp->ni_rootdir || dp == rootvnode) {				ndp->ni_dvp = dp;				ndp->ni_vp = dp;				VREF(dp);				goto nextname;			}			if ((dp->v_flag & VROOT) == 0 ||			    (cnp->cn_flags & NOCROSSMOUNT))				break;			tdp = dp;			dp = dp->v_mount->mnt_vnodecovered;			vput(tdp);			VREF(dp);			VOP_LOCK(dp);		}	}	/*	 * We now have a segment name to search for, and a directory to search.	 */unionlookup:	ndp->ni_dvp = dp;	if ((error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) != 0) {#ifdef DIAGNOSTIC		if (ndp->ni_vp != NULL)			panic("leaf should be empty");#endif#ifdef NAMEI_DIAGNOSTIC		printf("not found\n");#endif		if ((error == ENOENT) &&		    (dp->v_flag & VROOT) &&		    (dp->v_mount->mnt_flag & MNT_UNION)) {			tdp = dp;			dp = dp->v_mount->mnt_vnodecovered;			vput(tdp);			VREF(dp);			VOP_LOCK(dp);			goto unionlookup;		}		if (error != EJUSTRETURN)			goto bad;		/*		 * If creating and at end of pathname, then can consider		 * allowing file to be created.		 */		if (rdonly || (ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY)) {			error = EROFS;			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.		 */		if (cnp->cn_flags & SAVESTART) {			ndp->ni_startdir = ndp->ni_dvp;			VREF(ndp->ni_startdir);		}		return (0);	}#ifdef NAMEI_DIAGNOSTIC	printf("found\n");#endif	/*	 * Take into account any additional components consumed by	 * the underlying filesystem.	 */	if (cnp->cn_consume > 0) {		cnp->cn_nameptr += cnp->cn_consume;		ndp->ni_next += cnp->cn_consume;		ndp->ni_pathlen -= cnp->cn_consume;		cnp->cn_consume = 0;	}	dp = ndp->ni_vp;	/*	 * Check to see if the vnode has been mounted on;	 * if so find the root of the mounted file system.	 */	while (dp->v_type == VDIR && (mp = dp->v_mountedhere) &&	       (cnp->cn_flags & NOCROSSMOUNT) == 0) {		if (mp->mnt_flag & MNT_MLOCK) {			mp->mnt_flag |= MNT_MWAIT;			sleep((caddr_t)mp, PVFS);			continue;		}		if ((error = VFS_ROOT(dp->v_mountedhere, &tdp)) != 0)			goto bad2;		vput(dp);		ndp->ni_vp = dp = tdp;	}	/*	 * Check for symbolic link	 */	if ((dp->v_type == VLNK) &&	    ((cnp->cn_flags & FOLLOW) || *ndp->ni_next == '/')) {		cnp->cn_flags |= ISSYMLINK;		return (0);	}nextname:	/*	 * Not a symbolic link.  If more pathname,	 * continue at next component, else return.	 */	if (*ndp->ni_next == '/') {		cnp->cn_nameptr = ndp->ni_next;		while (*cnp->cn_nameptr == '/') {			cnp->cn_nameptr++;			ndp->ni_pathlen--;		}		vrele(ndp->ni_dvp);		goto dirloop;	}	/*	 * Check for read-only file systems.	 */	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {		/*		 * Disallow directory write attempts on read-only		 * file systems.		 */		if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||		    (wantparent &&		     (ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY))) {			error = EROFS;			goto bad2;		}	}	if (cnp->cn_flags & SAVESTART) {		ndp->ni_startdir = ndp->ni_dvp;		VREF(ndp->ni_startdir);	}	if (!wantparent)		vrele(ndp->ni_dvp);	if ((cnp->cn_flags & LOCKLEAF) == 0)		VOP_UNLOCK(dp);	return (0);bad2:	if ((cnp->cn_flags & LOCKPARENT) && *ndp->ni_next == '\0')		VOP_UNLOCK(ndp->ni_dvp);	vrele(ndp->ni_dvp);bad:	vput(dp);	ndp->ni_vp = NULL;	return (error);}/* * Reacquire a path name component. */intrelookup(dvp, vpp, cnp)	struct vnode *dvp, **vpp;	struct componentname *cnp;{	register struct vnode *dp = 0;	/* the directory we are searching */	int docache;			/* == 0 do not cache last component */	int wantparent;			/* 1 => wantparent or lockparent flag */	int rdonly;			/* lookup read-only flag bit */	int error = 0;#ifdef NAMEI_DIAGNOSTIC	int newhash;			/* DEBUG: check name hash */	char *cp;			/* DEBUG: check name ptr/len */#endif	/*	 * Setup: break out flag bits into variables.	 */	wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;	if (cnp->cn_nameiop == DELETE ||	    (wantparent && cnp->cn_nameiop != CREATE))		docache = 0;	rdonly = cnp->cn_flags & RDONLY;	cnp->cn_flags &= ~ISSYMLINK;	dp = dvp;	VOP_LOCK(dp);/* dirloop: */	/*	 * Search a new directory.	 *	 * The cn_hash value is for use by vfs_cache.	 * The last component of the filename is left accessible via	 * cnp->cn_nameptr for callers that need the name. Callers needing	 * the name set the SAVENAME flag. When done, they assume	 * responsibility for freeing the pathname buffer.	 */#ifdef NAMEI_DIAGNOSTIC	for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)		newhash += (unsigned char)*cp;	if (newhash != cnp->cn_hash)		panic("relookup: bad hash");	if (cnp->cn_namelen != cp - cnp->cn_nameptr)		panic ("relookup: bad len");	if (*cp != 0)		panic("relookup: not last component");	printf("{%s}: ", cnp->cn_nameptr);#endif	/*	 * Check for degenerate name (e.g. / or "")	 * which is a way of talking about a directory,	 * e.g. like "/." or ".".	 */	if (cnp->cn_nameptr[0] == '\0') {		if (dp->v_type != VDIR) {			error = ENOTDIR;			goto bad;		}		if (cnp->cn_nameiop != LOOKUP || wantparent) {			error = EISDIR;			goto bad;		}		if (!(cnp->cn_flags & LOCKLEAF))			VOP_UNLOCK(dp);		*vpp = dp;		if (cnp->cn_flags & SAVESTART)			panic("lookup: SAVESTART");		return (0);	}	if (cnp->cn_flags & ISDOTDOT)		panic ("relookup: lookup on dot-dot");	/*	 * We now have a segment name to search for, and a directory to search.	 */	if ((error = VOP_LOOKUP(dp, vpp, cnp)) != 0) {#ifdef DIAGNOSTIC		if (*vpp != NULL)			panic("leaf should be empty");#endif		if (error != EJUSTRETURN)			goto bad;		/*		 * If creating and at end of pathname, then can consider		 * allowing file to be created.		 */		if (rdonly || (dvp->v_mount->mnt_flag & MNT_RDONLY)) {			error = EROFS;			goto bad;		}		/* ASSERT(dvp == ndp->ni_startdir) */		if (cnp->cn_flags & SAVESTART)			VREF(dvp);		/*		 * 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);	}	dp = *vpp;#ifdef DIAGNOSTIC	/*	 * Check for symbolic link	 */	if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW))		panic ("relookup: symlink found.\n");#endif	/*	 * Check for read-only file systems.	 */	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {		/*		 * Disallow directory write attempts on read-only		 * file systems.		 */		if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||		    (wantparent &&		     (dvp->v_mount->mnt_flag & MNT_RDONLY))) {			error = EROFS;			goto bad2;		}	}	/* ASSERT(dvp == ndp->ni_startdir) */	if (cnp->cn_flags & SAVESTART)		VREF(dvp);		if (!wantparent)		vrele(dvp);	if ((cnp->cn_flags & LOCKLEAF) == 0)		VOP_UNLOCK(dp);	return (0);bad2:	if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))		VOP_UNLOCK(dvp);	vrele(dvp);bad:	vput(dp);	*vpp = NULL;	return (error);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -