2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
12 * Exported routines (and their private support) to implement
13 * the callback RPC interface.
16 #include <afsconfig.h>
17 #include "afs/param.h"
20 #include "afs/sysincludes.h" /*Standard vendor system headers */
21 #include "afsincludes.h" /*AFS-based standard headers */
22 #include "afs/afs_stats.h" /*Cache Manager stats */
23 #include "afs/afs_args.h"
25 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
26 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs */
27 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files */
28 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
29 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted */
30 afs_int32 afs_evenZaps = 0; /*File cache entries deleted */
31 afs_int32 afs_connectBacks = 0;
34 * Some debugging aids.
36 static struct ltable {
41 "afs_xvcache", (char *)&afs_xvcache}, {
42 "afs_xdcache", (char *)&afs_xdcache}, {
43 "afs_xserver", (char *)&afs_xserver}, {
44 "afs_xvcb", (char *)&afs_xvcb}, {
45 "afs_xbrs", (char *)&afs_xbrs}, {
46 "afs_xcell", (char *)&afs_xcell}, {
47 "afs_xconn", (char *)&afs_xconn}, {
48 "afs_xuser", (char *)&afs_xuser}, {
49 "afs_xvolume", (char *)&afs_xvolume}, {
50 "puttofile", (char *)&afs_puttofileLock}, {
51 "afs_ftf", (char *)&afs_ftf}, {
52 "afs_xcbhash", (char *)&afs_xcbhash}, {
53 "afs_xaxs", (char *)&afs_xaxs}, {
54 "afs_xinterface", (char *)&afs_xinterface},
57 "afs_xosi", (char *)&afs_xosi},
60 "afs_xsrvAddr", (char *)&afs_xsrvAddr},
62 "afs_xvreclaim", (char *)&afs_xvreclaim},
63 { "afsdb_client_lock", (char *)&afsdb_client_lock},
64 { "afsdb_req_lock", (char *)&afsdb_req_lock},
66 { "afs_discon_lock", (char *)&afs_discon_lock},
67 { "afs_disconDirtyLock", (char *)&afs_disconDirtyLock},
68 { "afs_discon_vc_dirty", (char *)&afs_xvcdirty},
71 unsigned long lastCallBack_vnode;
72 unsigned int lastCallBack_dv;
73 osi_timeval_t lastCallBack_time;
75 /* these are for storing alternate interface addresses */
76 struct interfaceAddr afs_cb_interface;
78 /*------------------------------------------------------------------------
79 * EXPORTED SRXAFSCB_GetCE
82 * Routine called by the server-side callback RPC interface to
83 * implement pulling out the contents of the i'th cache entry.
86 * a_call : Ptr to Rx call on which this request came in.
87 * a_index : Index of desired cache entry.
88 * a_result : Ptr to a buffer for the given cache entry.
91 * 0 if everything went fine,
92 * 1 if we were given a bad index.
95 * Nothing interesting.
99 *------------------------------------------------------------------------*/
102 SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
103 struct AFSDBCacheEntry *a_result)
106 register int i; /*Loop variable */
107 register struct vcache *tvc; /*Ptr to current cache entry */
108 int code; /*Return code */
113 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
115 AFS_STATCNT(SRXAFSCB_GetCE);
116 for (i = 0; i < VCSIZE; i++) {
117 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
121 } /*Zip through current hash chain */
122 } /*Zip through hash chains */
132 * Copy out the located entry.
134 a_result->addr = afs_data_pointer_to_int32(tvc);
135 a_result->cell = tvc->f.fid.Cell;
136 a_result->netFid.Volume = tvc->f.fid.Fid.Volume;
137 a_result->netFid.Vnode = tvc->f.fid.Fid.Vnode;
138 a_result->netFid.Unique = tvc->f.fid.Fid.Unique;
139 a_result->lock.waitStates = tvc->lock.wait_states;
140 a_result->lock.exclLocked = tvc->lock.excl_locked;
141 a_result->lock.readersReading = tvc->lock.readers_reading;
142 a_result->lock.numWaiting = tvc->lock.num_waiting;
143 #if defined(INSTRUMENT_LOCKS)
144 a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
145 a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
146 a_result->lock.src_indicator = tvc->lock.src_indicator;
148 /* On osf20 , the vcache does not maintain these three fields */
149 a_result->lock.pid_last_reader = 0;
150 a_result->lock.pid_writer = 0;
151 a_result->lock.src_indicator = 0;
152 #endif /* INSTRUMENT_LOCKS */
153 #ifdef AFS_64BIT_CLIENT
154 a_result->Length = (afs_int32) tvc->f.m.Length & 0xffffffff;
155 #else /* AFS_64BIT_CLIENT */
156 a_result->Length = tvc->f.m.Length;
157 #endif /* AFS_64BIT_CLIENT */
158 a_result->DataVersion = hgetlo(tvc->f.m.DataVersion);
159 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
160 a_result->cbExpires = tvc->cbExpires;
161 if (tvc->f.states & CVInit) {
162 a_result->refCount = 1;
164 #ifdef AFS_DARWIN80_ENV
165 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
167 a_result->refCount = VREFCOUNT(tvc);
170 a_result->opens = tvc->opens;
171 a_result->writers = tvc->execsOrWriters;
172 a_result->mvstat = tvc->mvstat;
173 a_result->states = tvc->f.states;
177 * Return our results.
186 } /*SRXAFSCB_GetCE */
189 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
190 struct AFSDBCacheEntry64 *a_result)
192 register int i; /*Loop variable */
193 register struct vcache *tvc; /*Ptr to current cache entry */
194 int code; /*Return code */
199 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
201 AFS_STATCNT(SRXAFSCB_GetCE64);
202 for (i = 0; i < VCSIZE; i++) {
203 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
207 } /*Zip through current hash chain */
208 } /*Zip through hash chains */
218 * Copy out the located entry.
220 a_result->addr = afs_data_pointer_to_int32(tvc);
221 a_result->cell = tvc->f.fid.Cell;
222 a_result->netFid.Volume = tvc->f.fid.Fid.Volume;
223 a_result->netFid.Vnode = tvc->f.fid.Fid.Vnode;
224 a_result->netFid.Unique = tvc->f.fid.Fid.Unique;
225 a_result->lock.waitStates = tvc->lock.wait_states;
226 a_result->lock.exclLocked = tvc->lock.excl_locked;
227 a_result->lock.readersReading = tvc->lock.readers_reading;
228 a_result->lock.numWaiting = tvc->lock.num_waiting;
229 #if defined(INSTRUMENT_LOCKS)
230 a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
231 a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
232 a_result->lock.src_indicator = tvc->lock.src_indicator;
234 /* On osf20 , the vcache does not maintain these three fields */
235 a_result->lock.pid_last_reader = 0;
236 a_result->lock.pid_writer = 0;
237 a_result->lock.src_indicator = 0;
238 #endif /* INSTRUMENT_LOCKS */
239 #if !defined(AFS_64BIT_ENV)
240 a_result->Length.high = 0;
241 a_result->Length.low = tvc->f.m.Length;
243 a_result->Length = tvc->f.m.Length;
245 a_result->DataVersion = hgetlo(tvc->f.m.DataVersion);
246 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
247 a_result->cbExpires = tvc->cbExpires;
248 if (tvc->f.states & CVInit) {
249 a_result->refCount = 1;
251 #ifdef AFS_DARWIN80_ENV
252 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
254 a_result->refCount = VREFCOUNT(tvc);
257 a_result->opens = tvc->opens;
258 a_result->writers = tvc->execsOrWriters;
259 a_result->mvstat = tvc->mvstat;
260 a_result->states = tvc->f.states;
264 * Return our results.
273 } /*SRXAFSCB_GetCE64 */
276 /*------------------------------------------------------------------------
277 * EXPORTED SRXAFSCB_GetLock
280 * Routine called by the server-side callback RPC interface to
281 * implement pulling out the contents of a lock in the lock
285 * a_call : Ptr to Rx call on which this request came in.
286 * a_index : Index of desired lock.
287 * a_result : Ptr to a buffer for the given lock.
290 * 0 if everything went fine,
291 * 1 if we were given a bad index.
294 * Nothing interesting.
298 *------------------------------------------------------------------------*/
301 SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
302 struct AFSDBLock *a_result)
304 struct ltable *tl; /*Ptr to lock table entry */
305 int nentries; /*Num entries in table */
306 int code; /*Return code */
311 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
313 AFS_STATCNT(SRXAFSCB_GetLock);
314 nentries = sizeof(ltable) / sizeof(struct ltable);
315 if (a_index < 0 || a_index >= nentries+afs_cellindex) {
320 } else if (a_index >= nentries) {
321 struct cell *tc = afs_GetCellByIndex(a_index-nentries, 0);
322 strcpy(a_result->name, tc->cellName);
323 a_result->lock.waitStates =
324 ((struct afs_lock *)&(tc->lock))->wait_states;
325 a_result->lock.exclLocked =
326 ((struct afs_lock *)&(tc->lock))->excl_locked;
327 a_result->lock.readersReading =
328 ((struct afs_lock *)&(tc->lock))->readers_reading;
329 a_result->lock.numWaiting =
330 ((struct afs_lock *)&(tc->lock))->num_waiting;
331 #ifdef INSTRUMENT_LOCKS
332 a_result->lock.pid_last_reader =
333 MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_last_reader);
334 a_result->lock.pid_writer =
335 MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_writer);
336 a_result->lock.src_indicator =
337 ((struct afs_lock *)&(tc->lock))->src_indicator;
339 a_result->lock.pid_last_reader = 0;
340 a_result->lock.pid_writer = 0;
341 a_result->lock.src_indicator = 0;
346 * Found it - copy out its contents.
348 tl = <able[a_index];
349 strcpy(a_result->name, tl->name);
350 a_result->lock.waitStates =
351 ((struct afs_lock *)(tl->addr))->wait_states;
352 a_result->lock.exclLocked =
353 ((struct afs_lock *)(tl->addr))->excl_locked;
354 a_result->lock.readersReading =
355 ((struct afs_lock *)(tl->addr))->readers_reading;
356 a_result->lock.numWaiting =
357 ((struct afs_lock *)(tl->addr))->num_waiting;
358 #ifdef INSTRUMENT_LOCKS
359 a_result->lock.pid_last_reader =
360 MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_last_reader);
361 a_result->lock.pid_writer =
362 MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_writer);
363 a_result->lock.src_indicator =
364 ((struct afs_lock *)(tl->addr))->src_indicator;
366 a_result->lock.pid_last_reader = 0;
367 a_result->lock.pid_writer = 0;
368 a_result->lock.src_indicator = 0;
379 } /*SRXAFSCB_GetLock */
382 /*------------------------------------------------------------------------
383 * static ClearCallBack
386 * Clear out callback information for the specified file, or
387 * even a whole volume. Used to worry about callback was from
388 * within the particular cell or not. Now we don't bother with
389 * that anymore; it's not worth the time.
392 * a_conn : Ptr to Rx connection involved.
393 * a_fid : Ptr to AFS fid being cleared.
399 * Nothing interesting.
404 Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
406 *------------------------------------------------------------------------*/
409 ClearCallBack(register struct rx_connection *a_conn,
410 register struct AFSFid *a_fid)
412 register struct vcache *tvc;
414 struct VenusFid localFid;
416 #ifdef AFS_DARWIN80_ENV
420 AFS_STATCNT(ClearCallBack);
425 * XXXX Don't hold any server locks here because of callback protocol XXX
428 localFid.Fid.Volume = a_fid->Volume;
429 localFid.Fid.Vnode = a_fid->Vnode;
430 localFid.Fid.Unique = a_fid->Unique;
433 * Volume ID of zero means don't do anything.
435 if (a_fid->Volume != 0) {
436 if (a_fid->Vnode == 0) {
437 struct afs_q *tq, *uq;
439 * Clear callback for the whole volume. Zip through the
440 * hash chain, nullifying entries whose volume ID matches.
443 ObtainReadLock(&afs_xvcache);
444 i = VCHashV(&localFid);
445 for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) {
448 if (tvc->f.fid.Fid.Volume == a_fid->Volume) {
449 tvc->callback = NULL;
451 localFid.Cell = tvc->f.fid.Cell;
452 tvc->dchint = NULL; /* invalidate hints */
453 if (tvc->f.states & CVInit) {
454 ReleaseReadLock(&afs_xvcache);
455 afs_osi_Sleep(&tvc->f.states);
458 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
459 VN_HOLD(AFSTOV(tvc));
461 #ifdef AFS_DARWIN80_ENV
462 if (tvc->f.states & CDeadVnode) {
463 if (!(tvc->f.states & CBulkFetching)) {
464 ReleaseReadLock(&afs_xvcache);
465 afs_osi_Sleep(&tvc->f.states);
478 if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
480 vnode_recycle(AFSTOV(tvc));
484 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
487 VREFCOUNT_INC(tvc); /* AIX, apparently */
491 ReleaseReadLock(&afs_xvcache);
492 ObtainWriteLock(&afs_xcbhash, 449);
493 afs_DequeueCallback(tvc);
494 tvc->f.states &= ~(CStatd | CUnique | CBulkFetching);
496 if (tvc->f.fid.Fid.Vnode & 1)
500 ReleaseWriteLock(&afs_xcbhash);
501 if ((tvc->f.fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)))
502 osi_dnlc_purgedp(tvc);
503 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
504 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
505 tvc->f.states, ICL_TYPE_INT32,
507 #ifdef AFS_DARWIN80_ENV
508 vnode_put(AFSTOV(tvc));
510 ObtainReadLock(&afs_xvcache);
513 } else if ((tvc->f.states & CMValid)
514 && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
515 tvc->f.states &= ~CMValid;
517 localFid.Cell = tvc->mvid->Cell;
520 ReleaseReadLock(&afs_xvcache);
523 * XXXX Don't hold any locks here XXXX
525 tv = afs_FindVolume(&localFid, 0);
527 afs_ResetVolumeInfo(tv);
528 afs_PutVolume(tv, 0);
529 /* invalidate mtpoint? */
531 } /*Clear callbacks for whole volume */
534 * Clear callbacks just for the one file.
538 if (a_fid->Vnode & 1)
539 afs_oddCBs++; /*Could do this on volume basis, too */
541 afs_evenCBs++; /*A particular fid was specified */
543 ObtainReadLock(&afs_xvcache);
544 i = VCHash(&localFid);
545 for (tvc = afs_vhashT[i]; tvc; tvc = uvc) {
547 if (tvc->f.fid.Fid.Vnode == a_fid->Vnode
548 && tvc->f.fid.Fid.Volume == a_fid->Volume
549 && tvc->f.fid.Fid.Unique == a_fid->Unique) {
550 tvc->callback = NULL;
551 tvc->dchint = NULL; /* invalidate hints */
552 if (tvc->f.states & CVInit) {
553 ReleaseReadLock(&afs_xvcache);
554 afs_osi_Sleep(&tvc->f.states);
557 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
558 VN_HOLD(AFSTOV(tvc));
560 #ifdef AFS_DARWIN80_ENV
561 if (tvc->f.states & CDeadVnode) {
562 if (!(tvc->f.states & CBulkFetching)) {
563 ReleaseReadLock(&afs_xvcache);
564 afs_osi_Sleep(&tvc->f.states);
577 if (tvc->f.states & (CBulkFetching|CDeadVnode)) {
579 vnode_recycle(AFSTOV(tvc));
583 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
586 VREFCOUNT_INC(tvc); /* AIX, apparently */
590 ReleaseReadLock(&afs_xvcache);
591 ObtainWriteLock(&afs_xcbhash, 450);
592 afs_DequeueCallback(tvc);
593 tvc->f.states &= ~(CStatd | CUnique | CBulkFetching);
594 ReleaseWriteLock(&afs_xcbhash);
595 if ((tvc->f.fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)))
596 osi_dnlc_purgedp(tvc);
597 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
598 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
599 tvc->f.states, ICL_TYPE_LONG, 0);
601 lastCallBack_vnode = afid->Vnode;
602 lastCallBack_dv = tvc->mstat.DataVersion.low;
603 osi_GetuTime(&lastCallBack_time);
605 #ifdef AFS_DARWIN80_ENV
606 vnode_put(AFSTOV(tvc));
608 ObtainReadLock(&afs_xvcache);
612 } /*Walk through hash table */
613 ReleaseReadLock(&afs_xvcache);
614 } /*Clear callbacks for one file */
617 /*Fid has non-zero volume ID */
619 * Always return a predictable value.
626 /*------------------------------------------------------------------------
627 * EXPORTED SRXAFSCB_CallBack
630 * Routine called by the server-side callback RPC interface to
631 * implement passing in callback information.
635 * a_call : Ptr to Rx call on which this request came in.
636 * a_fids : Ptr to array of fids involved.
637 * a_callbacks : Ptr to matching callback info for the fids.
643 * Nothing interesting.
647 *------------------------------------------------------------------------*/
650 SRXAFSCB_CallBack(struct rx_call *a_call, register struct AFSCBFids *a_fids,
651 struct AFSCBs *a_callbacks)
653 register int i; /*Loop variable */
654 struct AFSFid *tfid; /*Ptr to current fid */
655 register struct rx_connection *tconn; /*Call's connection */
661 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
663 AFS_STATCNT(SRXAFSCB_CallBack);
664 if (!(tconn = rx_ConnectionOf(a_call)))
666 tfid = (struct AFSFid *)a_fids->AFSCBFids_val;
669 * For now, we ignore callbacks, since the File Server only *breaks*
670 * callbacks at present.
672 for (i = 0; i < a_fids->AFSCBFids_len; i++)
673 ClearCallBack(tconn, &tfid[i]);
681 } /*SRXAFSCB_CallBack */
684 /*------------------------------------------------------------------------
685 * EXPORTED SRXAFSCB_Probe
688 * Routine called by the server-side callback RPC interface to
689 * implement ``probing'' the Cache Manager, just making sure it's
693 * a_call : Ptr to Rx call on which this request came in.
699 * Nothing interesting.
703 *------------------------------------------------------------------------*/
706 SRXAFSCB_Probe(struct rx_call *a_call)
712 AFS_STATCNT(SRXAFSCB_Probe);
714 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
721 } /*SRXAFSCB_Probe */
724 /*------------------------------------------------------------------------
725 * EXPORTED SRXAFSCB_InitCallBackState
728 * Routine called by the server-side callback RPC interface to
729 * implement clearing all callbacks from this host.
732 * a_call : Ptr to Rx call on which this request came in.
738 * Nothing interesting.
742 *------------------------------------------------------------------------*/
745 SRXAFSCB_InitCallBackState(struct rx_call *a_call)
748 register struct vcache *tvc;
749 register struct rx_connection *tconn;
750 register struct rx_peer *peer;
757 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
758 AFS_STATCNT(SRXAFSCB_InitCallBackState);
761 * Find the address of the host making this call
763 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
766 afs_oddCBs++; /*Including any missed via create race */
767 afs_evenCBs++; /*Including any missed via create race */
769 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *) 0,
772 for (i = 0; i < VCSIZE; i++)
773 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
774 if (tvc->callback == ts) {
775 ObtainWriteLock(&afs_xcbhash, 451);
776 afs_DequeueCallback(tvc);
777 tvc->callback = NULL;
778 tvc->f.states &= ~(CStatd | CUnique | CBulkFetching);
779 ReleaseWriteLock(&afs_xcbhash);
786 /* find any volumes residing on this server and flush their state */
788 register struct volume *tv;
791 for (i = 0; i < NVOLS; i++)
792 for (tv = afs_volumes[i]; tv; tv = tv->next) {
793 for (j = 0; j < AFS_MAXHOSTS; j++)
794 if (tv->serverHost[j] == ts)
795 afs_ResetVolumeInfo(tv);
798 osi_dnlc_purge(); /* may be a little bit extreme */
807 } /*SRXAFSCB_InitCallBackState */
810 /*------------------------------------------------------------------------
811 * EXPORTED SRXAFSCB_XStatsVersion
814 * Routine called by the server-side callback RPC interface to
815 * implement pulling out the xstat version number for the Cache
819 * a_versionP : Ptr to the version number variable to set.
825 * Nothing interesting.
829 *------------------------------------------------------------------------*/
832 SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 * a_versionP)
839 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
841 *a_versionP = AFSCB_XSTAT_VERSION;
848 } /*SRXAFSCB_XStatsVersion */
851 /*------------------------------------------------------------------------
852 * EXPORTED SRXAFSCB_GetXStats
855 * Routine called by the server-side callback RPC interface to
856 * implement getting the given data collection from the extended
857 * Cache Manager statistics.
860 * a_call : Ptr to Rx call on which this request came in.
861 * a_clientVersionNum : Client version number.
862 * a_opCode : Desired operation.
863 * a_serverVersionNumP : Ptr to version number to set.
864 * a_timeP : Ptr to time value (seconds) to set.
865 * a_dataArray : Ptr to variable array structure to return
872 * Nothing interesting.
876 *------------------------------------------------------------------------*/
879 SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
880 afs_int32 a_collectionNumber, afs_int32 * a_srvVersionNumP,
881 afs_int32 * a_timeP, AFSCB_CollData * a_dataP)
883 register int code; /*Return value */
884 afs_int32 *dataBuffP; /*Ptr to data to be returned */
885 afs_int32 dataBytes; /*Bytes in data buffer */
890 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
893 * Record the time of day and the server version number.
895 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
896 *a_timeP = osi_Time();
899 * Stuff the appropriate data in there (assume victory)
905 * We're not keeping stats, so just return successfully with
908 a_dataP->AFSCB_CollData_len = 0;
909 a_dataP->AFSCB_CollData_val = NULL;
911 switch (a_collectionNumber) {
912 case AFSCB_XSTATSCOLL_CALL_INFO:
914 * Pass back all the call-count-related data.
916 * >>> We are forced to allocate a separate area in which to
917 * >>> put this stuff in by the RPC stub generator, since it
918 * >>> will be freed at the tail end of the server stub code.
920 dataBytes = sizeof(struct afs_CMStats);
921 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
922 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
923 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
924 a_dataP->AFSCB_CollData_val = dataBuffP;
927 case AFSCB_XSTATSCOLL_PERF_INFO:
929 * Update and then pass back all the performance-related data.
930 * Note: the only performance fields that need to be computed
931 * at this time are the number of accesses for this collection
932 * and the current server record info.
934 * >>> We are forced to allocate a separate area in which to
935 * >>> put this stuff in by the RPC stub generator, since it
936 * >>> will be freed at the tail end of the server stub code.
938 afs_stats_cmperf.numPerfCalls++;
940 dataBytes = sizeof(afs_stats_cmperf);
941 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
942 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
943 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
944 a_dataP->AFSCB_CollData_val = dataBuffP;
947 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
949 * Pass back the full range of performance and statistical
950 * data available. We have to bring the normal performance
951 * data collection up to date, then copy that data into
952 * the full collection.
954 * >>> We are forced to allocate a separate area in which to
955 * >>> put this stuff in by the RPC stub generator, since it
956 * >>> will be freed at the tail end of the server stub code.
958 afs_stats_cmperf.numPerfCalls++;
960 memcpy((char *)(&(afs_stats_cmfullperf.perf)),
961 (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
962 afs_stats_cmfullperf.numFullPerfCalls++;
964 dataBytes = sizeof(afs_stats_cmfullperf);
965 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
966 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
967 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
968 a_dataP->AFSCB_CollData_val = dataBuffP;
973 * Illegal collection number.
975 a_dataP->AFSCB_CollData_len = 0;
976 a_dataP->AFSCB_CollData_val = NULL;
978 } /*Switch on collection number */
979 #endif /* AFS_NOSTATS */
987 } /*SRXAFSCB_GetXStats */
990 /*------------------------------------------------------------------------
991 * EXPORTED afs_RXCallBackServer
994 * Body of the thread supporting callback services.
1003 * Nothing interesting.
1007 *------------------------------------------------------------------------*/
1010 afs_RXCallBackServer(void)
1012 AFS_STATCNT(afs_RXCallBackServer);
1017 afs_osi_Sleep(&afs_server);
1021 * Donate this process to Rx.
1023 rx_ServerProc(NULL);
1026 } /*afs_RXCallBackServer */
1029 /*------------------------------------------------------------------------
1030 * EXPORTED shutdown_CB
1033 * Zero out important Cache Manager data structures.
1042 * Nothing interesting.
1046 *------------------------------------------------------------------------*/
1051 AFS_STATCNT(shutdown_CB);
1053 if (afs_cold_shutdown) {
1054 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps =
1055 afs_evenZaps = afs_connectBacks = 0;
1062 /*------------------------------------------------------------------------
1063 * EXPORTED SRXAFSCB_InitCallBackState2
1066 * This routine was used in the AFS 3.5 beta release, but not anymore.
1067 * It has since been replaced by SRXAFSCB_InitCallBackState3.
1070 * a_call : Ptr to Rx call on which this request came in.
1073 * RXGEN_OPCODE (always).
1076 * Nothing interesting.
1080 *------------------------------------------------------------------------*/
1083 SRXAFSCB_InitCallBackState2(struct rx_call *a_call,
1084 struct interfaceAddr *addr)
1086 return RXGEN_OPCODE;
1089 /*------------------------------------------------------------------------
1090 * EXPORTED SRXAFSCB_WhoAreYou
1093 * Routine called by the server-side callback RPC interface to
1094 * obtain a unique identifier for the client. The server uses
1095 * this identifier to figure out whether or not two RX connections
1096 * are from the same client, and to find out which addresses go
1097 * with which clients.
1100 * a_call : Ptr to Rx call on which this request came in.
1101 * addr: Ptr to return the list of interfaces for this client.
1107 * Nothing interesting.
1111 *------------------------------------------------------------------------*/
1114 SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
1121 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1123 memset(addr, 0, sizeof(*addr));
1125 ObtainReadLock(&afs_xinterface);
1127 /* return all network interface addresses */
1128 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1129 addr->uuid = afs_cb_interface.uuid;
1130 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1131 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1132 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1133 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1136 ReleaseReadLock(&afs_xinterface);
1144 /*------------------------------------------------------------------------
1145 * EXPORTED SRXAFSCB_InitCallBackState3
1148 * Routine called by the server-side callback RPC interface to
1149 * implement clearing all callbacks from this host.
1152 * a_call : Ptr to Rx call on which this request came in.
1158 * Nothing interesting.
1162 *------------------------------------------------------------------------*/
1165 SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID * a_uuid)
1170 * TBD: Lookup the server by the UUID instead of its IP address.
1172 code = SRXAFSCB_InitCallBackState(a_call);
1178 /*------------------------------------------------------------------------
1179 * EXPORTED SRXAFSCB_ProbeUuid
1182 * Routine called by the server-side callback RPC interface to
1183 * implement ``probing'' the Cache Manager, just making sure it's
1184 * still there is still the same client it used to be.
1187 * a_call : Ptr to Rx call on which this request came in.
1188 * a_uuid : Ptr to UUID that must match the client's UUID.
1191 * 0 if a_uuid matches the UUID for this client
1192 * Non-zero otherwize
1195 * Nothing interesting.
1199 *------------------------------------------------------------------------*/
1202 SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID * a_uuid)
1208 AFS_STATCNT(SRXAFSCB_Probe);
1210 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1211 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1212 code = 1; /* failure */
1221 /*------------------------------------------------------------------------
1222 * EXPORTED SRXAFSCB_GetServerPrefs
1225 * Routine to list server preferences used by this client.
1228 * a_call : Ptr to Rx call on which this request came in.
1229 * a_index : Input server index
1230 * a_srvr_addr : Output server address in host byte order
1231 * (0xffffffff on last server)
1232 * a_srvr_rank : Output server rank
1238 * Nothing interesting.
1242 *------------------------------------------------------------------------*/
1245 SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1246 afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
1252 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1254 ObtainReadLock(&afs_xserver);
1256 /* Search the hash table for the server with this index */
1257 *a_srvr_addr = 0xffffffff;
1258 *a_srvr_rank = 0xffffffff;
1259 for (i = 0, j = 0; j < NSERVERS && i <= a_index; j++) {
1260 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1262 *a_srvr_addr = ntohl(sa->sa_ip);
1263 *a_srvr_rank = sa->sa_iprank;
1268 ReleaseReadLock(&afs_xserver);
1276 /*------------------------------------------------------------------------
1277 * EXPORTED SRXAFSCB_GetCellServDB
1280 * Routine to list cells configured for this client
1283 * a_call : Ptr to Rx call on which this request came in.
1284 * a_index : Input cell index
1285 * a_name : Output cell name ("" on last cell)
1286 * a_hosts : Output cell database servers in host byte order.
1292 * Nothing interesting.
1296 *------------------------------------------------------------------------*/
1299 SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1300 char **a_name, serverList * a_hosts)
1304 char *t_name, *p_name = NULL;
1307 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1309 tcell = afs_GetCellByIndex(a_index, READ_LOCK);
1313 a_hosts->serverList_val = 0;
1314 a_hosts->serverList_len = 0;
1316 p_name = tcell->cellName;
1317 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
1319 a_hosts->serverList_val =
1320 (afs_int32 *) afs_osi_Alloc(j * sizeof(afs_int32));
1321 a_hosts->serverList_len = j;
1322 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++)
1323 a_hosts->serverList_val[j] =
1324 ntohl(tcell->cellHosts[j]->addr->sa_ip);
1325 afs_PutCell(tcell, READ_LOCK);
1328 t_name = (char *)afs_osi_Alloc(i + 1);
1329 if (t_name == NULL) {
1330 afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
1337 memcpy(t_name, p_name, i);
1346 /*------------------------------------------------------------------------
1347 * EXPORTED SRXAFSCB_GetLocalCell
1350 * Routine to return name of client's local cell
1353 * a_call : Ptr to Rx call on which this request came in.
1354 * a_name : Output cell name
1360 * Nothing interesting.
1364 *------------------------------------------------------------------------*/
1367 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1371 char *t_name, *p_name = NULL;
1374 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1376 /* Search the list for the primary cell. Cell number 1 is only
1377 * the primary cell is when no other cell is explicitly marked as
1378 * the primary cell. */
1379 tcell = afs_GetPrimaryCell(READ_LOCK);
1381 p_name = tcell->cellName;
1383 plen = strlen(p_name);
1386 t_name = (char *)afs_osi_Alloc(plen + 1);
1387 if (t_name == NULL) {
1389 afs_PutCell(tcell, READ_LOCK);
1394 t_name[plen] = '\0';
1396 memcpy(t_name, p_name, plen);
1402 afs_PutCell(tcell, READ_LOCK);
1408 * afs_MarshallCacheConfig - marshall client cache configuration
1412 * IN callerVersion - the rpc stat version of the caller.
1414 * IN config - client cache configuration.
1416 * OUT ptr - buffer where configuration is marshalled.
1423 afs_MarshallCacheConfig(afs_uint32 callerVersion, cm_initparams_v1 * config,
1426 AFS_STATCNT(afs_MarshallCacheConfig);
1428 * We currently only support version 1.
1430 *(ptr++) = config->nChunkFiles;
1431 *(ptr++) = config->nStatCaches;
1432 *(ptr++) = config->nDataCaches;
1433 *(ptr++) = config->nVolumeCaches;
1434 *(ptr++) = config->firstChunkSize;
1435 *(ptr++) = config->otherChunkSize;
1436 *(ptr++) = config->cacheSize;
1437 *(ptr++) = config->setTime;
1438 *(ptr++) = config->memCache;
1442 /*------------------------------------------------------------------------
1443 * EXPORTED SRXAFSCB_GetCacheConfig
1446 * Routine to return parameters used to initialize client cache.
1447 * Client may request any format version. Server may not return
1448 * format version greater than version requested by client.
1451 * a_call: Ptr to Rx call on which this request came in.
1452 * callerVersion: Data format version desired by the client.
1453 * serverVersion: Data format version of output data.
1454 * configCount: Number bytes allocated for output data.
1455 * config: Client cache configuration.
1461 * Nothing interesting.
1465 *------------------------------------------------------------------------*/
1468 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1469 afs_uint32 * serverVersion, afs_uint32 * configCount,
1470 cacheConfig * config)
1472 afs_uint32 *t_config;
1474 cm_initparams_v1 cm_config;
1477 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1480 * Currently only support version 1
1482 allocsize = sizeof(cm_initparams_v1);
1483 t_config = (afs_uint32 *) afs_osi_Alloc(allocsize);
1484 if (t_config == NULL) {
1489 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1490 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1491 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1492 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1493 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1494 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1495 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1496 cm_config.setTime = cm_initParams.cmi_setTime;
1497 cm_config.memCache = cm_initParams.cmi_memCache;
1499 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1501 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1502 *configCount = allocsize;
1503 config->cacheConfig_val = t_config;
1504 config->cacheConfig_len = allocsize / sizeof(afs_uint32);
1511 /*------------------------------------------------------------------------
1512 * EXPORTED SRXAFSCB_FetchData
1515 * Routine to do third party move from a remioserver to the original
1516 * issuer of an ArchiveData request. Presently supported only by the
1517 * "fs" command, not by the AFS client.
1520 * rxcall: Ptr to Rx call on which this request came in.
1521 * Fid: pointer to AFSFid structure.
1522 * Fd: File descriptor inside fs command.
1523 * Position: Offset in the file.
1524 * Length: Data length to transfer.
1525 * TotalLength: Pointer to total file length field
1531 * Nothing interesting.
1534 *------------------------------------------------------------------------*/
1536 SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1537 afs_int64 Position, afs_int64 Length,
1538 afs_int64 * TotalLength)
1543 /*------------------------------------------------------------------------
1544 * EXPORTED SRXAFSCB_StoreData
1547 * Routine to do third party move from a remioserver to the original
1548 * issuer of a RetrieveData request. Presently supported only by the
1549 * "fs" command, not by the AFS client.
1552 * rxcall: Ptr to Rx call on which this request came in.
1553 * Fid: pointer to AFSFid structure.
1554 * Fd: File descriptor inside fs command.
1555 * Position: Offset in the file.
1556 * Length: Data length to transfer.
1557 * TotalLength: Pointer to total file length field
1563 * Nothing interesting.
1567 *------------------------------------------------------------------------*/
1569 SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1570 afs_int64 Position, afs_int64 Length,
1571 afs_int64 * TotalLength)
1576 /*------------------------------------------------------------------------
1577 * EXPORTED SRXAFSCB_GetCellByNum
1580 * Routine to get information about a cell specified by its
1581 * cell number (returned by GetCE/GetCE64).
1584 * a_call : Ptr to Rx call on which this request came in.
1585 * a_cellnum : Input cell number
1586 * a_name : Output cell name (one zero byte when no such cell).
1587 * a_hosts : Output cell database servers in host byte order.
1593 * Nothing interesting.
1597 *------------------------------------------------------------------------*/
1600 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
1601 char **a_name, serverList * a_hosts)
1607 AFS_STATCNT(SRXAFSCB_GetCellByNum);
1609 a_hosts->serverList_val = 0;
1610 a_hosts->serverList_len = 0;
1612 tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
1614 *a_name = afs_strdup("");
1619 ObtainReadLock(&tcell->lock);
1620 *a_name = afs_strdup(tcell->cellName);
1622 for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++);
1623 a_hosts->serverList_len = sn;
1624 a_hosts->serverList_val =
1625 (afs_int32 *) afs_osi_Alloc(sn * sizeof(afs_int32));
1627 for (i = 0; i < sn; i++)
1628 a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
1629 ReleaseReadLock(&tcell->lock);
1630 afs_PutCell(tcell, READ_LOCK);
1637 SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
1638 struct interfaceAddr *addr,
1639 Capabilities * capabilities)
1643 afs_uint32 *dataBuffP;
1644 afs_int32 dataBytes;
1648 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1650 ObtainReadLock(&afs_xinterface);
1652 /* return all network interface addresses */
1653 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1654 addr->uuid = afs_cb_interface.uuid;
1655 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1656 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1657 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1658 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1661 ReleaseReadLock(&afs_xinterface);
1665 dataBytes = 1 * sizeof(afs_uint32);
1666 dataBuffP = (afs_uint32 *) afs_osi_Alloc(dataBytes);
1667 dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS;
1668 capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32);
1669 capabilities->Capabilities_val = dataBuffP;
1675 #if 0 && defined(AFS_LINUX24_ENV)
1676 extern struct vcache *afs_globalVp;
1678 int recurse_dcache_parent(parent, a_index, addr, inode, flags, time, fileName)
1679 struct dentry * parent;
1687 struct dentry *this_parent = parent;
1688 struct list_head *next;
1690 struct dentry *dentry;
1693 next = this_parent->d_subdirs.next;
1695 while (next != &this_parent->d_subdirs) {
1696 struct list_head *tmp = next;
1697 dentry = list_entry(tmp, struct dentry, d_child);
1703 * Descend a level if the d_subdirs list is non-empty.
1705 if (!list_empty(&dentry->d_subdirs)) {
1706 this_parent = dentry;
1711 * All done at this level ... ascend and resume the search.
1713 if (this_parent != parent) {
1714 next = this_parent->d_child.next;
1715 this_parent = this_parent->d_parent;
1721 if (d_unhashed(dentry))
1726 *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
1727 *inode = ITOAFS(dentry->d_inode);
1728 *addr = atomic_read(&(dentry)->d_count);
1729 *time = dentry->d_time;
1737 int SRXAFSCB_GetDE(struct rx_call *a_call, afs_int32 a_index, afs_int32 *addr,
1738 afs_int32 *inode, afs_int32 *flags, afs_int32 *time,
1740 { /*SRXAFSCB_GetDE*/
1741 int code = 0; /*Return code*/
1742 #if 0 && defined(AFS_LINUX24_ENV)
1743 register int i; /*Loop variable*/
1744 register struct vcache *tvc = afs_globalVp;
1745 struct dentry *dentry;
1746 struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
1748 #ifdef RX_ENABLE_LOCKS
1750 #endif /* RX_ENABLE_LOCKS */
1752 #if defined(AFS_LINUX24_ENV)
1753 spin_lock(&dcache_lock);
1757 while ((cur = cur->next) != head) {
1758 dentry = list_entry(cur, struct dentry, d_alias);
1760 dget_locked(dentry);
1762 #if defined(AFS_LINUX24_ENV)
1763 spin_unlock(&dcache_lock);
1769 if (recurse_dcache_parent(dentry, a_index, addr, inode, flags, time, fileName) == 0) {
1780 *fileName = afs_strdup("");
1784 if (d_unhashed(dentry))
1789 *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
1790 *inode = ITOAFS(dentry->d_inode);
1791 *addr = atomic_read(&(dentry)->d_count);
1792 *time = dentry->d_time;
1799 #ifdef RX_ENABLE_LOCKS
1801 #endif /* RX_ENABLE_LOCKS */
1805 } /*SRXAFSCB_GetDE*/