📄 klm_lockmgr.c
字号:
#ifndef lintstatic char *sccsid = "@(#)klm_lockmgr.c 4.2 10/8/90";#endif lint/************************************************************************ * * * Copyright (c) 1986 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 * * * 08-Sep-90 Fred Glover * Transfer complete fhandle definition into lockhandle construction * in klm_drlock () * * 08-Aug-89 Fred Glover * Reduce remapping calls due to RPC timeouts based upon excessive * time to process multiple lock request to same file * * 01-Jun-89 Fred Glover * Update for nfssrc 4.0 data structure changes in klm_prot.h * * 09-Oct-88 condylis * Added SMP locking for locking transaction id * * 28-09-88 Fred Glover * Add transction id code for kernel/lockd communication * * 10-Jun-88 -- jaw * add parameter to ISSIG for SMP.... this makes going to stop * state atomic. * * 19-01-88 Fred Glover * Add klm_drlock function to support * ufs region locking when daemon based * locking is enabled. *//* * Kernel<->Network Lock-Manager Interface * * File- and Record-locking requests are forwarded (via RPC) to a * Network Lock-Manager running on the local machine. The protocol * for these transactions is defined in /usr/src/protocols/klm_prot.x */#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/socket.h"#include "../h/socketvar.h"#include "../h/proc.h"#include "../h/file.h"#include "../h/stat.h"/* files included by <rpc/rpc.h> */#include "../rpc/types.h"#include "../netinet/in.h"#include "../rpc/xdr.h"#include "../rpc/auth.h"#include "../rpc/clnt.h"#include "../rpcsvc/klm_prot.h"#include "../net/if.h"#include "../fs/nfs/nfs.h"#include "../fs/nfs/nfs_clnt.h"#include "../h/mount.h"#include "../fs/nfs/vfs.h"#include "../fs/nfs/vnode.h"#include "../rpc/lockmgr.h"/* @JAA this is from sun netinet/in.h */#define INADDR_LOOPBACK 0x7f000001static struct sockaddr_in lm_sa; /* talk to portmapper & lock-manager */static talk_to_lockmgr();extern int wakeup();/* SMP lock for accessing client handle xid */extern struct lock_t lk_rpcxid;int klm_debug = 0;/* * Define parameters for run-time tuning: * * Note that the policy for retries and timeouts has been modified * and no longer matches the NFSSRC 4.0 reference code. The modifications * were made to resolve the V3.1 ULTRIX CLD associated with local * lock daemon wakeups: i.e. the lock daemon cannot wake up * a process which has been blocked waiting for a lock to be * released; a kernel "retry" must take place. Thus, the retry * mechanism must retry frequently enough to be responsive in this * case, yet not result in excessive overhead. This code was modified * such that: * a) the process sleeps for klm_working_timeout seconds * b) each retry uses a new RPC transaction number * c) the general backoff algorithm in callit is avoided, * which resulted in long delays once a process was * blocked waiting for a lock * * The basic strategy is to avoid the remap loop when the lock daemon * is present, and to avoid the backoff as long as communcation * with the lock daemon is in progress */int klm_backoff_timeout = 10; /* time to wait on klm_denied_nolocks */int klm_first_retry = 1; /* first attempt if klm port# known */int klm_first_timeout = 1;int klm_normal_timeout = 1;int klm_working_retry = 1; /* attempts after klm_working */int klm_working_timeout = 1;int klm_remap_retry = 1;int klm_timeout_retry = 20;int klm_reqs=0;int klm_succ_out=0;int klm_succ_work=0;int klm_to=0;int klm_other=0;/* Define lock mgr/Kernel transaction id variable */int lm_xid=0;/* * klm_lockctl - process a lock/unlock/test-lock request * * Calls (via RPC) the local lock manager to register the request. * Lock requests are cancelled if interrupted by signals. */klm_lockctl(lh, ld, cmd, cred) register lockhandle_t *lh; register struct flock *ld; int cmd; struct ucred *cred;{ register int error; klm_lockargs args; klm_testrply reply; u_long xdrproc; xdrproc_t xdrargs; xdrproc_t xdrreply; extern struct timeval time; klm_reqs++; /* initialize sockaddr_in used to talk to local processes */ if (lm_sa.sin_port == 0) {#ifdef notdef struct ifnet *ifp; if ((ifp = if_ifwithafup(AF_INET)) == (struct ifnet *)NULL) { panic("klm_lockctl: no inet address"); } lm_sa = *(struct sockaddr_in *) &(ifp->if_addr);#else lm_sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); lm_sa.sin_family = AF_INET;#endif } args.block = FALSE; args.exclusive = FALSE; args.alock.fh.n_bytes = (char *)&lh->lh_id; args.alock.fh.n_len = sizeof (lh->lh_id); args.alock.server_name = lh->lh_servername; args.alock.pid = (int)u.u_procp->p_pid; args.alock.l_offset = ld->l_start; args.alock.l_len = ld->l_len; xdrproc = KLM_LOCK; xdrargs = (xdrproc_t)xdr_klm_lockargs; xdrreply = (xdrproc_t)xdr_klm_stat; /* now modify the lock argument structure for specific cases */ switch (ld->l_type) { case F_WRLCK: args.exclusive = TRUE; break; case F_UNLCK: xdrproc = KLM_UNLOCK; xdrargs = (xdrproc_t)xdr_klm_unlockargs; break; } switch (cmd) { case F_SETLKW: args.block = TRUE; break; case F_GETLK: xdrproc = KLM_TEST; xdrargs = (xdrproc_t)xdr_klm_testargs; xdrreply = (xdrproc_t)xdr_klm_testrply; break; }requestloop: if (klm_debug) { printf("reqlp: pid:%d proc:%d %d %d\n", args.alock.pid, (int) xdrproc, time.tv_sec, lm_xid); } /* send the request out to the local lock-manager and wait for reply */ error = talk_to_lockmgr(xdrproc, xdrargs, &args, xdrreply, &reply, cred); if (error == ENOLCK) { goto ereturn; /* no way the request could have gotten out */ } /* * The only other possible return values are: * klm_granted | klm_denied | klm_denied_nolocks | EINTR | * klm_would_deadlock */ switch (xdrproc) { case KLM_LOCK: switch (error) { case klm_granted: error = 0; /* got the requested lock */ goto ereturn; case klm_denied: if (args.block) { goto requestloop; /* loop forever */ } error = EACCES; /* EAGAIN?? */ goto ereturn; case klm_denied_nolocks: error = ENOLCK; /* no resources available?! */ goto ereturn; case EINTR: if (args.block) goto cancel; /* cancel blocking locks */ else goto requestloop; /* loop forever */ case klm_would_deadlock: error = EDEADLK; /* blocking would result in */ goto ereturn; /* deadlock condition */ } case KLM_UNLOCK: switch (error) { case klm_granted: error = 0; goto ereturn; case klm_denied: error = EINVAL; goto ereturn; case klm_denied_nolocks: goto nolocks_wait; /* back off; loop forever */ case EINTR: goto requestloop; /* loop forever */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -