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

📄 nfs_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)nfs_subr.c	4.6	(ULTRIX)	2/28/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1986, 1987 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* *	Portions of this software have been licensed to  *	Digital Equipment Company, Maynard, MA. *	Copyright (c) 1986 Sun Microsystems, Inc.  ALL RIGHTS RESERVED. *//* * *   Modification history: * * 28 Feb 91 -- dws *	Clean up for server view of fhandle.   * * 27 Feb 91 -- chet *	Change nfs_attrcache() calls (yet again). * * 10 Feb 91 -- chet *	Change nfs_attrcache() calls (again). * * 29 Jan 91 -- chet *	Make kernel RPC calls interruptible. * *  7 Jul 90 -- chet *	Change nfs_attrcache() calls. * *  9 Mar 90 -- chet *	Change nfs_attrcache() calls for new argument. *	Add clearing of rnode in nfs_ginit(). * * 12 Jan 90 -- prs *	Added a lockinit of nfsargs lock structure to nfsinit(). * * 08 Dec 89 -- cb *	fixed export list corruption bug. Also check for null gp *	in makenfsnode(). * * 19 Jul 89 -- cb *	modified exportfs() and makefh() to support export options on *	directories. * * 15 May 89 -- condylis *	Moved specvp call from makenfsnode() to nfs_ginit(). * * 10 Mar 89 -- chet *	Added nfs_system_size() routine that returns *	"small | medium | large | xlarge"; *	use it to size # of client handles. * *  7 Mar 89 -- condylis *	Free client handle for a time between RPC timeout cycles *	when trying to reach a hard mounted server. * * 28 Feb 89 -- chet *	Added scheme to prevent "stale fhandle" messages from *	locking out server console. * *  6 Feb 89 -- prs *	Added gput() to a return path in exportfs(). * *  1 Sep 88 -- chet  *	Put a unique transaction ID into rfscall * * 18-Jul-88 -- condylis *	Added SMP locking for CLIENT handle table in clget and clfree. *	Added nfsinit to initialize NFS SMP locks.  Replaced unsafe  *	modifications of gnodes with calls to SMP gnode primitives.  *	Added SMP locking of NFS client statistics. *	 * 10-Jun-88 -- jaw  * 	add parameter to ISSIG for SMP.... this makes going to stop *	state atomic. * * 17 Aug 88 -- chet *      Clear the group IDs for a root mapped to nobody * * 8 Mar 88 -- chet *	exportfs() changes * * 4 Feb 88 -- chet *	Change fhtovp() to not return fhandle unless filesystem *	is exported. * * 26 Jan 88 -- chet *	Fix newname() so that it comes up with a more unique name. *	This routine is used by nfs_unlink() when unlinking open files. * * 14 Jan 88 -- chet *	Expanded stale file handle messages * * 12-28-87	Tim Burke *  	Moved u.u_ttyp to u.u_procp->p_ttyp. * * 12-11-87	Robin L. and Larry C. and Ricky P. *	Added new kmalloc memory allocation to system. * * 14-Jul-87 -- logcher *	Revised logic in exportfs.  Fixed declaration of uap *	arguments.  Added logic to only set m_flags if M_NOFH or *	M_EXRONLY and no other flags ar set.  Added logic to clear *	the M_NOFH and M_EXRONLY flags before setting.  This way a *	flag is turned off without having to reboot or adb the kernel. * * 17-Jun-87 -- logcher *	Changed short cast to an int in exportfs * * 15-Jun-87 -- logcher *	Added suser check to exportfs(), cleaned up returns * * 05-May-87 -- logcher *	Changed usage of m_exflags to m_flags and added M_EXRONLY * * 02-Mar-87 -- logcher *	Merged in diskless changes, added exportfs and check in *	fhtovp for root mapping, added check for specvp */#include "../h/param.h"#include "../h/systm.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/buf.h"#include "../h/proc.h"#include "../h/fs_types.h"#include "../h/mount.h"#include "../h/gnode.h"#include "../h/socket.h"#include "../h/socketvar.h"#include "../h/uio.h"#include "../net/netinet/in.h"#include "../net/rpc/types.h"#include "../net/rpc/xdr.h"#include "../net/rpc/auth.h"#include "../net/rpc/clnt.h"#include "../net/rpc/svc.h"#include "../net/net/if.h"#define NFSSERVER#include "../nfs/nfs.h"#include "../nfs/nfs_clnt.h"#include "../nfs/vfs.h"#include "../nfs/vnode.h"#include "../ufs/fs.h"int do_uprintf = 0;extern struct vnodeops nfs_vnodeops;extern struct gnode_ops *nfs_gnode_ops;extern struct mount_ops *nfs_mount_ops;struct gnode *rfind();extern struct lock_t lk_gnode;/* * Client side utilities *//* * client side statistics */struct {        int     nclsleeps;              /* client handle waits */        int     nclgets;                /* client handle gets */        int     ncalls;                 /* client requests */        int     nbadcalls;              /* rpc failures */        int     reqs[32];               /* count of each request */} clstat;/* SMP lock for client handle table		*/struct	lock_t	lk_nfschtable;/* SMP lock for nfs and rpc statistics		*/struct	lock_t	lk_nfsstat;/* Need extern for nfsinit routine */extern	struct	lock_t lk_nfsbiod;extern	struct	lock_t lk_nfsdnlc;extern	struct	lock_t lk_nfsrrok;extern	struct	lock_t lk_nfsargs;/* lk_rpcxid is used by rpc clients for updating client handle xids *//* (also used by klm_lockmgr.c)  */extern	struct	lock_t lk_rpcxid;#define MINCLIENTS      8#define MAXCLIENTS      36struct chtab {	int	ch_timesused;	bool_t	ch_inuse;	CLIENT	*ch_client;} chtable[MAXCLIENTS];int	chtable_max = 0;	/* chtable high water mark */int	clwanted = 0;/* NFS transaction ID */int     nfs_next_xid = 0;struct chtab *clget(mi, cred)	struct mntinfo *mi;	struct ucred *cred;{	register struct chtab *ch;	int retrans;	/*	 * Set client handle table high water mark based on system "size"	 */	if (!chtable_max) {		smp_lock(&lk_nfschtable, LK_RETRY);		if (!chtable_max) {			chtable_max = 8 * nfs_system_size();			chtable_max = MAX(MINCLIENTS, chtable_max);			chtable_max = MIN(MAXCLIENTS, chtable_max);		}		smp_unlock(&lk_nfschtable);	}	/*	 * If soft mount and server is down just try once	 */	if (!mi->mi_hard && mi->mi_down) {		retrans = 1;	} else {		retrans = mi->mi_retrans;	}	/*	 * Find an unused handle or create one if not at limit yet.	 */	for (;;) {		smp_lock(&lk_nfsstat, LK_RETRY);		clstat.nclgets++;		smp_unlock(&lk_nfsstat);		/* SMP lock client handle table during access */		smp_lock(&lk_nfschtable, LK_RETRY);		for (ch = chtable; ch < &chtable[chtable_max]; ch++) {			if (!ch->ch_inuse) {				ch->ch_inuse = TRUE;				smp_unlock(&lk_nfschtable);				if (ch->ch_client == NULL) {					ch->ch_client =					    clntkudp_create(&mi->mi_addr,					    NFS_PROGRAM, NFS_VERSION,					    retrans, cred);					if (ch->ch_client == NULL)						panic("clget: null client");				} else {					clntkudp_init(ch->ch_client,					    &mi->mi_addr, retrans, cred);				}				ch->ch_timesused++;				return (ch);			}		}		/*		 * If we got here there are no available handles		 */		clwanted++;		sleep_unlock((caddr_t)chtable, PRIBIO, &lk_nfschtable);		smp_lock(&lk_nfsstat, LK_RETRY);		clstat.nclsleeps++;		smp_unlock(&lk_nfsstat);	}}clfree(ch)	struct chtab *ch;{	/* SMP lock client handle table during access		*/	smp_lock(&lk_nfschtable, LK_RETRY);	ch->ch_inuse = FALSE;	if (clwanted) {		clwanted = 0;		wakeup((caddr_t)chtable);	}	smp_unlock(&lk_nfschtable);}char *rpcstatnames[] = {	"Success", "Can't encode arguments", "Can't decode result",	"Unable to send", "Unable to receive", "Timed out",	"Incompatible versions of RPC", "Authentication error",	"Program unavailable", "Program/version mismatch",	"Procedure unavailable", "Server can't decode arguments",	"Remote system error", "Unknown host", "Port mapper failure",	"Program not registered", "Failed (unspecified error)",	"Unknown protocol", "Interrupted"	};char *rfsnames[] = {	"null", "getattr", "setattr", "unused", "lookup", "readlink", "read",	"unused", "write", "create", "remove", "rename", "link", "symlink",	"mkdir", "rmdir", "readdir", "fsstat" };/* * Back off for retransmission timeout, MAXTIMO is in 10ths of a sec */#define MAXTIMO	300#define backoff(tim)	((((tim) << 2) > MAXTIMO) ? MAXTIMO : ((tim) << 2))intrfscall(mi, which, xdrargs, argsp, xdrres, resp, cred)	register struct mntinfo *mi;	int	 which;	xdrproc_t xdrargs;	caddr_t	argsp;	xdrproc_t xdrres;	caddr_t	resp;	struct ucred *cred;{	struct chtab *cht;	CLIENT *client;	register enum clnt_stat status;	struct rpc_err rpcerr;	struct timeval wait;	struct ucred *newcred;	int timeo;	int user_told;	bool_t tryagain;	int hold_nfs_xid;	extern nfs_hardpause();	if (cred == NULL)		panic("rfscall: NULL cred");	smp_lock(&lk_nfsstat, LK_RETRY);	clstat.ncalls++;	clstat.reqs[which]++;	smp_unlock(&lk_nfsstat);	rpcerr.re_errno = 0;	newcred = NULL;	timeo = mi->mi_timeo;	user_told = 0;retry:	cht = clget(mi, cred);	client = cht->ch_client;        /* NFS transaction ID */	smp_lock(&lk_rpcxid, LK_RETRY);        if (!nfs_next_xid)                nfs_next_xid = timepick->tv_sec;        client->cl_xid = nfs_next_xid++;	smp_unlock(&lk_rpcxid);	/*	 * If hard mounted fs, retry call forever unless hard error occurs	 */	do {		tryagain = FALSE;		wait.tv_sec = timeo / 10;		wait.tv_usec = 100000 * (timeo % 10);		status = CLNT_CALL(client, which, xdrargs, argsp,		    xdrres, resp, wait);		switch (status) {		case RPC_SUCCESS:			break;		/*		 * Unrecoverable errors: give up immediately		 */		case RPC_AUTHERROR:		case RPC_CANTENCODEARGS:		case RPC_CANTDECODERES:		case RPC_VERSMISMATCH:		case RPC_PROGVERSMISMATCH:		case RPC_CANTDECODEARGS:			break;		default:			if (mi->mi_hard) {				if (mi->mi_int && status == RPC_INTR) {					tryagain = FALSE;					break;				} else {					tryagain = TRUE; 					if (status == RPC_INTR) 						continue;					timeo = backoff(timeo);					if (!mi->mi_printed) {						mi->mi_printed = 1;      mprintf("NFS server %s not responding, still trying\n", mi->mi_hostname);					}					if (!user_told && u.u_procp->p_ttyp) {						user_told = 1;      uprintf("NFS server %s not responding, still trying\n", mi->mi_hostname);					}					/*				 	 * Pause to free up the client handle 				 	 * for a while. (minimum of 1					 * second)				 	 */					hold_nfs_xid = client->cl_xid;

⌨️ 快捷键说明

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