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

📄 klm_lockmgr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	case KLM_TEST:		switch (error) {		case klm_granted:			ld->l_type = F_UNLCK;	/* mark lock available */			error = 0;			goto ereturn;		case klm_denied:			ld->l_type = (reply.klm_testrply_u.holder.exclusive) ?			    F_WRLCK : F_RDLCK;			ld->l_start = reply.klm_testrply_u.holder.l_offset;			ld->l_len = reply.klm_testrply_u.holder.l_len;			ld->l_pid = reply.klm_testrply_u.holder.svid;			error = 0;			goto ereturn;		case klm_denied_nolocks:			goto nolocks_wait;	/* back off; loop forever */		case EINTR:			/* may want to take a longjmp here */			goto requestloop;	/* loop forever */		}	}/*NOTREACHED*/nolocks_wait:	timeout(wakeup, (caddr_t)&lm_sa, (klm_backoff_timeout * hz));	(void) sleep((caddr_t)&lm_sa, PZERO|PCATCH);	untimeout(wakeup, (caddr_t)&lm_sa);	goto requestloop;	/* now try again */cancel:	if(klm_debug)	          printf("klm_lockctl: request canceled for pid:%d\n",				args.alock.pid);	/*	 * If we get here, a signal interrupted a rqst that must be cancelled.	 * Change the procedure number to KLM_CANCEL and reissue the exact same	 * request.  Use the results to decide what return value to give.	 */	xdrproc = KLM_CANCEL;	error = talk_to_lockmgr(xdrproc,xdrargs, &args, xdrreply, &reply, cred);	switch (error) {	case klm_granted:		error = 0;		/* lock granted */		goto ereturn;	case klm_denied:		/* may want to take a longjmp here */		error = EINTR;		goto ereturn;	case EINTR:		goto cancel;	/* ignore signals til cancel succeeds */	case klm_denied_nolocks:		error = ENOLCK;		/* no resources available?! */		goto ereturn;	case ENOLCK:		goto ereturn;	}/*NOTREACHED*/ereturn:	if(klm_debug)	  printf("klm_lockctl: returning: err: %d\n", error);	return(error);}/* * Send the given request to the local lock-manager. * If timeout or error, go back to the portmapper to check the port number. * This routine loops forever until one of the following occurs: *	1) A legitimate (not 'klm_working') reply is returned (returns 'stat'). * *	2) A signal occurs (returns EINTR).  In this case, at least one try *	   has been made to do the RPC; this protects against jamming the *	   CPU if a KLM_CANCEL request has yet to go out. * *	3) A drastic error occurs (e.g., the local lock-manager has never *	   been activated OR cannot create a client-handle) (returns ENOLCK). */statictalk_to_lockmgr(xdrproc, xdrargs, args, xdrreply, reply, cred)	u_long xdrproc;	xdrproc_t xdrargs;	klm_lockargs *args;	xdrproc_t xdrreply;	klm_testrply *reply;	struct ucred *cred;{	register CLIENT *client;	struct timeval tmo;	register int error;	register int retries;	/* set up a client handle to talk to the local lock manager */	client = clntkudp_create(&lm_sa, (u_long)KLM_PROG, (u_long)KLM_VERS,	    klm_first_retry, cred);	if (client == (CLIENT *) NULL) {		return(ENOLCK);	}	tmo.tv_sec = klm_first_timeout;	tmo.tv_usec = 0;	/* init and manage xid on behalf of lockd/kernel communication */	smp_lock(&lk_rpcxid, LK_RETRY);	if (!lm_xid)		lm_xid = time.tv_sec;	client->cl_xid = lm_xid++;	smp_unlock(&lk_rpcxid);	/*	 * If cached port number, go right to CLNT_CALL().	 * This works because timeouts go back to the portmapper to	 * refresh the port number.	 */	if (lm_sa.sin_port != 0) {		retries = klm_timeout_retry;		goto retryloop;		/* skip first portmapper query */	}	for (;;) {remaploop:                if (klm_debug) {                        printf ("remap: pid:%d proc:%d %d %d\n",                                args->alock.pid, (int) xdrproc,                                time.tv_sec, lm_xid);                }		/* go get the port number from the portmapper...		 * if return 1, signal was received before portmapper answered;		 * if return -1, the lock-manager is not registered		 * else, got a port number		 */		switch(getport_loop(&lm_sa, (u_long)KLM_PROG, (u_long)KLM_VERS,		(u_long)KLM_PROTO)) {		case 1:			error = EINTR;		/* signal interrupted things */			goto out;		case -1:			error = ENOLCK;			goto out;		}		/*		 * If a signal occurred, pop back out to the higher		 * level to decide what action to take.  If we just		 * got a port number from the portmapper, the next		 * call into this subroutine will jump to retryloop.		 */		if (ISSIG(u.u_procp,0)) {			error = EINTR;			goto out;		}		/* reset the lock-manager client handle */		(void) clntkudp_init(client, &lm_sa, 			klm_remap_retry, cred);		tmo.tv_sec = klm_normal_timeout;		retries    = klm_timeout_retry;retryloop:                if (klm_debug) {                        printf ("retry: pid:%d proc:%d %d %d %d\n",                                args->alock.pid, (int) xdrproc, time.tv_sec,                                lm_xid, retries);                }		/* retry the request until completion, timeout, or error */		for (;;) {			smp_lock(&lk_rpcxid, LK_RETRY);			client->cl_xid = lm_xid++;			smp_unlock(&lk_rpcxid);			error = (int) CLNT_CALL(client, xdrproc, xdrargs,			    (caddr_t)args, xdrreply, (caddr_t)reply, tmo);			if (klm_debug)printf("retry: rec'd: pid:%d proce:%d [off:%d,len:%d] err:%d rs:%d %d %d\n",				    args->alock.pid,				    (int) xdrproc,				    args->alock.l_offset,				    args->alock.l_len,				    error, (int) reply->stat, time.tv_sec,					lm_xid);			switch (error) {			case RPC_SUCCESS:				error = (int) reply->stat;				if (error == (int) klm_working) {					if (ISSIG(u.u_procp,0)) {						error = EINTR;						goto out;					}					/* lock-mgr is up...can wait longer */					(void) clntkudp_init(client, &lm_sa,					    klm_working_retry, cred);					tmo.tv_sec = klm_working_timeout;					retries    = klm_timeout_retry;					klm_succ_work++;					continue;	/* retry */				}				klm_succ_out++;				goto out;	/* got a legitimate answer */			case RPC_TIMEDOUT:				if(klm_debug)					printf("retry: RPC_TIMEDOUT:pid:%d retries:%d\n",						args->alock.pid, retries);				klm_to++;				if (--retries > 0)					continue;				else					goto remaploop;	/* ask for port# again */			default:				klm_other++;				if (klm_debug) 			printf("lock-manager: RPC error:%d sleeping:%d\n",				  error, (klm_normal_timeout*hz));				/* on RPC error, wait a bit and try again */				timeout(wakeup, (caddr_t)&lm_sa,				    (klm_normal_timeout * hz));				error = sleep((caddr_t)&lm_sa,PZERO|PCATCH);				untimeout(wakeup, (caddr_t)&lm_sa);				if (error) {				    error = EINTR;				    goto out;				}				goto remaploop;	/* ask for port# again */	    			} /*switch*/		} /*for*/	/* loop until timeout, error, or completion */	} /*for*/		/* loop until signal or completion */out:	AUTH_DESTROY(client->cl_auth);	/* drop the authenticator */	CLNT_DESTROY(client);		/* drop the client handle */	return(error);}/* * Pass Record-locking requests to the local Lock-Manager daemon. * *	Note: this routine is called from ufs_rlock () as a result of an  *	      attempt to lock a local file AND * 			WHEN nfs is configured AND the daemon based *			region locking functionality  *			is enabled (kernel_locking = 0) */intklm_drlock(gp, ld, cmd, cred)	struct gnode *gp;	struct flock *ld;	int cmd;	struct ucred *cred;{	lockhandle_t lh;	fhandle_t    fh;	if(u.u_error = makefh(&fh, gp))		return;	lh.lh_id = fh;	lh.lh_gp = gp;	lh.lh_servername = hostname;	return (klm_lockctl(&lh, ld, cmd, cred)); }

⌨️ 快捷键说明

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