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

📄 nfs_gfsops.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	dprint(nfsdebug, 4, "called by 0x%x\n", *(&foo + 5));#endif	if(gp->g_count <= 0)		panic("nfs_rele: zero count");/*	grele will take care of this	if(gp->g_count == 1)		nfs_inactive(gp, u.u_cred);*/	/*	 * Check the count again before freeing up the gnode, in case	 * another reference has been created (we may block in the	 * nfs_inactive call).	 * We have to worry about this because the gnode is still in the	 * cache during the period that we are making it inactive.	 *//*	if (--gp->g_count == 0) {		vp = (struct vnode *)gp;		((struct mntinfo *)vp->v_vfsp->vfs_data)->mi_refct--;		if (vtor(vp)->r_cred) {			crfree(vtor(vp)->r_cred);			vtor(vp)->r_cred = NULL;		}		freegnode(gp);	}*/	grele(gp);}nfs_unlink(gp, ndp)	register struct gnode *gp;	register struct nameidata *ndp;{#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_unlink: trying to remove '%s' from gp 0x%x (%d)\n",	ndp->ni_cp, ndp->ni_pdir, ndp->ni_pdir->g_number);#endif	u.u_error = nfs_remove(ndp->ni_pdir, gp, ndp->ni_cp, u.u_cred);	return(u.u_error);}struct fs_data *nfs_getfsdata(mp)	register struct mount *mp;{	register struct fs_data *fsdata = mp->m_fs_data;	struct statfs statfs;#ifdef GFSDEBUG	if(GFS[14])		printf("nfs_getfsdata: mp 0x%x\n", mp);#endif	u.u_error = nfs_statfs(mp, &statfs);	if (!u.u_error) {		fsdata->fd_fstype = GT_NFS;		fsdata->fd_gtot = 0;		fsdata->fd_gfree = 0;		fsdata->fd_btot = statfs.f_blocks;		fsdata->fd_bfree = statfs.f_bfree;		fsdata->fd_bfreen = statfs.f_bavail;		fsdata->fd_mtsize =			fsdata->fd_otsize =				MP_TO_MIP(mp)->mi_stsize;	}		return(fsdata);}nfs_gsymlink(ndp, to)	register struct nameidata *ndp;	register char *to;{	struct vattr va;#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_symlink: creating a link with name '%s' parent 0x%x (%d)\n",	ndp->ni_cp, ndp->ni_pdir, ndp->ni_pdir->g_number);#endif	vattr_null(&va);	va.va_mode = (0777 & ~u.u_cmask) & 0xffff;	nfs_unlock(ndp->ni_pdir);	u.u_error = nfs_symlink(ndp->ni_pdir, ndp->ni_cp, &va, to, u.u_cred);	nfs_rele(ndp->ni_pdir);	return(u.u_error);}struct gnode *nfs_makenode(mode, dev, ndp)	register int mode;        register dev_t dev;	register struct nameidata *ndp;{	struct vattr _va;	register struct vattr *va = &_va;	struct gnode *vpp;	#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_makenode: trying to make '%s' mode 0%o\n",	ndp->ni_cp, mode);#endif	/*	 * replication of the gross mknod hack	 */	vattr_null(va);	switch (mode & GFMT) {        case GFREG:                va->va_type = VREG;                break;	case GFCHR:		va->va_type = VCHR;/*	printf("nfs_makenode: making chr file '%s'\n",ndp->ni_cp); */		break;	case GFBLK:		va->va_type = VBLK;/*	printf("nfs_makenode: making blk file '%s'\n",ndp->ni_cp); */		break;	case GFPORT:		va->va_type = VFIFO;/*	printf("nfs_makenode: making fifo file '%s'\n",ndp->ni_cp); */		break;	case GFSOCK:		va->va_type = VSOCK;/*	printf("nfs_makenode: making sock file '%s'\n",ndp->ni_cp); */		break;	default:		u.u_error = EINVAL;		goto bad;	}	va->va_mode = (mode & ~u.u_cmask) & 0xffff;	va->va_size = 0;	va->va_rdev = dev;	u.u_error = nfs_create(ndp->ni_pdir, ndp->ni_cp, va, NONEXCL, &vpp, u.u_cred);bad:	gput(ndp->ni_pdir);	if (u.u_error)		return(NULL);	else {		nfs_lock(vpp);		return(vpp);	}}int nfsnameidebug = 0;/* * The routine nfs_namei performs pathname lookup in remote filesystems, * with side effects. * * Unlike the ufs namei, we leave a pointer to the last pathname component * in ndp->ni_cp.  Other NFS code depends on this. */ struct gnode *nfs_namei(ndp)	register struct nameidata *ndp;{	struct gnode *gpp, *gp;	register char *slash, *ptr, *cp, *ncp;	int lockparent, flag, i;	char name[NFS_MAXNAMLEN+1];	struct uio _auio;	register struct uio *auio = &_auio;	struct iovec _aiov;	register struct iovec *aiov = &_aiov;	struct mount *mpp;	int name_len;	u_int sl_len, rem_len;	#ifdef NFSDEBUG	if (nfsnameidebug)	printf("Entering nfs_namei to look up %s\n", ndp->ni_cp);#endif	flag = ndp->ni_nameiop & (LOOKUP | CREATE | DELETE);	lockparent = ndp->ni_nameiop & LOCKPARENT;	gp = ndp->ni_pdir;	nfs_unlock(gp);#ifdef NFSDEBUG	if (gp == NULL) panic("nfs_namei: no parent");	if ((flag != LOOKUP) && (flag != CREATE) && (flag != DELETE))		panic("nfs_namei: bad flags");#endif NFSDEBUG		cp = ndp->ni_cp;	/* 	 * This is a hack for the automounter which mounts itself as  	 * a symbolic link for a direct map entry and expects to be  	 * sent a readlink call.  	 */	if ((gp->g_mode & GFMT) == GFLNK  &&	   ((ndp->ni_nameiop & FOLLOW) || *cp == '/')) {		ncp = cp;		gpp = gp;		gref(gp);  /* bump ref count */		goto MPLINK;	}	while (*cp == '/')		cp++;	while(*cp) {		/*		 * Find the next pathname component, move it into name[].		 */		for (i = 0; cp[i] != 0 && cp[i] != '/'; i++) {			if (i == NFS_MAXNAMLEN)				u.u_error = ENAMETOOLONG;			/* disable parity checking for internationalization */			/* if (cp[i] & 0200) */			/*	u.u_error = EINVAL; */			if (u.u_error) {				nfs_rele(gp);				return(NULL);			}			name[i] = cp[i];		}		name_len = i + 1;		name[i] = '\0';		ncp = cp + i;		/*		 * If we're at the root of a filesystem and the next		 * component is ".." then we just bounce back to caller.		 */		if ((name[0] == '.') && (name[1] == '.') && !name[2]		&& ((gp == gp->g_mp->m_rootgp) || (gp == u.u_rdir))) {			nfs_rele(gp);			/* 			 * If we are not at the system root directory, nor			 * at the processes root directory, set gp to the			 * mounted on gp.			 */ 			if ((gp->g_mp->m_gnodp != (struct gnode *) NULL) &&			     gp != u.u_rdir) 				gp = gp->g_mp->m_gnodp;			gref(gp);	/* bump ref count */			gfs_lock(gp);			gp->g_flag |= GINCOMPLETE;			ndp->ni_pdir = gp;			/*			 * If we're at the system root directory, or the			 * processes root directory, strip off ".."			 */			if (gp == gp->g_mp->m_rootgp || gp == u.u_rdir)				ndp->ni_cp = ncp;			else				ndp->ni_cp = cp;			return(gp);		}				/*		 * Now look up the current pathname component.		 */#ifdef NFSDEBUG		if (nfsnameidebug)		printf("nfs_namei: about to do an nfs_lookup for \"%s\"\n",			name);#endif NFSDEBUG		u.u_error = nfs_lookup(gp, name, &gpp, u.u_cred);#ifdef NFSDEBUGif (nfsnameidebug) {	if (u.u_error)		printf ("nfs_namei: nfs_lookup error return %d\n", u.u_error);	if (gpp)	printf("nfs_namei: nfs_lookup returned #%d\n", (gpp)->g_number);	else printf("nfs_namei: nfs_lookup returned null\n");}#endif NFSDEBUG		/*		 * Take appropriate action if the lookup fails.		 * Negate the error if the file doesn't exist and		 * the operation is create.		 */		if (u.u_error) {			if ((flag == CREATE) && (cp[i] == '\0') &&			    (u.u_error == ENOENT)) {				nfs_lock(gp);				if (!access(gp, GWRITE)) {					u.u_error = 0;					ndp->ni_pdir = gp;					ndp->ni_cp = cp;				}				else {					nfs_unlock(gp);					nfs_rele(gp);				}			}			else {				nfs_rele(gp);			}			return(NULL);		}		/*		 * The lookup has succeeded.  If we've hit a mount point		 * traverse it if it's type NFS, else bounce back to		 * caller.		 *		 * XXX Should check that unmount is not in progress on fs.		 */		if (gpp->g_flag & GMOUNT) {			mpp = gpp->g_mpp;			if (mpp->m_fstype != GT_NFS) {				nfs_rele(gp);				nfs_rele(gpp);				gp = mpp->m_rootgp;				gref(gp);	/* bump ref count */				gfs_lock(gp);				ndp->ni_cp = ncp;				ndp->ni_pdir = gp;				gp->g_flag |= GINCOMPLETE;				return(gp);			}			else {				nfs_rele(gp);				gp = gpp;				gpp = mpp->m_rootgp;				gref(gpp);			}		}		/*		 * Check for symbolic links		 */MPLINK:		if ((gpp->g_mode & GFMT) == GFLNK  &&		   ((ndp->ni_nameiop & FOLLOW) || *ncp == '/')) {			char *tcp;			rem_len = 0;			if (ncp != '\0') {				/*				 * If more pathname to parse, save it				 * in the upper boundary of ni_dirp, because				 * the call to readlink will destroy path.				 */				rem_len = strlen(ncp);				tcp = ndp->ni_dirp + (MAXPATHLEN - rem_len);				ovbcopy(ncp, tcp, rem_len);			}			if (++ndp->ni_slcnt > MAXSYMLINKS) {				u.u_error = ELOOP;				nfs_rele(gp);				nfs_rele(gpp);				return (NULL);			}			aiov->iov_base = ndp->ni_dirp;			aiov->iov_len = auio->uio_resid = MAXPATHLEN;			auio->uio_iov = aiov;			auio->uio_iovcnt = 1;			auio->uio_segflg = UIO_SYSSPACE;			auio->uio_offset = 0;			u.u_error = nfs_readlink((struct vnode *)gpp,				auio, u.u_cred);			if (u.u_error) {				nfs_rele(gp);				nfs_rele(gpp);				return (NULL);			}			/*			 * Since we set iov_len and uio_resid to MAXPATHLEN,			 * we can calculate the size of the symbolic link			 * name by subtracting the remainder of the			 * translation from MAXPATHLEN.			 */			sl_len = MAXPATHLEN - auio->uio_resid; 			/*			 * The remainder of path was stored in			 * the upper boundary of ni_dirp, verify it			 * was not overwritten by the readlink call.			 */			if (sl_len + rem_len + 1 >= MAXPATHLEN - 1) {				u.u_error = ENAMETOOLONG;				nfs_rele(gp);				nfs_rele(gpp);				return (NULL);			}			/*			 * Append remainder of path to symbolic link name			 * returned from server, so we can parse entire			 * path locally. tcp still points to the beginning			 * offset where we stored the remainder.			 */			if (rem_len)				ovbcopy(tcp, ndp->ni_dirp + sl_len, rem_len);			/*			 * Append NULL to new path.			 */			tcp = ndp->ni_dirp + sl_len + rem_len;			*tcp = '\0';			/*			 * Set cp to point at the new path, and check			 * if absolute path.			 */			cp = ndp->ni_dirp;			nfs_rele(gpp);			if (*cp == '/') {				nfs_rele(gp);				while (*cp == '/')					cp++;				if ((gp = u.u_rdir) == NULL)					gp = rootdir;				gref(gp);	/* bump ref count */				gfs_lock(gp);				ndp->ni_cp = cp;				ndp->ni_pdir = gp;				gp->g_flag |= GINCOMPLETE;				return(gp);			}			else {				continue;			}		}		/*		 * The lookup has succeeded and we haven't hit a mount		 * point.  Handle the case where this is the last component		 * of the pathname.		 */		while (*ncp == '/')			ncp++;		if (*ncp == '\0') {			if (ndp->ni_nameiop & NOCACHE)				dnlc_purge_vp(gpp);			if (flag == DELETE) {				nfs_lock(gp);				if (access(gp, GWRITE)) {					nfs_unlock(gp);					nfs_rele(gp);					nfs_rele(gpp);					return(NULL);				}				nfs_unlock(gp);			}			ndp->ni_cp = cp;			if (lockparent) {				if (gp != gpp)					nfs_lock(gp);				ndp->ni_pdir = gp;			}			else {				nfs_rele(gp);			}			/*			 * Copy in the last component name in			 * ni_dent for accounting.			 */			bcopy(ndp->ni_cp, ndp->ni_dent.d_name, name_len);			ndp->ni_dent.d_namlen = name_len;			nfs_lock(gpp);			gpp->g_flag &= ~GINCOMPLETE;			return(gpp);		}		/*		 * The lookup has succeeded, but this is not the last		 * component of the pathname.		 */		nfs_rele(gp);		gp = gpp;		cp = ncp;	}	/*	 * "Temporary" hack for handling null pathnames, which denote the	 * starting directory by convention.  If the path is null and the	 * operation is a create or delete we return EISDIR for hysterical	 * reasons.  Note: we can also get here if the pathname resolves	 * to an NFS mount point.	 */	if (flag != LOOKUP) {		if (gp == gp->g_mp->m_rootgp) {			if (flag == CREATE)			        if ((gp->g_mode & GFMT) == GFDIR)				        u.u_error = EEXIST;			        else {				  	nfs_lock(gp);					gp->g_flag &= ~GINCOMPLETE;					return(gp);				}			else				u.u_error = EBUSY;		} else			u.u_error = EISDIR;		nfs_rele(gp);		return(NULL);	}	nfs_lock(gp);	gp->g_flag &= ~GINCOMPLETE;	return(gp);}

⌨️ 快捷键说明

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