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"
22 #include "afs/sysincludes.h" /*Standard vendor system headers */
23 #include "afsincludes.h" /*AFS-based standard headers */
24 #include "afs/afs_stats.h" /*Cache Manager stats */
25 #include "afs/afs_args.h"
27 afs_int32 afs_allCBs = 0; /*Break callbacks on all objects */
28 afs_int32 afs_oddCBs = 0; /*Break callbacks on dirs */
29 afs_int32 afs_evenCBs = 0; /*Break callbacks received on files */
30 afs_int32 afs_allZaps = 0; /*Objects entries deleted */
31 afs_int32 afs_oddZaps = 0; /*Dir cache entries deleted */
32 afs_int32 afs_evenZaps = 0; /*File cache entries deleted */
33 afs_int32 afs_connectBacks = 0;
36 * Some debugging aids.
38 static struct ltable {
43 "afs_xvcache", (char *)&afs_xvcache}, {
44 "afs_xdcache", (char *)&afs_xdcache}, {
45 "afs_xserver", (char *)&afs_xserver}, {
46 "afs_xvcb", (char *)&afs_xvcb}, {
47 "afs_xbrs", (char *)&afs_xbrs}, {
48 "afs_xcell", (char *)&afs_xcell}, {
49 "afs_xconn", (char *)&afs_xconn}, {
50 "afs_xuser", (char *)&afs_xuser}, {
51 "afs_xvolume", (char *)&afs_xvolume}, {
52 "puttofile", (char *)&afs_puttofileLock}, {
53 "afs_ftf", (char *)&afs_ftf}, {
54 "afs_xcbhash", (char *)&afs_xcbhash}, {
55 "afs_xaxs", (char *)&afs_xaxs}, {
56 "afs_xinterface", (char *)&afs_xinterface},
59 "afs_xosi", (char *)&afs_xosi},
62 "afs_xsrvAddr", (char *)&afs_xsrvAddr}
64 unsigned long lastCallBack_vnode;
65 unsigned int lastCallBack_dv;
66 osi_timeval_t lastCallBack_time;
68 /* these are for storing alternate interface addresses */
69 struct interfaceAddr afs_cb_interface;
71 /*------------------------------------------------------------------------
72 * EXPORTED SRXAFSCB_GetCE
75 * Routine called by the server-side callback RPC interface to
76 * implement pulling out the contents of the i'th cache entry.
79 * a_call : Ptr to Rx call on which this request came in.
80 * a_index : Index of desired cache entry.
81 * a_result : Ptr to a buffer for the given cache entry.
84 * 0 if everything went fine,
85 * 1 if we were given a bad index.
88 * Nothing interesting.
92 *------------------------------------------------------------------------*/
95 SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
96 struct AFSDBCacheEntry *a_result)
99 register int i; /*Loop variable */
100 register struct vcache *tvc; /*Ptr to current cache entry */
101 int code; /*Return code */
106 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
108 AFS_STATCNT(SRXAFSCB_GetCE);
109 for (i = 0; i < VCSIZE; i++) {
110 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
114 } /*Zip through current hash chain */
115 } /*Zip through hash chains */
125 * Copy out the located entry.
127 a_result->addr = afs_data_pointer_to_int32(tvc);
128 a_result->cell = tvc->fid.Cell;
129 a_result->netFid.Volume = tvc->fid.Fid.Volume;
130 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
131 a_result->netFid.Unique = tvc->fid.Fid.Unique;
132 a_result->lock.waitStates = tvc->lock.wait_states;
133 a_result->lock.exclLocked = tvc->lock.excl_locked;
134 a_result->lock.readersReading = tvc->lock.readers_reading;
135 a_result->lock.numWaiting = tvc->lock.num_waiting;
136 #if defined(INSTRUMENT_LOCKS)
137 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
138 a_result->lock.pid_writer = tvc->lock.pid_writer;
139 a_result->lock.src_indicator = tvc->lock.src_indicator;
141 /* On osf20 , the vcache does not maintain these three fields */
142 a_result->lock.pid_last_reader = 0;
143 a_result->lock.pid_writer = 0;
144 a_result->lock.src_indicator = 0;
145 #endif /* AFS_OSF20_ENV */
146 #ifdef AFS_64BIT_CLIENT
147 a_result->Length = (afs_int32) tvc->m.Length & 0xffffffff;
148 #else /* AFS_64BIT_CLIENT */
149 a_result->Length = tvc->m.Length;
150 #endif /* AFS_64BIT_CLIENT */
151 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
152 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
153 a_result->cbExpires = tvc->cbExpires;
154 if (tvc->states & CVInit) {
155 a_result->refCount = 1;
157 #ifdef AFS_DARWIN80_ENV
158 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
160 a_result->refCount = VREFCOUNT(tvc);
163 a_result->opens = tvc->opens;
164 a_result->writers = tvc->execsOrWriters;
165 a_result->mvstat = tvc->mvstat;
166 a_result->states = tvc->states;
170 * Return our results.
179 } /*SRXAFSCB_GetCE */
182 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
183 struct AFSDBCacheEntry64 *a_result)
185 register int i; /*Loop variable */
186 register struct vcache *tvc; /*Ptr to current cache entry */
187 int code; /*Return code */
192 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETCE);
194 AFS_STATCNT(SRXAFSCB_GetCE64);
195 for (i = 0; i < VCSIZE; i++) {
196 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
200 } /*Zip through current hash chain */
201 } /*Zip through hash chains */
211 * Copy out the located entry.
213 a_result->addr = afs_data_pointer_to_int32(tvc);
214 a_result->cell = tvc->fid.Cell;
215 a_result->netFid.Volume = tvc->fid.Fid.Volume;
216 a_result->netFid.Vnode = tvc->fid.Fid.Vnode;
217 a_result->netFid.Unique = tvc->fid.Fid.Unique;
218 a_result->lock.waitStates = tvc->lock.wait_states;
219 a_result->lock.exclLocked = tvc->lock.excl_locked;
220 a_result->lock.readersReading = tvc->lock.readers_reading;
221 a_result->lock.numWaiting = tvc->lock.num_waiting;
222 #if defined(INSTRUMENT_LOCKS)
223 a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
224 a_result->lock.pid_writer = tvc->lock.pid_writer;
225 a_result->lock.src_indicator = tvc->lock.src_indicator;
227 /* On osf20 , the vcache does not maintain these three fields */
228 a_result->lock.pid_last_reader = 0;
229 a_result->lock.pid_writer = 0;
230 a_result->lock.src_indicator = 0;
231 #endif /* AFS_OSF20_ENV */
232 #if !defined(AFS_64BIT_ENV)
233 a_result->Length.high = 0;
234 a_result->Length.low = tvc->m.Length;
236 a_result->Length = tvc->m.Length;
238 a_result->DataVersion = hgetlo(tvc->m.DataVersion);
239 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
240 a_result->cbExpires = tvc->cbExpires;
241 if (tvc->states & CVInit) {
242 a_result->refCount = 1;
244 #ifdef AFS_DARWIN80_ENV
245 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
247 a_result->refCount = VREFCOUNT(tvc);
250 a_result->opens = tvc->opens;
251 a_result->writers = tvc->execsOrWriters;
252 a_result->mvstat = tvc->mvstat;
253 a_result->states = tvc->states;
257 * Return our results.
266 } /*SRXAFSCB_GetCE64 */
269 /*------------------------------------------------------------------------
270 * EXPORTED SRXAFSCB_GetLock
273 * Routine called by the server-side callback RPC interface to
274 * implement pulling out the contents of a lock in the lock
278 * a_call : Ptr to Rx call on which this request came in.
279 * a_index : Index of desired lock.
280 * a_result : Ptr to a buffer for the given lock.
283 * 0 if everything went fine,
284 * 1 if we were given a bad index.
287 * Nothing interesting.
291 *------------------------------------------------------------------------*/
294 SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
295 struct AFSDBLock *a_result)
297 struct ltable *tl; /*Ptr to lock table entry */
298 int nentries; /*Num entries in table */
299 int code; /*Return code */
304 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
306 AFS_STATCNT(SRXAFSCB_GetLock);
307 nentries = sizeof(ltable) / sizeof(struct ltable);
308 if (a_index < 0 || a_index >= nentries) {
315 * Found it - copy out its contents.
317 tl = <able[a_index];
318 strcpy(a_result->name, tl->name);
319 a_result->lock.waitStates =
320 ((struct afs_lock *)(tl->addr))->wait_states;
321 a_result->lock.exclLocked =
322 ((struct afs_lock *)(tl->addr))->excl_locked;
323 a_result->lock.readersReading =
324 ((struct afs_lock *)(tl->addr))->readers_reading;
325 a_result->lock.numWaiting =
326 ((struct afs_lock *)(tl->addr))->num_waiting;
327 #ifdef INSTRUMENT_LOCKS
328 a_result->lock.pid_last_reader =
329 ((struct afs_lock *)(tl->addr))->pid_last_reader;
330 a_result->lock.pid_writer =
331 ((struct afs_lock *)(tl->addr))->pid_writer;
332 a_result->lock.src_indicator =
333 ((struct afs_lock *)(tl->addr))->src_indicator;
335 a_result->lock.pid_last_reader = 0;
336 a_result->lock.pid_writer = 0;
337 a_result->lock.src_indicator = 0;
348 } /*SRXAFSCB_GetLock */
351 /*------------------------------------------------------------------------
352 * static ClearCallBack
355 * Clear out callback information for the specified file, or
356 * even a whole volume. Used to worry about callback was from
357 * within the particular cell or not. Now we don't bother with
358 * that anymore; it's not worth the time.
361 * a_conn : Ptr to Rx connection involved.
362 * a_fid : Ptr to AFS fid being cleared.
368 * Nothing interesting.
373 Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
375 *------------------------------------------------------------------------*/
378 ClearCallBack(register struct rx_connection *a_conn,
379 register struct AFSFid *a_fid)
381 register struct vcache *tvc;
383 struct VenusFid localFid;
386 AFS_STATCNT(ClearCallBack);
391 * XXXX Don't hold any server locks here because of callback protocol XXX
394 localFid.Fid.Volume = a_fid->Volume;
395 localFid.Fid.Vnode = a_fid->Vnode;
396 localFid.Fid.Unique = a_fid->Unique;
399 * Volume ID of zero means don't do anything.
401 if (a_fid->Volume != 0) {
402 if (a_fid->Vnode == 0) {
403 struct afs_q *tq, *uq;
405 * Clear callback for the whole volume. Zip through the
406 * hash chain, nullifying entries whose volume ID matches.
408 i = VCHashV(&localFid);
409 for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) {
412 if (tvc->fid.Fid.Volume == a_fid->Volume) {
413 tvc->callback = NULL;
415 localFid.Cell = tvc->fid.Cell;
416 tvc->dchint = NULL; /* invalidate hints */
417 ObtainWriteLock(&afs_xcbhash, 449);
418 afs_DequeueCallback(tvc);
419 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
421 if (tvc->fid.Fid.Vnode & 1)
425 ReleaseWriteLock(&afs_xcbhash);
426 if (!(tvc->states & CVInit) &&
427 (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)))
428 osi_dnlc_purgedp(tvc);
429 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
430 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
431 tvc->states, ICL_TYPE_INT32,
433 } else if ((tvc->states & CMValid)
434 && (tvc->mvid->Fid.Volume == a_fid->Volume)) {
435 tvc->states &= ~CMValid;
437 localFid.Cell = tvc->mvid->Cell;
442 * XXXX Don't hold any locks here XXXX
444 tv = afs_FindVolume(&localFid, 0);
446 afs_ResetVolumeInfo(tv);
447 afs_PutVolume(tv, 0);
448 /* invalidate mtpoint? */
450 } /*Clear callbacks for whole volume */
453 * Clear callbacks just for the one file.
456 if (a_fid->Vnode & 1)
457 afs_oddCBs++; /*Could do this on volume basis, too */
459 afs_evenCBs++; /*A particular fid was specified */
460 i = VCHash(&localFid);
461 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
462 if (tvc->fid.Fid.Vnode == a_fid->Vnode
463 && tvc->fid.Fid.Volume == a_fid->Volume
464 && tvc->fid.Fid.Unique == a_fid->Unique) {
465 tvc->callback = NULL;
466 tvc->dchint = NULL; /* invalidate hints */
467 ObtainWriteLock(&afs_xcbhash, 450);
468 afs_DequeueCallback(tvc);
469 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
470 ReleaseWriteLock(&afs_xcbhash);
471 if (!(tvc->states & CVInit) &&
472 (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)))
473 osi_dnlc_purgedp(tvc);
474 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
475 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
476 tvc->states, ICL_TYPE_LONG, 0);
478 lastCallBack_vnode = afid->Vnode;
479 lastCallBack_dv = tvc->mstat.DataVersion.low;
480 osi_GetuTime(&lastCallBack_time);
483 } /*Walk through hash table */
484 } /*Clear callbacks for one file */
487 /*Fid has non-zero volume ID */
489 * Always return a predictable value.
496 /*------------------------------------------------------------------------
497 * EXPORTED SRXAFSCB_CallBack
500 * Routine called by the server-side callback RPC interface to
501 * implement passing in callback information.
505 * a_call : Ptr to Rx call on which this request came in.
506 * a_fids : Ptr to array of fids involved.
507 * a_callbacks : Ptr to matching callback info for the fids.
513 * Nothing interesting.
517 *------------------------------------------------------------------------*/
520 SRXAFSCB_CallBack(struct rx_call *a_call, register struct AFSCBFids *a_fids,
521 struct AFSCBs *a_callbacks)
523 register int i; /*Loop variable */
524 struct AFSFid *tfid; /*Ptr to current fid */
525 register struct rx_connection *tconn; /*Call's connection */
531 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
533 AFS_STATCNT(SRXAFSCB_CallBack);
534 if (!(tconn = rx_ConnectionOf(a_call)))
536 tfid = (struct AFSFid *)a_fids->AFSCBFids_val;
539 * For now, we ignore callbacks, since the File Server only *breaks*
540 * callbacks at present.
542 for (i = 0; i < a_fids->AFSCBFids_len; i++)
543 ClearCallBack(tconn, &tfid[i]);
551 } /*SRXAFSCB_CallBack */
554 /*------------------------------------------------------------------------
555 * EXPORTED SRXAFSCB_Probe
558 * Routine called by the server-side callback RPC interface to
559 * implement ``probing'' the Cache Manager, just making sure it's
563 * a_call : Ptr to Rx call on which this request came in.
569 * Nothing interesting.
573 *------------------------------------------------------------------------*/
576 SRXAFSCB_Probe(struct rx_call *a_call)
582 AFS_STATCNT(SRXAFSCB_Probe);
584 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
591 } /*SRXAFSCB_Probe */
594 /*------------------------------------------------------------------------
595 * EXPORTED SRXAFSCB_InitCallBackState
598 * Routine called by the server-side callback RPC interface to
599 * implement clearing all callbacks from this host.
602 * a_call : Ptr to Rx call on which this request came in.
608 * Nothing interesting.
612 *------------------------------------------------------------------------*/
615 SRXAFSCB_InitCallBackState(struct rx_call *a_call)
618 register struct vcache *tvc;
619 register struct rx_connection *tconn;
620 register struct rx_peer *peer;
627 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
628 AFS_STATCNT(SRXAFSCB_InitCallBackState);
631 * Find the address of the host making this call
633 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
636 afs_oddCBs++; /*Including any missed via create race */
637 afs_evenCBs++; /*Including any missed via create race */
639 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *) 0,
642 for (i = 0; i < VCSIZE; i++)
643 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
644 if (tvc->callback == ts) {
645 ObtainWriteLock(&afs_xcbhash, 451);
646 afs_DequeueCallback(tvc);
647 tvc->callback = NULL;
648 tvc->states &= ~(CStatd | CUnique | CBulkFetching);
649 ReleaseWriteLock(&afs_xcbhash);
656 /* find any volumes residing on this server and flush their state */
658 register struct volume *tv;
661 for (i = 0; i < NVOLS; i++)
662 for (tv = afs_volumes[i]; tv; tv = tv->next) {
663 for (j = 0; j < MAXHOSTS; j++)
664 if (tv->serverHost[j] == ts)
665 afs_ResetVolumeInfo(tv);
668 osi_dnlc_purge(); /* may be a little bit extreme */
677 } /*SRXAFSCB_InitCallBackState */
680 /*------------------------------------------------------------------------
681 * EXPORTED SRXAFSCB_XStatsVersion
684 * Routine called by the server-side callback RPC interface to
685 * implement pulling out the xstat version number for the Cache
689 * a_versionP : Ptr to the version number variable to set.
695 * Nothing interesting.
699 *------------------------------------------------------------------------*/
702 SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 * a_versionP)
709 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
711 *a_versionP = AFSCB_XSTAT_VERSION;
718 } /*SRXAFSCB_XStatsVersion */
721 /*------------------------------------------------------------------------
722 * EXPORTED SRXAFSCB_GetXStats
725 * Routine called by the server-side callback RPC interface to
726 * implement getting the given data collection from the extended
727 * Cache Manager statistics.
730 * a_call : Ptr to Rx call on which this request came in.
731 * a_clientVersionNum : Client version number.
732 * a_opCode : Desired operation.
733 * a_serverVersionNumP : Ptr to version number to set.
734 * a_timeP : Ptr to time value (seconds) to set.
735 * a_dataArray : Ptr to variable array structure to return
742 * Nothing interesting.
746 *------------------------------------------------------------------------*/
749 SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
750 afs_int32 a_collectionNumber, afs_int32 * a_srvVersionNumP,
751 afs_int32 * a_timeP, AFSCB_CollData * a_dataP)
753 register int code; /*Return value */
754 afs_int32 *dataBuffP; /*Ptr to data to be returned */
755 afs_int32 dataBytes; /*Bytes in data buffer */
760 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
763 * Record the time of day and the server version number.
765 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
766 *a_timeP = osi_Time();
769 * Stuff the appropriate data in there (assume victory)
775 * We're not keeping stats, so just return successfully with
778 a_dataP->AFSCB_CollData_len = 0;
779 a_dataP->AFSCB_CollData_val = NULL;
781 switch (a_collectionNumber) {
782 case AFSCB_XSTATSCOLL_CALL_INFO:
784 * Pass back all the call-count-related data.
786 * >>> We are forced to allocate a separate area in which to
787 * >>> put this stuff in by the RPC stub generator, since it
788 * >>> will be freed at the tail end of the server stub code.
790 dataBytes = sizeof(struct afs_CMStats);
791 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
792 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
793 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
794 a_dataP->AFSCB_CollData_val = dataBuffP;
797 case AFSCB_XSTATSCOLL_PERF_INFO:
799 * Update and then pass back all the performance-related data.
800 * Note: the only performance fields that need to be computed
801 * at this time are the number of accesses for this collection
802 * and the current server record info.
804 * >>> We are forced to allocate a separate area in which to
805 * >>> put this stuff in by the RPC stub generator, since it
806 * >>> will be freed at the tail end of the server stub code.
808 afs_stats_cmperf.numPerfCalls++;
810 dataBytes = sizeof(afs_stats_cmperf);
811 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
812 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
813 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
814 a_dataP->AFSCB_CollData_val = dataBuffP;
817 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
819 * Pass back the full range of performance and statistical
820 * data available. We have to bring the normal performance
821 * data collection up to date, then copy that data into
822 * the full collection.
824 * >>> We are forced to allocate a separate area in which to
825 * >>> put this stuff in by the RPC stub generator, since it
826 * >>> will be freed at the tail end of the server stub code.
828 afs_stats_cmperf.numPerfCalls++;
830 memcpy((char *)(&(afs_stats_cmfullperf.perf)),
831 (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
832 afs_stats_cmfullperf.numFullPerfCalls++;
834 dataBytes = sizeof(afs_stats_cmfullperf);
835 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
836 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
837 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
838 a_dataP->AFSCB_CollData_val = dataBuffP;
843 * Illegal collection number.
845 a_dataP->AFSCB_CollData_len = 0;
846 a_dataP->AFSCB_CollData_val = NULL;
848 } /*Switch on collection number */
849 #endif /* AFS_NOSTATS */
857 } /*SRXAFSCB_GetXStats */
860 /*------------------------------------------------------------------------
861 * EXPORTED afs_RXCallBackServer
864 * Body of the thread supporting callback services.
873 * Nothing interesting.
877 *------------------------------------------------------------------------*/
880 afs_RXCallBackServer(void)
882 AFS_STATCNT(afs_RXCallBackServer);
887 afs_osi_Sleep(&afs_server);
891 * Donate this process to Rx.
896 } /*afs_RXCallBackServer */
899 /*------------------------------------------------------------------------
900 * EXPORTED shutdown_CB
903 * Zero out important Cache Manager data structures.
912 * Nothing interesting.
916 *------------------------------------------------------------------------*/
921 AFS_STATCNT(shutdown_CB);
923 if (afs_cold_shutdown) {
924 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps =
925 afs_evenZaps = afs_connectBacks = 0;
932 /*------------------------------------------------------------------------
933 * EXPORTED SRXAFSCB_InitCallBackState2
936 * This routine was used in the AFS 3.5 beta release, but not anymore.
937 * It has since been replaced by SRXAFSCB_InitCallBackState3.
940 * a_call : Ptr to Rx call on which this request came in.
943 * RXGEN_OPCODE (always).
946 * Nothing interesting.
950 *------------------------------------------------------------------------*/
953 SRXAFSCB_InitCallBackState2(struct rx_call *a_call,
954 struct interfaceAddr *addr)
959 /*------------------------------------------------------------------------
960 * EXPORTED SRXAFSCB_WhoAreYou
963 * Routine called by the server-side callback RPC interface to
964 * obtain a unique identifier for the client. The server uses
965 * this identifier to figure out whether or not two RX connections
966 * are from the same client, and to find out which addresses go
967 * with which clients.
970 * a_call : Ptr to Rx call on which this request came in.
971 * addr: Ptr to return the list of interfaces for this client.
977 * Nothing interesting.
981 *------------------------------------------------------------------------*/
984 SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
991 AFS_STATCNT(SRXAFSCB_WhoAreYou);
993 memset(addr, 0, sizeof(*addr));
995 ObtainReadLock(&afs_xinterface);
997 /* return all network interface addresses */
998 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
999 addr->uuid = afs_cb_interface.uuid;
1000 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1001 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1002 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1003 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1006 ReleaseReadLock(&afs_xinterface);
1014 /*------------------------------------------------------------------------
1015 * EXPORTED SRXAFSCB_InitCallBackState3
1018 * Routine called by the server-side callback RPC interface to
1019 * implement clearing all callbacks from this host.
1022 * a_call : Ptr to Rx call on which this request came in.
1028 * Nothing interesting.
1032 *------------------------------------------------------------------------*/
1035 SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID * a_uuid)
1040 * TBD: Lookup the server by the UUID instead of its IP address.
1042 code = SRXAFSCB_InitCallBackState(a_call);
1048 /*------------------------------------------------------------------------
1049 * EXPORTED SRXAFSCB_ProbeUuid
1052 * Routine called by the server-side callback RPC interface to
1053 * implement ``probing'' the Cache Manager, just making sure it's
1054 * still there is still the same client it used to be.
1057 * a_call : Ptr to Rx call on which this request came in.
1058 * a_uuid : Ptr to UUID that must match the client's UUID.
1061 * 0 if a_uuid matches the UUID for this client
1062 * Non-zero otherwize
1065 * Nothing interesting.
1069 *------------------------------------------------------------------------*/
1072 SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID * a_uuid)
1078 AFS_STATCNT(SRXAFSCB_Probe);
1080 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1081 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1082 code = 1; /* failure */
1091 /*------------------------------------------------------------------------
1092 * EXPORTED SRXAFSCB_GetServerPrefs
1095 * Routine to list server preferences used by this client.
1098 * a_call : Ptr to Rx call on which this request came in.
1099 * a_index : Input server index
1100 * a_srvr_addr : Output server address in host byte order
1101 * (0xffffffff on last server)
1102 * a_srvr_rank : Output server rank
1108 * Nothing interesting.
1112 *------------------------------------------------------------------------*/
1115 SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1116 afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
1122 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1124 ObtainReadLock(&afs_xserver);
1126 /* Search the hash table for the server with this index */
1127 *a_srvr_addr = 0xffffffff;
1128 *a_srvr_rank = 0xffffffff;
1129 for (i = 0, j = 0; j < NSERVERS && i <= a_index; j++) {
1130 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1132 *a_srvr_addr = ntohl(sa->sa_ip);
1133 *a_srvr_rank = sa->sa_iprank;
1138 ReleaseReadLock(&afs_xserver);
1146 /*------------------------------------------------------------------------
1147 * EXPORTED SRXAFSCB_GetCellServDB
1150 * Routine to list cells configured for this client
1153 * a_call : Ptr to Rx call on which this request came in.
1154 * a_index : Input cell index
1155 * a_name : Output cell name ("" on last cell)
1156 * a_hosts : Output cell database servers in host byte order.
1162 * Nothing interesting.
1166 *------------------------------------------------------------------------*/
1169 SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1170 char **a_name, serverList * a_hosts)
1174 char *t_name, *p_name = NULL;
1177 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1179 tcell = afs_GetCellByIndex(a_index, READ_LOCK);
1183 a_hosts->serverList_val = 0;
1184 a_hosts->serverList_len = 0;
1186 p_name = tcell->cellName;
1187 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
1189 a_hosts->serverList_val =
1190 (afs_int32 *) afs_osi_Alloc(j * sizeof(afs_int32));
1191 a_hosts->serverList_len = j;
1192 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++)
1193 a_hosts->serverList_val[j] =
1194 ntohl(tcell->cellHosts[j]->addr->sa_ip);
1195 afs_PutCell(tcell, READ_LOCK);
1198 t_name = (char *)afs_osi_Alloc(i + 1);
1199 if (t_name == NULL) {
1200 afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
1207 memcpy(t_name, p_name, i);
1216 /*------------------------------------------------------------------------
1217 * EXPORTED SRXAFSCB_GetLocalCell
1220 * Routine to return name of client's local cell
1223 * a_call : Ptr to Rx call on which this request came in.
1224 * a_name : Output cell name
1230 * Nothing interesting.
1234 *------------------------------------------------------------------------*/
1237 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1241 char *t_name, *p_name = NULL;
1244 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1246 /* Search the list for the primary cell. Cell number 1 is only
1247 * the primary cell is when no other cell is explicitly marked as
1248 * the primary cell. */
1249 tcell = afs_GetPrimaryCell(READ_LOCK);
1251 p_name = tcell->cellName;
1253 plen = strlen(p_name);
1256 t_name = (char *)afs_osi_Alloc(plen + 1);
1257 if (t_name == NULL) {
1259 afs_PutCell(tcell, READ_LOCK);
1264 t_name[plen] = '\0';
1266 memcpy(t_name, p_name, plen);
1272 afs_PutCell(tcell, READ_LOCK);
1278 * afs_MarshallCacheConfig - marshall client cache configuration
1282 * IN callerVersion - the rpc stat version of the caller.
1284 * IN config - client cache configuration.
1286 * OUT ptr - buffer where configuration is marshalled.
1293 afs_MarshallCacheConfig(afs_uint32 callerVersion, cm_initparams_v1 * config,
1296 AFS_STATCNT(afs_MarshallCacheConfig);
1298 * We currently only support version 1.
1300 *(ptr++) = config->nChunkFiles;
1301 *(ptr++) = config->nStatCaches;
1302 *(ptr++) = config->nDataCaches;
1303 *(ptr++) = config->nVolumeCaches;
1304 *(ptr++) = config->firstChunkSize;
1305 *(ptr++) = config->otherChunkSize;
1306 *(ptr++) = config->cacheSize;
1307 *(ptr++) = config->setTime;
1308 *(ptr++) = config->memCache;
1312 /*------------------------------------------------------------------------
1313 * EXPORTED SRXAFSCB_GetCacheConfig
1316 * Routine to return parameters used to initialize client cache.
1317 * Client may request any format version. Server may not return
1318 * format version greater than version requested by client.
1321 * a_call: Ptr to Rx call on which this request came in.
1322 * callerVersion: Data format version desired by the client.
1323 * serverVersion: Data format version of output data.
1324 * configCount: Number bytes allocated for output data.
1325 * config: Client cache configuration.
1331 * Nothing interesting.
1335 *------------------------------------------------------------------------*/
1338 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1339 afs_uint32 * serverVersion, afs_uint32 * configCount,
1340 cacheConfig * config)
1342 afs_uint32 *t_config;
1344 cm_initparams_v1 cm_config;
1347 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1350 * Currently only support version 1
1352 allocsize = sizeof(cm_initparams_v1);
1353 t_config = (afs_uint32 *) afs_osi_Alloc(allocsize);
1354 if (t_config == NULL) {
1359 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1360 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1361 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1362 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1363 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1364 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1365 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1366 cm_config.setTime = cm_initParams.cmi_setTime;
1367 cm_config.memCache = cm_initParams.cmi_memCache;
1369 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1371 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1372 *configCount = allocsize;
1373 config->cacheConfig_val = t_config;
1374 config->cacheConfig_len = allocsize / sizeof(afs_uint32);
1381 /*------------------------------------------------------------------------
1382 * EXPORTED SRXAFSCB_FetchData
1385 * Routine to do third party move from a remioserver to the original
1386 * issuer of an ArchiveData request. Presently supported only by the
1387 * "fs" command, not by the AFS client.
1390 * rxcall: Ptr to Rx call on which this request came in.
1391 * Fid: pointer to AFSFid structure.
1392 * Fd: File descriptor inside fs command.
1393 * Position: Offset in the file.
1394 * Length: Data length to transfer.
1395 * TotalLength: Pointer to total file length field
1401 * Nothing interesting.
1404 *------------------------------------------------------------------------*/
1406 SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1407 afs_int64 Position, afs_int64 Length,
1408 afs_int64 * TotalLength)
1413 /*------------------------------------------------------------------------
1414 * EXPORTED SRXAFSCB_StoreData
1417 * Routine to do third party move from a remioserver to the original
1418 * issuer of a RetrieveData request. Presently supported only by the
1419 * "fs" command, not by the AFS client.
1422 * rxcall: Ptr to Rx call on which this request came in.
1423 * Fid: pointer to AFSFid structure.
1424 * Fd: File descriptor inside fs command.
1425 * Position: Offset in the file.
1426 * Length: Data length to transfer.
1427 * TotalLength: Pointer to total file length field
1433 * Nothing interesting.
1437 *------------------------------------------------------------------------*/
1439 SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1440 afs_int64 Position, afs_int64 Length,
1441 afs_int64 * TotalLength)
1446 /*------------------------------------------------------------------------
1447 * EXPORTED SRXAFSCB_GetCellByNum
1450 * Routine to get information about a cell specified by its
1451 * cell number (returned by GetCE/GetCE64).
1454 * a_call : Ptr to Rx call on which this request came in.
1455 * a_cellnum : Input cell number
1456 * a_name : Output cell name (one zero byte when no such cell).
1457 * a_hosts : Output cell database servers in host byte order.
1463 * Nothing interesting.
1467 *------------------------------------------------------------------------*/
1470 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
1471 char **a_name, serverList * a_hosts)
1477 AFS_STATCNT(SRXAFSCB_GetCellByNum);
1479 a_hosts->serverList_val = 0;
1480 a_hosts->serverList_len = 0;
1482 tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
1484 *a_name = afs_strdup("");
1489 ObtainReadLock(&tcell->lock);
1490 *a_name = afs_strdup(tcell->cellName);
1492 for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++);
1493 a_hosts->serverList_len = sn;
1494 a_hosts->serverList_val =
1495 (afs_int32 *) afs_osi_Alloc(sn * sizeof(afs_int32));
1497 for (i = 0; i < sn; i++)
1498 a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
1499 ReleaseReadLock(&tcell->lock);
1500 afs_PutCell(tcell, READ_LOCK);
1507 SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
1508 struct interfaceAddr *addr,
1509 Capabilities * capabilities)
1513 afs_int32 *dataBuffP;
1514 afs_int32 dataBytes;
1518 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1520 ObtainReadLock(&afs_xinterface);
1522 /* return all network interface addresses */
1523 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1524 addr->uuid = afs_cb_interface.uuid;
1525 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1526 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1527 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1528 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1531 ReleaseReadLock(&afs_xinterface);
1535 dataBytes = 1 * sizeof(afs_int32);
1536 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
1537 dataBuffP[0] = CAPABILITY_ERRORTRANS;
1538 capabilities->Capabilities_len = dataBytes / sizeof(afs_int32);
1539 capabilities->Capabilities_val = dataBuffP;
1545 #ifdef AFS_LINUX24_ENV
1546 extern struct vcache *afs_globalVp;
1548 int recurse_dcache_parent(parent, a_index, addr, inode, flags, time, fileName)
1549 struct dentry * parent;
1557 struct dentry *this_parent = parent;
1558 struct list_head *next;
1560 struct dentry *dentry;
1563 next = this_parent->d_subdirs.next;
1565 while (next != &this_parent->d_subdirs) {
1566 struct list_head *tmp = next;
1567 dentry = list_entry(tmp, struct dentry, d_child);
1573 * Descend a level if the d_subdirs list is non-empty.
1575 if (!list_empty(&dentry->d_subdirs)) {
1576 this_parent = dentry;
1581 * All done at this level ... ascend and resume the search.
1583 if (this_parent != parent) {
1584 next = this_parent->d_child.next;
1585 this_parent = this_parent->d_parent;
1591 if (d_unhashed(dentry))
1596 *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
1597 *inode = ITOAFS(dentry->d_inode);
1598 *addr = atomic_read(&(dentry)->d_count);
1599 *time = dentry->d_time;
1607 int SRXAFSCB_GetDE(a_call, a_index, addr, inode, flags, time, fileName)
1608 struct rx_call *a_call;
1615 { /*SRXAFSCB_GetDE*/
1616 int code = 0; /*Return code*/
1617 #ifdef AFS_LINUX24_ENV
1618 register int i; /*Loop variable*/
1619 register struct vcache *tvc = afs_globalVp;
1620 struct dentry *dentry;
1621 struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
1623 #ifdef RX_ENABLE_LOCKS
1625 #endif /* RX_ENABLE_LOCKS */
1627 #if defined(AFS_LINUX24_ENV)
1628 spin_lock(&dcache_lock);
1632 while ((cur = cur->next) != head) {
1633 dentry = list_entry(cur, struct dentry, d_alias);
1635 dget_locked(dentry);
1637 #if defined(AFS_LINUX24_ENV)
1638 spin_unlock(&dcache_lock);
1644 if (recurse_dcache_parent(dentry, a_index, addr, inode, flags, time, fileName) == 0) {
1655 *fileName = afs_strdup("");
1659 if (d_unhashed(dentry))
1664 *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
1665 *inode = ITOAFS(dentry->d_inode);
1666 *addr = atomic_read(&(dentry)->d_count);
1667 *time = dentry->d_time;
1674 #ifdef RX_ENABLE_LOCKS
1676 #endif /* RX_ENABLE_LOCKS */
1680 } /*SRXAFSCB_GetDE*/