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

📄 nfs_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
					clfree(cht);					timeout(nfs_hardpause,						(caddr_t)u.u_procp,						MAX(((timeo * hz) / 10), hz));					sleep((caddr_t)u.u_procp, PRIBIO);        				cht = clget(mi, cred);        				client = cht->ch_client;        				client->cl_xid = hold_nfs_xid;				}			}		}	} while (tryagain);	if (status != RPC_SUCCESS) {		if (status == RPC_INTR) {			rpcerr.re_status = RPC_INTR;			rpcerr.re_errno = EINTR;			u.u_error = EINTR;		} else {			CLNT_GETERR(client, &rpcerr);			mprintf("NFS %s failed for server %s: %s\n",				rfsnames[which], mi->mi_hostname,				rpcstatnames[(int)status]);			if (do_uprintf && u.u_procp->p_ttyp)				uprintf("NFS %s failed for server %s: %s\n",					rfsnames[which], mi->mi_hostname,					rpcstatnames[(int)status]);			if (!u.u_error)				u.u_error = EIO; /* if in doubt ... */		}		smp_lock(&lk_nfsstat, LK_RETRY);		clstat.nbadcalls++;		smp_unlock(&lk_nfsstat);		mi->mi_down = 1;	} else if (resp && *(int *)resp == EACCES &&		   newcred == NULL && cred->cr_uid == 0 &&		   cred->cr_ruid != 0) {		/*		 * Boy is this a kludge!  If the reply status is EACCES		 * it may be because we are root (no root net access).		 * Check the real uid, if it isn't root make that		 * the uid instead and retry the call.		 */		newcred = crdup(cred);		cred = newcred;		cred->cr_uid = cred->cr_ruid;		clfree(cht);		goto retry;	} else if (mi->mi_hard) {		if (mi->mi_printed) {			mprintf("NFS server %s ok\n", mi->mi_hostname);			mi->mi_printed = 0;		}		if (user_told) {			uprintf("NFS server %s ok\n", mi->mi_hostname);		}	} else {		mi->mi_down = 0;	}	clfree(cht);	if (newcred) {		crfree(newcred);	}	return (rpcerr.re_errno);}/* * Set vattr structure to a null value. */voidvattr_null(vap)	struct vattr *vap;{	register int n;	register char *cp;	n = sizeof(struct vattr);	cp = (char *)vap;	while (n--) {		*cp++ = -1;	}}int attrdebug = 0;vattr_to_sattr(vap, sa)	register struct vattr *vap;	register struct nfssattr *sa;{	sa->sa_mode = vap->va_mode;	sa->sa_uid = vap->va_uid;	sa->sa_gid = vap->va_gid;	sa->sa_size = vap->va_size;	sa->sa_atime  = vap->va_atime;	sa->sa_mtime  = vap->va_mtime;if (attrdebug) {	printf("vattr_to_sattr: atime: %d, %d    mtime: %d, %d\n",		sa->sa_atime.tv_sec, sa->sa_atime.tv_usec,		sa->sa_mtime.tv_sec, sa->sa_mtime.tv_usec);}}setdiropargs(da, nm, dvp)	struct nfsdiropargs *da;	char *nm;	struct vnode *dvp;{	da->da_fhandle = *vtofh(dvp);	da->da_name = nm;}/* * Return a gnode for the given fhandle.  If no gnode exists for this * fhandle create one and put it in the gnode table.  If a gnode is found, * return it with its reference count incremented. */struct rnode_data {	fhandle_t	*rn_fh;	struct nfsfattr	*rn_attr;	int		rn_newnode;};/* * Return a gnode for the given fhandle.  If no gnode exists for this * fhandle create one and put it in the gnode table.  If a gnode is found, * return it with its reference count incremented.  KLUDGE: the GFS buffer * hashing scheme will not work unless we reuse the same gnode slot when * we reopen a given file.  For this reason we leave gnodes on their * hash chain when we free them, so gget can find them and reclaim them. * We must take care when reinitializing reclaimed gnodes; some parts must * be reinitialized and others must be kept from the last invocation (such * as the modify time). */struct vnode *makenfsnode(fh, attr, vfsp, mp)	fhandle_t *fh;	struct nfsfattr *attr;	struct vfs *vfsp;	struct mount *mp;{	char newnode = 0;	register struct gnode *gp;	struct rnode_data rnd;	register struct vnode *vp;	gno_t	gno;	rnd.rn_fh = fh;	rnd.rn_attr = attr;	rnd.rn_newnode = 0;	gno = (attr) ? attr->na_nodeid : fh->fh_fno;	gp = gget(mp, gno, 1, &rnd);	if (gp != NULL) {		gfs_unlock(gp);		if (attr && rnd.rn_newnode == 0)			nfs_attrcache(gp, attr, SFLUSH);	}	return ((struct vnode *)gp);}intnfs_match(gp, rdp)	struct gnode *gp;	struct rnode_data *rdp;{	return(!bcmp(vtofh((struct vnode *)gp), rdp->rn_fh,		sizeof(fhandle_t)));}/*	 * Initialize the gnode if this is the first reference (the gnode	 * is either new or reclaimed).	 */nfs_ginit(gp, iflag, rdp)	struct gnode *gp;	int iflag;	struct rnode_data *rdp;{	register struct vnode *vp = (struct vnode *)gp;	register struct nfsfattr *attr;	int type;/* * if we get here via ggrab, rdp is null, so we need to return an * error, so ufs_namei will keep its hands off this gnode... */	if (rdp == NULL)			return(NULL);	attr = rdp->rn_attr; 	gp->g_ops = nfs_gnode_ops;	bzero(vtor((struct vnode *)gp), sizeof(struct rnode));	vtor(vp)->r_fh = *(rdp->rn_fh);	if (attr)		vp->v_type = (enum vtype)attr->na_type;	vp->v_vfsp = MP_TO_VFSP(gp->g_mp);	((struct mntinfo *)(vp->v_vfsp->vfs_data))->mi_refct++;	if (attr)		nfs_attrcache(gp, attr,			      (iflag == NEW_GNODE) ? NOFLUSH : SFLUSH);	type = gp->g_mode & GFMT;	if ((type == GFCHR) || (type == GFBLK) || (type == GFPORT))		specvp(gp);	rdp->rn_newnode = 1;	return(1);}/* * Kludge an "invisible temp name from an existing name. * Attempt to make a unique one, * but can't guarantee this. This new name is used for the * "rename game" - renaming an open file that is unlinked over NFS. * Use hostid, pid, and a generation # in the temp name. */#define	PREFIXLEN	4static char prefix[PREFIXLEN+1] = ".nfs";u_long rename_gennum;char *newname(s)	char *s;{	register char *news;	register char *s1, *s2;	register int i;	register u_long id;	kmem_alloc(news, char *, (u_int)NFS_MAXNAMLEN, KM_NFS);	for (s1 = news, s2 = prefix; s2 < &prefix[PREFIXLEN]; ) {		*s1++ = *s2++;	}	id = hostid;	for (i = 0; i < sizeof(id)*2; i++) {		*s1++ = "0123456789ABCDEF"[id & 0x0f];		id = id >> 4;	}	id = u.u_procp->p_pid;	for (i = 0; i < sizeof(id)*2; i++) {		*s1++ = "0123456789ABCDEF"[id & 0x0f];		id = id >> 4;	}	if (!rename_gennum)		rename_gennum = timepick->tv_usec;	id = rename_gennum++;	for (i = 0; i < sizeof(id)*2; i++) {		*s1++ = "0123456789ABCDEF"[id & 0x0f];		id = id >> 4;	}	*s1 = '\0';	return (news);}/* * Server side utilities */vattr_to_nattr(vap, na)	register struct vattr *vap;	register struct nfsfattr *na;{	na->na_type = (enum nfsftype)vap->va_type;	na->na_mode = vap->va_mode;	na->na_uid = vap->va_uid;	na->na_gid = vap->va_gid;	na->na_fsid = vap->va_fsid;	na->na_nodeid = vap->va_nodeid;	na->na_nlink = vap->va_nlink;	na->na_size = vap->va_size;	na->na_atime = vap->va_atime;	na->na_mtime = vap->va_mtime;	na->na_ctime = vap->va_ctime;	na->na_rdev = vap->va_rdev;	na->na_blocks = vap->va_blocks;	na->na_blocksize = vap->va_blocksize;	/*	 * This bit of ugliness is a *TEMPORARY* hack to preserve the	 * over-the-wire protocols for named-pipe vnodes.  It remaps the	 * VFIFO type to the special over-the-wire type. (see note in nfs.h)	 *	 * BUYER BEWARE:	 *  If you are porting the NFS to a non-SUN server, you probably	 *  don't want to include the following block of code.  The	 *  over-the-wire special file types will be changing with the	 *  NFS Protocol Revision.	 */	if ((vap->va_mode&GFMT) == GFPORT) {		na->na_type = (enum nfsftype)VCHR;		na->na_rdev = NFS_FIFO_DEV;		na->na_mode = (na->na_mode&~GFMT)|GFCHR; 	}}sattr_to_vattr(sa, vap)	register struct nfssattr *sa;	register struct vattr *vap;{	vattr_null(vap);	vap->va_mode = sa->sa_mode;	vap->va_uid = sa->sa_uid;	vap->va_gid = sa->sa_gid;	vap->va_size = sa->sa_size;	vap->va_atime = sa->sa_atime;	vap->va_mtime = sa->sa_mtime;	if (attrdebug) {		printf("sattr_to_vattr: atime: %d, %d    mtime: %d, %d\n",			sa->sa_atime.tv_sec, sa->sa_atime.tv_usec,			sa->sa_mtime.tv_sec, sa->sa_mtime.tv_usec);	}}/* * Make an fhandle from a ufs gnode */makefh(fh, gp, enumber, egen)	register fhandle_t *fh;	struct gnode *gp;	u_long enumber, egen;{	if (gp->g_mp->m_ops == nfs_mount_ops)		return(EREMOTE);	bzero((caddr_t)fh, NFS_FHSIZE);	fh->fh_fsid = gp->g_dev;	fh->fh_fno = gp->g_number;	fh->fh_fgen = gp->g_gennum;	fh->fh_eno = enumber;	fh->fh_egen = egen;	return (0);}/* * Global "constants" and defines used for stale file handle processing */long stalefh_count = 0;long nfs_n_nomount = 0;long nfs_last_nomount = 0;long nfs_nomount_thresh = 10;long nfs_nomount_timeout = 600;long nfs_noexport_thresh = 10;long nfs_noexport_timeout = 600;long nfs_stale_thresh = 10;long nfs_stale_timeout = 600;#define NFS_N_NOEXPORT(mp) ((mp)->m_fs_data->fd_spare[100])#define NFS_LAST_NOEXPORT(mp) ((mp)->m_fs_data->fd_spare[101])#define NFS_N_STALE(mp) ((mp)->m_fs_data->fd_spare[102])#define NFS_LAST_STALE(mp) ((mp)->m_fs_data->fd_spare[103])/* * Convert a fhandle into a gnode.  Uses the inode number in the * fhandle (fh_fno) to get the locked inode.  The inode is unlocked * and used to get the gnode.  WARNING: users of this routine must * do a VN_RELE on the gnode when they are done with it. */struct vnode *fhtovp(fh, xprt, which, xpd)	fhandle_t *fh;	SVCXPRT *xprt;	int	which;	struct exportdata *xpd;{	register struct mount *mp; 	register struct gnode *gp;        register int *grp;      /* group ID pointer */	register struct gnode *rgp;	struct export *ep;	extern struct mount *getmp();	extern struct gnode *fref();	int	print;	print = 1; 	/*	 * Check that the file system is mounted on and	 * if so get a ref on it.	 */	GETMP(mp, fh->fh_fsid);	if ((rgp = fref(mp, fh->fh_fsid)) == NULL) {		/*		 * These messages can be a pain - sometimes you want them,		 * sometimes (most of the time) you don't.		 * Print the first nfs_nomount_thresh, then keep a		 * timestamp and throw the rest away until nfs_nomount_timeout		 * seconds have passed; after that, start over with the		 * same algorithm.		 *		 * If nfs_nomount_thresh is set (via adb or the like)		 * to zero, then all messages will be printed.		 *		 * If nfs_nomount_thresh is positive, and		 * nfs_nomount_timeout is set to zero,		 * then no more than nfs_nomount_thresh messages will be		 * printed.		 */		if (nfs_nomount_thresh) {			++nfs_n_nomount;			if (nfs_n_nomount == nfs_nomount_thresh) {				nfs_last_nomount = timepick->tv_sec;			}			else if (nfs_n_nomount > nfs_nomount_thresh) {				if (nfs_nomount_timeout &&					timepick->tv_sec > nfs_last_nomount +					nfs_nomount_timeout) {						nfs_n_nomount = 1;				}

⌨️ 快捷键说明

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