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 + -
显示快捷键?