prot_proc.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 707 行 · 第 1/2 页

C
707
字号
# ifndef lintstatic char *sccsid = "@(#)prot_proc.c	4.2	(ULTRIX)	10/8/90";# endif not lint/**************************************************************** *								* *  Licensed to Digital Equipment Corporation, Maynard, MA	* *		Copyright 1985 Sun Microsystems, Inc.		* *			All rights reserved.			* *								* ****************************************************************//**//* *	Modification history: *	~~~~~~~~~~~~~~~~~~~~ * *	revision			comments *	--------	----------------------------------------------- * *	08-Sep-90	Fred Glover *			Modify remote_lock () to call remote_blocked () routine *			to ensure that client side fhandle comparisons are  *			performed using the 32 byte opaque fhandle definition. * *	01-Jun-89	Fred Glover *			Update to nfssrc 4.0 * *	09-28-88	Fred Glover *			Modify remote_test function to conform to  *			SunOS 4.0 * *	01-Mar-88	fglover *			Add support in cont_lock for remote deadlock  *				avoidance error response * *	16-Feb-88	fglover *			Add check for deadlock avoidance in local_lock (). * *	18-Jan-88	fries *			Added Header and Copyright notice. * *	 *//* prot_proc.c  * consists all local, remote, and continuation routines: * local_xxx, remote_xxx, and cont_xxx. */#include <stdio.h>#include <sys/file.h>#include "prot_lock.h"#define same_proc(x, y) (obj_cmp(&x->lck.oh, &y->lck.oh))remote_result nlm_result;		/* local nlm result */remote_result *nlm_resp = &nlm_result;	/* ptr to klm result */remote_result *remote_cancel(), *remote_lock(), *remote_test(), *remote_unlock();remote_result *local_test(), *local_lock(), *local_cancel(), *local_unlock();msg_entry *search_msg(), *retransmitted();char *xmalloc();struct fs_rlck *find_fe();reclock *search_lock(), *search_block_lock();extern int debug;extern int res_len;extern msg_entry *klm_msg;remote_result *local_lock(a)	reclock *a;{	struct fs_rlck *fp;	reclock *insrtp;	if (debug)		printf("enter local_lock\n");	if (blocked(&fp, &insrtp, a) == 1) {  /*blocked*/		if (a->lck.op & LOCK_NB) {			nlm_resp->lstat = denied;			a->rel = 1;		/* to release a */		}		else { 				/* add_wait */			/*			 *	Check for possible deadlock			 *	Ultrix mod - fsg			 */			if (would_deadlock (insrtp, a) == 1) {				nlm_resp->lstat = deadlocked;				a->rel = 1;			}			else {				/* 				 *	Store lock owner pid and				 *	add to wait queue				 */				a->lopid = insrtp->lck.svid;				add_wait(a);				nlm_resp->lstat = blocking;			}		}	}	else { /* not blocked*/		if (add_reclock(fp, insrtp, a) == -1) {			nlm_resp->lstat= nolocks;			a->rel = 1;		}		else 			nlm_resp->lstat = granted;	}	return(nlm_resp);}/* * note: due to the change in fhandle definition in ULTRIX V4.0 (export * extensions), ULTRIX fhandles may compare unequal, and yet still identify * the same NFS file.  On the server, the server lockd may "know" the format * and compare only those fields relevant to the comparison.  On the client, * however, the fhandle must be treated as completely opaque since the  * actual server may be other than ULTRIX.  thus, the remote_lock routine * now calls remote_blocked (rather than blocked), which calls remote_find_fe * (rather than find_fe), which calls remote_cmp_fh (rather than cmp_fh) to * do the proper fhandle comparison.  Note that the blocked check on the  * client is done as a performance enhancement: i.e. if the local lock daemon * has cached information indicating that a given file is already locked, * and the request is a non-blocking lock, then the local lockd returns a  * "lock request denied" response; otherwise, the server lockd is contacted, * and the (blocking lock) request is placed on the remote wait queue. *  * * remote_lock and local_lock have great similarities! * choice == RPC; rpc calls to remote; * choice == MSG; msg passing calls to remote; */remote_result *remote_lock(a, choice)	reclock *a;	int choice;{	struct fs_rlck *fp;	reclock *insrtp;	if (debug)		printf("enter remote_lock\n");	if (remote_blocked(&fp, &insrtp, a) == 1) { /*blocked*/		if (a->lck.op & LOCK_NB) {			nlm_resp->lstat = denied;			a->rel = 1;			return(nlm_resp);		}	}	/* blocked == 0 or blocked == 1 and blocking */	if ( insrtp != NULL && same_proc(insrtp, a) && same_op(insrtp, a) && inside(a, insrtp)) {		/*lock exists*/		a->rel = 1;				nlm_resp->lstat = granted;		return(nlm_resp);	}	else {		/* consult with svr lock manager*/		if (choice == MSG) { /* msg passing */			if (nlm_call(NLM_LOCK_MSG, a, 0) == -1)				a->rel = 1;		/* rpc error, discard */			return(NULL);			/* no reply available */		}		else { /*rpc*/			printf("rpc not supported\n");			a->rel = 1;			return(NULL);		}	}}remote_result *local_unlock(a)	reclock *a;{	struct fs_rlck *fp;	reclock *insrtp;	if (debug)		printf("enter local_unlock\n");	insrtp = NULL;	if ((fp = find_fe(a)) != NULL)			/*found*/		if (delete_reclock(fp, &insrtp, a) >0 )	/* more than one entry deleted */			(void) wakeup(a);	a->rel = 1;	nlm_resp->lstat = granted;	return(nlm_resp);}remote_result *remote_unlock(a, choice)	reclock *a;	int choice;{	if (debug)		printf("enter remote_unlock\n");	if ( find_fe(a) != NULL) {  /*found*/		if (choice == MSG) { 			if (nlm_call(NLM_UNLOCK_MSG, a, 0) == -1)				a->rel = 1;			return(NULL);			}		/* rpc case */		else {			printf("rpc not supported\n");			a->rel = 1;			return(NULL);		}	}	a->rel = 1;		/* not found */	nlm_resp->lstat = granted;	return(nlm_resp);}	remote_result *local_test(a)	reclock *a;{	struct fs_rlck *fp;	reclock *insrtp;	if (debug)		printf("enter local_test\n");	a->rel = 1;	if (blocked(&fp, &insrtp, a) == 0){ /* nonblocking */		nlm_resp->lstat = granted;		return(nlm_resp);	}	else{		nlm_resp->lstat = denied;		nlm_resp->lholder.svid = insrtp->lck.svid;		nlm_resp->lholder.l_offset = insrtp->lck.l_offset;		nlm_resp->lholder.l_len = insrtp->lck.l_len;		nlm_resp->lholder.exclusive = insrtp->exclusive;		(void) obj_copy( &nlm_resp->lholder.oh, &insrtp->lck.oh);		if (debug)			printf("lock blocked by %d, (%d, %d)\n",			nlm_resp->lholder.svid, nlm_resp->lholder.l_offset, nlm_resp->lholder.l_len );		return(nlm_resp);	}}remote_result *remote_test(a, choice)	reclock *a;	int choice;{	struct fs_rlck *fp;	reclock *insrtp;	if (debug)		printf("enter remote_test\n");	if (blocked(&fp, &insrtp, a) == 0) { /* nonblocking */		a->rel = 1;		nlm_resp->lstat = granted;		return(nlm_resp);	}	else {		if (choice == MSG) {			if (nlm_call(NLM_TEST_MSG, a, 0) == -1)				a->rel = 1;			return(NULL);		}		/* rpc case */		else {			printf("rpc not supported\n");			a->rel = 1;			return(NULL);		}	}}remote_result *local_cancel(a)	reclock *a;{	reclock *nl;	msg_entry *msgp;	if (debug)		printf("enter local_cancel(%x)\n", a);	a->rel = 1;	if ((nl = search_lock(a)) == NULL)	/* the use of grant is confusing here */		nlm_resp->lstat = denied;	else {		if (nl->w_flag == 0)			nlm_resp->lstat = granted;			else {			remove_wait(nl);			nl->rel = 1;			if (!remote_clnt(nl)) {				if ((msgp = retransmitted(nl, KLM_LOCK)) != NULL) {					if (debug)						printf(" local_cancel: dequeue(%x)\n", msgp->req);					dequeue(msgp);				}				else {					release_le(nl);				}			}			else				release_le(nl);			nlm_resp->lstat = denied;			}		}	return(nlm_resp);}remote_result *remote_cancel(a, choice)	reclock *a;	int choice;{	reclock *nl;	msg_entry *msgp;	if (debug)		printf("enter remote_cancel(%x)\n", a);	if ((nl = search_lock(a)) == NULL) {		if ((msgp = retransmitted(a, KLM_LOCK)) == NULL) {			/* msg was never received */			a->rel = 1;			nlm_resp->lstat = denied;			return(nlm_resp);		}		else { /* msg is being processed */			if (debug)				printf("remove msg(%x) due to remote cancel\n", msgp->req);			msgp->req->rel = 1;			if (a->pre_le != NULL || a->pre_fe != NULL) {				fprintf(stderr, "rpc.lockd: cancel request pre_le=%x pre_fe = %x\n", a->pre_le, a->pre_fe);			}			else { /* take over the pre_fe and pre_le */				a->pre_le = msgp->req->pre_le;				a->pre_fe = msgp->req->pre_fe;				msgp->req->pre_le = NULL;				msgp->req->pre_fe = NULL;			}			dequeue(msgp);		}	}	else {

⌨️ 快捷键说明

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