Merge 1.8.0~pre4 packaging into master
[pkg-k5-afs_openafs.git] / src / afs / afs_callback.c
blob61b2a75b7a20b3af63e2152cf58849872eaac41d
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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
8 */
11 * afs_callback.c:
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 {
37 char *name;
38 char *addr;
39 } 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},
55 #ifndef UKERNEL
57 "afs_xosi", (char *)&afs_xosi},
58 #endif
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},
65 { "afs_discon_lock", (char *)&afs_discon_lock},
66 { "afs_disconDirtyLock", (char *)&afs_disconDirtyLock},
67 { "afs_discon_vc_dirty", (char *)&afs_xvcdirty},
68 { "afs_dynrootDirLock", (char *)&afs_dynrootDirLock},
69 { "afs_dynSymlinkLock", (char *)&afs_dynSymlinkLock},
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
81 * Description:
82 * Routine called by the server-side callback RPC interface to
83 * implement pulling out the contents of the i'th cache entry.
85 * Arguments:
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.
90 * Returns:
91 * 0 if everything went fine,
92 * 1 if we were given a bad index.
94 * Environment:
95 * Nothing interesting.
97 * Side Effects:
98 * As advertised.
99 *------------------------------------------------------------------------*/
102 SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
103 struct AFSDBCacheEntry *a_result)
106 int i; /*Loop variable */
107 struct vcache *tvc; /*Ptr to current cache entry */
108 int code; /*Return code */
109 XSTATS_DECLS;
111 RX_AFS_GLOCK();
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) {
118 if (a_index == 0)
119 goto searchDone;
120 a_index--;
121 } /*Zip through current hash chain */
122 } /*Zip through hash chains */
124 searchDone:
125 if (tvc == NULL) {
126 /*Past EOF */
127 code = 1;
128 goto fcnDone;
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;
147 #else
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;
163 } else {
164 #ifdef AFS_DARWIN80_ENV
165 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
166 #else
167 a_result->refCount = VREFCOUNT(tvc);
168 #endif
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;
174 code = 0;
177 * Return our results.
179 fcnDone:
180 XSTATS_END_TIME;
182 RX_AFS_GUNLOCK();
184 return (code);
186 } /*SRXAFSCB_GetCE */
189 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
190 struct AFSDBCacheEntry64 *a_result)
192 int i; /*Loop variable */
193 struct vcache *tvc; /*Ptr to current cache entry */
194 int code; /*Return code */
195 XSTATS_DECLS;
197 RX_AFS_GLOCK();
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) {
204 if (a_index == 0)
205 goto searchDone;
206 a_index--;
207 } /*Zip through current hash chain */
208 } /*Zip through hash chains */
210 searchDone:
211 if (tvc == NULL) {
212 /*Past EOF */
213 code = 1;
214 goto fcnDone;
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;
233 #else
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 a_result->Length = tvc->f.m.Length;
240 a_result->DataVersion = hgetlo(tvc->f.m.DataVersion);
241 a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */
242 a_result->cbExpires = tvc->cbExpires;
243 if (tvc->f.states & CVInit) {
244 a_result->refCount = 1;
245 } else {
246 #ifdef AFS_DARWIN80_ENV
247 a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */
248 #else
249 a_result->refCount = VREFCOUNT(tvc);
250 #endif
252 a_result->opens = tvc->opens;
253 a_result->writers = tvc->execsOrWriters;
254 a_result->mvstat = tvc->mvstat;
255 a_result->states = tvc->f.states;
256 code = 0;
259 * Return our results.
261 fcnDone:
262 XSTATS_END_TIME;
264 RX_AFS_GUNLOCK();
266 return (code);
268 } /*SRXAFSCB_GetCE64 */
271 /*------------------------------------------------------------------------
272 * EXPORTED SRXAFSCB_GetLock
274 * Description:
275 * Routine called by the server-side callback RPC interface to
276 * implement pulling out the contents of a lock in the lock
277 * table.
279 * Arguments:
280 * a_call : Ptr to Rx call on which this request came in.
281 * a_index : Index of desired lock.
282 * a_result : Ptr to a buffer for the given lock.
284 * Returns:
285 * 0 if everything went fine,
286 * 1 if we were given a bad index.
288 * Environment:
289 * Nothing interesting.
291 * Side Effects:
292 * As advertised.
293 *------------------------------------------------------------------------*/
296 SRXAFSCB_GetLock(struct rx_call *a_call, afs_int32 a_index,
297 struct AFSDBLock *a_result)
299 struct ltable *tl; /*Ptr to lock table entry */
300 int nentries; /*Num entries in table */
301 int code; /*Return code */
302 XSTATS_DECLS;
304 RX_AFS_GLOCK();
306 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETLOCK);
308 AFS_STATCNT(SRXAFSCB_GetLock);
309 nentries = sizeof(ltable) / sizeof(struct ltable);
310 if (a_index < 0 || a_index >= nentries+afs_cellindex) {
312 * Past EOF
314 code = 1;
315 } else if (a_index >= nentries) {
316 struct cell *tc = afs_GetCellByIndex(a_index-nentries, 0);
317 strcpy(a_result->name, tc->cellName);
318 a_result->lock.waitStates =
319 ((struct afs_lock *)&(tc->lock))->wait_states;
320 a_result->lock.exclLocked =
321 ((struct afs_lock *)&(tc->lock))->excl_locked;
322 a_result->lock.readersReading =
323 ((struct afs_lock *)&(tc->lock))->readers_reading;
324 a_result->lock.numWaiting =
325 ((struct afs_lock *)&(tc->lock))->num_waiting;
326 #ifdef INSTRUMENT_LOCKS
327 a_result->lock.pid_last_reader =
328 MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_last_reader);
329 a_result->lock.pid_writer =
330 MyPidxx2Pid(((struct afs_lock *)&(tc->lock))->pid_writer);
331 a_result->lock.src_indicator =
332 ((struct afs_lock *)&(tc->lock))->src_indicator;
333 #else
334 a_result->lock.pid_last_reader = 0;
335 a_result->lock.pid_writer = 0;
336 a_result->lock.src_indicator = 0;
337 #endif
338 code = 0;
339 } else {
341 * Found it - copy out its contents.
343 tl = &ltable[a_index];
344 strcpy(a_result->name, tl->name);
345 a_result->lock.waitStates =
346 ((struct afs_lock *)(tl->addr))->wait_states;
347 a_result->lock.exclLocked =
348 ((struct afs_lock *)(tl->addr))->excl_locked;
349 a_result->lock.readersReading =
350 ((struct afs_lock *)(tl->addr))->readers_reading;
351 a_result->lock.numWaiting =
352 ((struct afs_lock *)(tl->addr))->num_waiting;
353 #ifdef INSTRUMENT_LOCKS
354 a_result->lock.pid_last_reader =
355 MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_last_reader);
356 a_result->lock.pid_writer =
357 MyPidxx2Pid(((struct afs_lock *)(tl->addr))->pid_writer);
358 a_result->lock.src_indicator =
359 ((struct afs_lock *)(tl->addr))->src_indicator;
360 #else
361 a_result->lock.pid_last_reader = 0;
362 a_result->lock.pid_writer = 0;
363 a_result->lock.src_indicator = 0;
364 #endif
365 code = 0;
368 XSTATS_END_TIME;
370 RX_AFS_GUNLOCK();
372 return (code);
374 } /*SRXAFSCB_GetLock */
377 /*------------------------------------------------------------------------
378 * static ClearCallBack
380 * Description:
381 * Clear out callback information for the specified file, or
382 * even a whole volume. Used to worry about callback was from
383 * within the particular cell or not. Now we don't bother with
384 * that anymore; it's not worth the time.
386 * Arguments:
387 * a_conn : Ptr to Rx connection involved.
388 * a_fid : Ptr to AFS fid being cleared.
390 * Returns:
391 * 0 (always)
393 * Environment:
394 * Nothing interesting.
396 * Side Effects:
397 * As advertised.
399 Appears to need to be called with GLOCK held, as the icl_Event4 stuff asserts otherwise
401 *------------------------------------------------------------------------*/
403 static int
404 ClearCallBack(struct rx_connection *a_conn,
405 struct AFSFid *a_fid)
407 struct vcache *tvc;
408 int i;
409 struct VenusFid localFid;
410 struct volume *tv;
411 #ifdef AFS_DARWIN80_ENV
412 vnode_t vp;
413 #endif
415 AFS_STATCNT(ClearCallBack);
417 AFS_ASSERT_GLOCK();
420 * XXXX Don't hold any server locks here because of callback protocol XXX
422 localFid.Cell = 0;
423 localFid.Fid.Volume = a_fid->Volume;
424 localFid.Fid.Vnode = a_fid->Vnode;
425 localFid.Fid.Unique = a_fid->Unique;
428 * Volume ID of zero means don't do anything.
430 if (a_fid->Volume != 0) {
431 if (a_fid->Vnode == 0) {
432 struct afs_q *tq, *uq;
434 * Clear callback for the whole volume. Zip through the
435 * hash chain, nullifying entries whose volume ID matches.
437 loop1:
438 ObtainReadLock(&afs_xvcache);
439 i = VCHashV(&localFid);
440 for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) {
441 uq = QPrev(tq);
442 tvc = QTOVH(tq);
443 if (tvc->f.fid.Fid.Volume == a_fid->Volume) {
444 tvc->callback = NULL;
445 if (!localFid.Cell)
446 localFid.Cell = tvc->f.fid.Cell;
447 tvc->dchint = NULL; /* invalidate hints */
448 if (tvc->f.states & CVInit) {
449 ReleaseReadLock(&afs_xvcache);
450 afs_osi_Sleep(&tvc->f.states);
451 goto loop1;
453 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
454 AFS_FAST_HOLD(tvc);
455 #else
456 #ifdef AFS_DARWIN80_ENV
457 if (tvc->f.states & CDeadVnode) {
458 ReleaseReadLock(&afs_xvcache);
459 afs_osi_Sleep(&tvc->f.states);
460 goto loop1;
462 vp = AFSTOV(tvc);
463 if (vnode_get(vp))
464 continue;
465 if (vnode_ref(vp)) {
466 AFS_GUNLOCK();
467 vnode_put(vp);
468 AFS_GLOCK();
469 continue;
471 #else
472 AFS_FAST_HOLD(tvc);
473 #endif
474 #endif
475 ReleaseReadLock(&afs_xvcache);
476 afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
477 afs_allCBs++;
478 if (tvc->f.fid.Fid.Vnode & 1)
479 afs_oddCBs++;
480 else
481 afs_evenCBs++;
482 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
483 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
484 tvc->f.states, ICL_TYPE_INT32,
485 a_fid->Volume);
486 #ifdef AFS_DARWIN80_ENV
487 vnode_put(AFSTOV(tvc));
488 #endif
489 ObtainReadLock(&afs_xvcache);
490 uq = QPrev(tq);
491 AFS_FAST_RELE(tvc);
492 } else if ((tvc->f.states & CMValid)
493 && (tvc->mvid.target_root->Fid.Volume == a_fid->Volume)) {
494 tvc->f.states &= ~CMValid;
495 if (!localFid.Cell)
496 localFid.Cell = tvc->mvid.target_root->Cell;
499 ReleaseReadLock(&afs_xvcache);
502 * XXXX Don't hold any locks here XXXX
504 tv = afs_FindVolume(&localFid, 0);
505 if (tv) {
506 afs_ResetVolumeInfo(tv);
507 afs_PutVolume(tv, 0);
508 /* invalidate mtpoint? */
510 } /*Clear callbacks for whole volume */
511 else {
513 * Clear callbacks just for the one file.
515 struct vcache *uvc;
516 afs_allCBs++;
517 if (a_fid->Vnode & 1)
518 afs_oddCBs++; /*Could do this on volume basis, too */
519 else
520 afs_evenCBs++; /*A particular fid was specified */
521 loop2:
522 ObtainReadLock(&afs_xvcache);
523 i = VCHash(&localFid);
524 for (tvc = afs_vhashT[i]; tvc; tvc = uvc) {
525 uvc = tvc->hnext;
526 if (tvc->f.fid.Fid.Vnode == a_fid->Vnode
527 && tvc->f.fid.Fid.Volume == a_fid->Volume
528 && tvc->f.fid.Fid.Unique == a_fid->Unique) {
529 tvc->callback = NULL;
530 tvc->dchint = NULL; /* invalidate hints */
531 if (tvc->f.states & CVInit) {
532 ReleaseReadLock(&afs_xvcache);
533 afs_osi_Sleep(&tvc->f.states);
534 goto loop2;
536 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
537 AFS_FAST_HOLD(tvc);
538 #else
539 #ifdef AFS_DARWIN80_ENV
540 if (tvc->f.states & CDeadVnode) {
541 ReleaseReadLock(&afs_xvcache);
542 afs_osi_Sleep(&tvc->f.states);
543 goto loop2;
545 vp = AFSTOV(tvc);
546 if (vnode_get(vp))
547 continue;
548 if (vnode_ref(vp)) {
549 AFS_GUNLOCK();
550 vnode_put(vp);
551 AFS_GLOCK();
552 continue;
554 #else
555 AFS_FAST_HOLD(tvc);
556 #endif
557 #endif
558 ReleaseReadLock(&afs_xvcache);
559 afs_StaleVCacheFlags(tvc, 0, CUnique | CBulkFetching);
560 afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK,
561 ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32,
562 tvc->f.states, ICL_TYPE_LONG, 0);
563 #ifdef CBDEBUG
564 lastCallBack_vnode = afid->Vnode;
565 lastCallBack_dv = tvc->mstat.DataVersion.low;
566 osi_GetuTime(&lastCallBack_time);
567 #endif /* CBDEBUG */
568 #ifdef AFS_DARWIN80_ENV
569 vnode_put(AFSTOV(tvc));
570 #endif
571 ObtainReadLock(&afs_xvcache);
572 uvc = tvc->hnext;
573 AFS_FAST_RELE(tvc);
575 } /*Walk through hash table */
576 ReleaseReadLock(&afs_xvcache);
577 } /*Clear callbacks for one file */
580 /*Fid has non-zero volume ID */
582 * Always return a predictable value.
584 return (0);
586 } /*ClearCallBack */
589 /*------------------------------------------------------------------------
590 * EXPORTED SRXAFSCB_CallBack
592 * Description:
593 * Routine called by the server-side callback RPC interface to
594 * implement passing in callback information.
595 * table.
597 * Arguments:
598 * a_call : Ptr to Rx call on which this request came in.
599 * a_fids : Ptr to array of fids involved.
600 * a_callbacks : Ptr to matching callback info for the fids.
602 * Returns:
603 * 0 (always).
605 * Environment:
606 * Nothing interesting.
608 * Side Effects:
609 * As advertised.
610 *------------------------------------------------------------------------*/
613 SRXAFSCB_CallBack(struct rx_call *a_call, struct AFSCBFids *a_fids,
614 struct AFSCBs *a_callbacks)
616 int i; /*Loop variable */
617 struct AFSFid *tfid; /*Ptr to current fid */
618 struct rx_connection *tconn; /*Call's connection */
619 int code = 0;
620 XSTATS_DECLS;
622 RX_AFS_GLOCK();
624 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_CALLBACK);
626 AFS_STATCNT(SRXAFSCB_CallBack);
627 if (!(tconn = rx_ConnectionOf(a_call)))
628 return (0);
629 tfid = (struct AFSFid *)a_fids->AFSCBFids_val;
632 * For now, we ignore callbacks, since the File Server only *breaks*
633 * callbacks at present.
635 for (i = 0; i < a_fids->AFSCBFids_len; i++)
636 ClearCallBack(tconn, &tfid[i]);
638 XSTATS_END_TIME;
640 RX_AFS_GUNLOCK();
642 return (0);
644 } /*SRXAFSCB_CallBack */
647 /*------------------------------------------------------------------------
648 * EXPORTED SRXAFSCB_Probe
650 * Description:
651 * Routine called by the server-side callback RPC interface to
652 * implement ``probing'' the Cache Manager, just making sure it's
653 * still there.
655 * Arguments:
656 * a_call : Ptr to Rx call on which this request came in.
658 * Returns:
659 * 0 (always).
661 * Environment:
662 * Nothing interesting.
664 * Side Effects:
665 * As advertised.
666 *------------------------------------------------------------------------*/
669 SRXAFSCB_Probe(struct rx_call *a_call)
671 int code = 0;
672 XSTATS_DECLS;
674 RX_AFS_GLOCK();
675 AFS_STATCNT(SRXAFSCB_Probe);
677 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
678 XSTATS_END_TIME;
680 RX_AFS_GUNLOCK();
682 return (0);
684 } /*SRXAFSCB_Probe */
687 /*------------------------------------------------------------------------
688 * EXPORTED SRXAFSCB_InitCallBackState
690 * Description:
691 * Routine called by the server-side callback RPC interface to
692 * implement clearing all callbacks from this host.
694 * Arguments:
695 * a_call : Ptr to Rx call on which this request came in.
697 * Returns:
698 * 0 (always).
700 * Environment:
701 * Nothing interesting.
703 * Side Effects:
704 * As advertised.
705 *------------------------------------------------------------------------*/
708 SRXAFSCB_InitCallBackState(struct rx_call *a_call)
710 int i;
711 struct vcache *tvc;
712 struct rx_connection *tconn;
713 struct rx_peer *peer;
714 struct server *ts;
715 int code = 0;
716 XSTATS_DECLS;
718 RX_AFS_GLOCK();
720 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE);
721 AFS_STATCNT(SRXAFSCB_InitCallBackState);
724 * Find the address of the host making this call
726 if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) {
728 afs_allCBs++;
729 afs_oddCBs++; /*Including any missed via create race */
730 afs_evenCBs++; /*Including any missed via create race */
732 ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *) 0,
734 if (ts) {
735 for (i = 0; i < VCSIZE; i++)
736 for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) {
737 if (tvc->callback == ts) {
738 afs_StaleVCacheFlags(tvc, AFS_STALEVC_NODNLC |
739 AFS_STALEVC_CLEARCB,
740 CUnique | CBulkFetching);
744 /* capabilities need be requested again */
745 ts->flags &= ~SCAPS_KNOWN;
750 /* find any volumes residing on this server and flush their state */
752 struct volume *tv;
753 int j;
755 for (i = 0; i < NVOLS; i++)
756 for (tv = afs_volumes[i]; tv; tv = tv->next) {
757 for (j = 0; j < AFS_MAXHOSTS; j++)
758 if (tv->serverHost[j] == ts)
759 afs_ResetVolumeInfo(tv);
762 osi_dnlc_purge(); /* may be a little bit extreme */
765 XSTATS_END_TIME;
767 RX_AFS_GUNLOCK();
769 return (0);
771 } /*SRXAFSCB_InitCallBackState */
774 /*------------------------------------------------------------------------
775 * EXPORTED SRXAFSCB_XStatsVersion
777 * Description:
778 * Routine called by the server-side callback RPC interface to
779 * implement pulling out the xstat version number for the Cache
780 * Manager.
782 * Arguments:
783 * a_versionP : Ptr to the version number variable to set.
785 * Returns:
786 * 0 (always)
788 * Environment:
789 * Nothing interesting.
791 * Side Effects:
792 * As advertised.
793 *------------------------------------------------------------------------*/
796 SRXAFSCB_XStatsVersion(struct rx_call *a_call, afs_int32 * a_versionP)
798 int code = 0;
800 XSTATS_DECLS;
802 RX_AFS_GLOCK();
803 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_XSTATSVERSION);
805 *a_versionP = AFSCB_XSTAT_VERSION;
807 XSTATS_END_TIME;
809 RX_AFS_GUNLOCK();
811 return (0);
812 } /*SRXAFSCB_XStatsVersion */
815 /*------------------------------------------------------------------------
816 * EXPORTED SRXAFSCB_GetXStats
818 * Description:
819 * Routine called by the server-side callback RPC interface to
820 * implement getting the given data collection from the extended
821 * Cache Manager statistics.
823 * Arguments:
824 * a_call : Ptr to Rx call on which this request came in.
825 * a_clientVersionNum : Client version number.
826 * a_opCode : Desired operation.
827 * a_serverVersionNumP : Ptr to version number to set.
828 * a_timeP : Ptr to time value (seconds) to set.
829 * a_dataArray : Ptr to variable array structure to return
830 * stuff in.
832 * Returns:
833 * 0 (always).
835 * Environment:
836 * Nothing interesting.
838 * Side Effects:
839 * As advertised.
840 *------------------------------------------------------------------------*/
843 SRXAFSCB_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
844 afs_int32 a_collectionNumber, afs_int32 * a_srvVersionNumP,
845 afs_int32 * a_timeP, AFSCB_CollData * a_dataP)
847 int code; /*Return value */
848 afs_int32 *dataBuffP; /*Ptr to data to be returned */
849 afs_int32 dataBytes; /*Bytes in data buffer */
850 XSTATS_DECLS;
852 RX_AFS_GLOCK();
854 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_GETXSTATS);
857 * Record the time of day and the server version number.
859 *a_srvVersionNumP = AFSCB_XSTAT_VERSION;
860 *a_timeP = osi_Time();
863 * Stuff the appropriate data in there (assume victory)
865 code = 0;
867 #ifdef AFS_NOSTATS
869 * We're not keeping stats, so just return successfully with
870 * no data.
872 a_dataP->AFSCB_CollData_len = 0;
873 a_dataP->AFSCB_CollData_val = NULL;
874 #else
875 switch (a_collectionNumber) {
876 case AFSCB_XSTATSCOLL_CALL_INFO:
878 * Pass back all the call-count-related data.
880 * >>> We are forced to allocate a separate area in which to
881 * >>> put this stuff in by the RPC stub generator, since it
882 * >>> will be freed at the tail end of the server stub code.
884 dataBytes = sizeof(struct afs_CMStats);
885 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
886 osi_Assert(dataBuffP != NULL);
887 memcpy((char *)dataBuffP, (char *)&afs_cmstats, dataBytes);
888 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
889 a_dataP->AFSCB_CollData_val = dataBuffP;
890 break;
892 case AFSCB_XSTATSCOLL_PERF_INFO:
894 * Update and then pass back all the performance-related data.
895 * Note: the only performance fields that need to be computed
896 * at this time are the number of accesses for this collection
897 * and the current server record info.
899 * >>> We are forced to allocate a separate area in which to
900 * >>> put this stuff in by the RPC stub generator, since it
901 * >>> will be freed at the tail end of the server stub code.
903 afs_stats_cmperf.numPerfCalls++;
904 afs_CountServers();
905 dataBytes = sizeof(afs_stats_cmperf);
906 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
907 osi_Assert(dataBuffP != NULL);
908 memcpy((char *)dataBuffP, (char *)&afs_stats_cmperf, dataBytes);
909 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
910 a_dataP->AFSCB_CollData_val = dataBuffP;
911 break;
913 case AFSCB_XSTATSCOLL_FULL_PERF_INFO:
915 * Pass back the full range of performance and statistical
916 * data available. We have to bring the normal performance
917 * data collection up to date, then copy that data into
918 * the full collection.
920 * >>> We are forced to allocate a separate area in which to
921 * >>> put this stuff in by the RPC stub generator, since it
922 * >>> will be freed at the tail end of the server stub code.
924 afs_stats_cmperf.numPerfCalls++;
925 afs_CountServers();
926 memcpy((char *)(&(afs_stats_cmfullperf.perf)),
927 (char *)(&afs_stats_cmperf), sizeof(struct afs_stats_CMPerf));
928 afs_stats_cmfullperf.numFullPerfCalls++;
930 dataBytes = sizeof(afs_stats_cmfullperf);
931 dataBuffP = (afs_int32 *) afs_osi_Alloc(dataBytes);
932 osi_Assert(dataBuffP != NULL);
933 memcpy((char *)dataBuffP, (char *)(&afs_stats_cmfullperf), dataBytes);
934 a_dataP->AFSCB_CollData_len = dataBytes >> 2;
935 a_dataP->AFSCB_CollData_val = dataBuffP;
936 break;
938 default:
940 * Illegal collection number.
942 a_dataP->AFSCB_CollData_len = 0;
943 a_dataP->AFSCB_CollData_val = NULL;
944 code = 1;
945 } /*Switch on collection number */
946 #endif /* AFS_NOSTATS */
948 XSTATS_END_TIME;
950 RX_AFS_GUNLOCK();
952 return (code);
954 } /*SRXAFSCB_GetXStats */
957 /*------------------------------------------------------------------------
958 * EXPORTED afs_RXCallBackServer
960 * Description:
961 * Body of the thread supporting callback services.
963 * Arguments:
964 * None.
966 * Returns:
967 * 0 (always).
969 * Environment:
970 * Nothing interesting.
972 * Side Effects:
973 * As advertised.
974 *------------------------------------------------------------------------*/
977 afs_RXCallBackServer(void)
979 AFS_STATCNT(afs_RXCallBackServer);
981 while (1) {
982 if (afs_server)
983 break;
984 afs_osi_Sleep(&afs_server);
988 * Donate this process to Rx.
990 rx_ServerProc(NULL);
991 return (0);
993 } /*afs_RXCallBackServer */
996 /*------------------------------------------------------------------------
997 * EXPORTED shutdown_CB
999 * Description:
1000 * Zero out important Cache Manager data structures.
1002 * Arguments:
1003 * None.
1005 * Returns:
1006 * 0 (always).
1008 * Environment:
1009 * Nothing interesting.
1011 * Side Effects:
1012 * As advertised.
1013 *------------------------------------------------------------------------*/
1016 shutdown_CB(void)
1018 AFS_STATCNT(shutdown_CB);
1020 if (afs_cold_shutdown) {
1021 afs_oddCBs = afs_evenCBs = afs_allCBs = afs_allZaps = afs_oddZaps =
1022 afs_evenZaps = afs_connectBacks = 0;
1025 return (0);
1027 } /*shutdown_CB */
1029 /*------------------------------------------------------------------------
1030 * EXPORTED SRXAFSCB_InitCallBackState2
1032 * Description:
1033 * This routine was used in the AFS 3.5 beta release, but not anymore.
1034 * It has since been replaced by SRXAFSCB_InitCallBackState3.
1036 * Arguments:
1037 * a_call : Ptr to Rx call on which this request came in.
1039 * Returns:
1040 * RXGEN_OPCODE (always).
1042 * Environment:
1043 * Nothing interesting.
1045 * Side Effects:
1046 * None
1047 *------------------------------------------------------------------------*/
1050 SRXAFSCB_InitCallBackState2(struct rx_call *a_call,
1051 struct interfaceAddr *addr)
1053 return RXGEN_OPCODE;
1056 /*------------------------------------------------------------------------
1057 * EXPORTED SRXAFSCB_WhoAreYou
1059 * Description:
1060 * Routine called by the server-side callback RPC interface to
1061 * obtain a unique identifier for the client. The server uses
1062 * this identifier to figure out whether or not two RX connections
1063 * are from the same client, and to find out which addresses go
1064 * with which clients.
1066 * Arguments:
1067 * a_call : Ptr to Rx call on which this request came in.
1068 * addr: Ptr to return the list of interfaces for this client.
1070 * Returns:
1071 * 0 (Always)
1073 * Environment:
1074 * Nothing interesting.
1076 * Side Effects:
1077 * As advertised.
1078 *------------------------------------------------------------------------*/
1081 SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
1083 int i;
1084 int code = 0;
1086 RX_AFS_GLOCK();
1088 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1090 memset(addr, 0, sizeof(*addr));
1092 ObtainReadLock(&afs_xinterface);
1094 /* return all network interface addresses */
1095 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1096 addr->uuid = afs_cb_interface.uuid;
1097 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1098 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1099 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1100 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1103 ReleaseReadLock(&afs_xinterface);
1105 RX_AFS_GUNLOCK();
1107 return code;
1111 /*------------------------------------------------------------------------
1112 * EXPORTED SRXAFSCB_InitCallBackState3
1114 * Description:
1115 * Routine called by the server-side callback RPC interface to
1116 * implement clearing all callbacks from this host.
1118 * Arguments:
1119 * a_call : Ptr to Rx call on which this request came in.
1121 * Returns:
1122 * 0 (always).
1124 * Environment:
1125 * Nothing interesting.
1127 * Side Effects:
1128 * As advertised.
1129 *------------------------------------------------------------------------*/
1132 SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID * a_uuid)
1134 int code;
1137 * TBD: Lookup the server by the UUID instead of its IP address.
1139 code = SRXAFSCB_InitCallBackState(a_call);
1141 return code;
1145 /*------------------------------------------------------------------------
1146 * EXPORTED SRXAFSCB_ProbeUuid
1148 * Description:
1149 * Routine called by the server-side callback RPC interface to
1150 * implement ``probing'' the Cache Manager, just making sure it's
1151 * still there is still the same client it used to be.
1153 * Arguments:
1154 * a_call : Ptr to Rx call on which this request came in.
1155 * a_uuid : Ptr to UUID that must match the client's UUID.
1157 * Returns:
1158 * 0 if a_uuid matches the UUID for this client
1159 * Non-zero otherwize
1161 * Environment:
1162 * Nothing interesting.
1164 * Side Effects:
1165 * As advertised.
1166 *------------------------------------------------------------------------*/
1169 SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID * a_uuid)
1171 int code = 0;
1172 XSTATS_DECLS;
1174 RX_AFS_GLOCK();
1175 AFS_STATCNT(SRXAFSCB_Probe);
1177 XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_PROBE);
1178 if (!afs_uuid_equal(a_uuid, &afs_cb_interface.uuid))
1179 code = 1; /* failure */
1180 XSTATS_END_TIME;
1182 RX_AFS_GUNLOCK();
1184 return code;
1188 /*------------------------------------------------------------------------
1189 * EXPORTED SRXAFSCB_GetServerPrefs
1191 * Description:
1192 * Routine to list server preferences used by this client.
1194 * Arguments:
1195 * a_call : Ptr to Rx call on which this request came in.
1196 * a_index : Input server index
1197 * a_srvr_addr : Output server address in host byte order
1198 * (0xffffffff on last server)
1199 * a_srvr_rank : Output server rank
1201 * Returns:
1202 * 0 on success
1204 * Environment:
1205 * Nothing interesting.
1207 * Side Effects:
1208 * As advertised.
1209 *------------------------------------------------------------------------*/
1212 SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
1213 afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
1215 int i, j;
1216 struct srvAddr *sa;
1218 RX_AFS_GLOCK();
1219 AFS_STATCNT(SRXAFSCB_GetServerPrefs);
1221 ObtainReadLock(&afs_xserver);
1223 /* Search the hash table for the server with this index */
1224 *a_srvr_addr = 0xffffffff;
1225 *a_srvr_rank = 0xffffffff;
1226 for (i = 0, j = 0; j < NSERVERS && i <= a_index; j++) {
1227 for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) {
1228 if (i == a_index) {
1229 *a_srvr_addr = ntohl(sa->sa_ip);
1230 *a_srvr_rank = sa->sa_iprank;
1235 ReleaseReadLock(&afs_xserver);
1237 RX_AFS_GUNLOCK();
1239 return 0;
1243 /*------------------------------------------------------------------------
1244 * EXPORTED SRXAFSCB_GetCellServDB
1246 * Description:
1247 * Routine to list cells configured for this client
1249 * Arguments:
1250 * a_call : Ptr to Rx call on which this request came in.
1251 * a_index : Input cell index
1252 * a_name : Output cell name ("" on last cell)
1253 * a_hosts : Output cell database servers in host byte order.
1255 * Returns:
1256 * 0 on success
1258 * Environment:
1259 * Nothing interesting.
1261 * Side Effects:
1262 * As advertised.
1263 *------------------------------------------------------------------------*/
1266 SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
1267 char **a_name, serverList * a_hosts)
1269 afs_int32 i, j = 0;
1270 struct cell *tcell;
1271 char *t_name, *p_name = NULL;
1273 RX_AFS_GLOCK();
1274 AFS_STATCNT(SRXAFSCB_GetCellServDB);
1276 tcell = afs_GetCellByIndex(a_index, READ_LOCK);
1278 if (!tcell) {
1279 i = 0;
1280 a_hosts->serverList_val = 0;
1281 a_hosts->serverList_len = 0;
1282 } else {
1283 p_name = tcell->cellName;
1284 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++);
1285 i = strlen(p_name);
1286 a_hosts->serverList_val = afs_osi_Alloc(j * sizeof(afs_int32));
1287 osi_Assert(a_hosts->serverList_val != NULL);
1288 a_hosts->serverList_len = j;
1289 for (j = 0; j < AFSMAXCELLHOSTS && tcell->cellHosts[j]; j++)
1290 a_hosts->serverList_val[j] =
1291 ntohl(tcell->cellHosts[j]->addr->sa_ip);
1292 afs_PutCell(tcell, READ_LOCK);
1295 t_name = afs_osi_Alloc(i + 1);
1296 if (t_name == NULL) {
1297 if (tcell != NULL)
1298 afs_osi_Free(a_hosts->serverList_val, (j * sizeof(afs_int32)));
1299 RX_AFS_GUNLOCK();
1300 return ENOMEM;
1303 t_name[i] = '\0';
1304 if (p_name)
1305 memcpy(t_name, p_name, i);
1307 RX_AFS_GUNLOCK();
1309 *a_name = t_name;
1310 return 0;
1314 /*------------------------------------------------------------------------
1315 * EXPORTED SRXAFSCB_GetLocalCell
1317 * Description:
1318 * Routine to return name of client's local cell
1320 * Arguments:
1321 * a_call : Ptr to Rx call on which this request came in.
1322 * a_name : Output cell name
1324 * Returns:
1325 * 0 on success
1327 * Environment:
1328 * Nothing interesting.
1330 * Side Effects:
1331 * As advertised.
1332 *------------------------------------------------------------------------*/
1335 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
1337 int plen;
1338 struct cell *tcell;
1339 char *t_name, *p_name = NULL;
1341 RX_AFS_GLOCK();
1342 AFS_STATCNT(SRXAFSCB_GetLocalCell);
1344 /* Search the list for the primary cell. Cell number 1 is only
1345 * the primary cell is when no other cell is explicitly marked as
1346 * the primary cell. */
1347 tcell = afs_GetPrimaryCell(READ_LOCK);
1348 if (tcell)
1349 p_name = tcell->cellName;
1350 if (p_name)
1351 plen = strlen(p_name);
1352 else
1353 plen = 0;
1354 t_name = afs_osi_Alloc(plen + 1);
1355 if (t_name == NULL) {
1356 if (tcell)
1357 afs_PutCell(tcell, READ_LOCK);
1358 RX_AFS_GUNLOCK();
1359 return ENOMEM;
1362 t_name[plen] = '\0';
1363 if (p_name)
1364 memcpy(t_name, p_name, plen);
1366 RX_AFS_GUNLOCK();
1368 *a_name = t_name;
1369 if (tcell)
1370 afs_PutCell(tcell, READ_LOCK);
1371 return 0;
1376 * afs_MarshallCacheConfig - marshall client cache configuration
1378 * PARAMETERS
1380 * IN callerVersion - the rpc stat version of the caller.
1382 * IN config - client cache configuration.
1384 * OUT ptr - buffer where configuration is marshalled.
1386 * RETURN CODES
1388 * Returns void.
1390 static void
1391 afs_MarshallCacheConfig(afs_uint32 callerVersion, cm_initparams_v1 * config,
1392 afs_uint32 * ptr)
1394 AFS_STATCNT(afs_MarshallCacheConfig);
1396 * We currently only support version 1.
1398 *(ptr++) = config->nChunkFiles;
1399 *(ptr++) = config->nStatCaches;
1400 *(ptr++) = config->nDataCaches;
1401 *(ptr++) = config->nVolumeCaches;
1402 *(ptr++) = config->firstChunkSize;
1403 *(ptr++) = config->otherChunkSize;
1404 *(ptr++) = config->cacheSize;
1405 *(ptr++) = config->setTime;
1406 *(ptr++) = config->memCache;
1410 /*------------------------------------------------------------------------
1411 * EXPORTED SRXAFSCB_GetCacheConfig
1413 * Description:
1414 * Routine to return parameters used to initialize client cache.
1415 * Client may request any format version. Server may not return
1416 * format version greater than version requested by client.
1418 * Arguments:
1419 * a_call: Ptr to Rx call on which this request came in.
1420 * callerVersion: Data format version desired by the client.
1421 * serverVersion: Data format version of output data.
1422 * configCount: Number bytes allocated for output data.
1423 * config: Client cache configuration.
1425 * Returns:
1426 * 0 on success
1428 * Environment:
1429 * Nothing interesting.
1431 * Side Effects:
1432 * As advertised.
1433 *------------------------------------------------------------------------*/
1436 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
1437 afs_uint32 * serverVersion, afs_uint32 * configCount,
1438 cacheConfig * config)
1440 afs_uint32 *t_config;
1441 size_t allocsize;
1442 cm_initparams_v1 cm_config;
1444 RX_AFS_GLOCK();
1445 AFS_STATCNT(SRXAFSCB_GetCacheConfig);
1448 * Currently only support version 1
1450 allocsize = sizeof(cm_initparams_v1);
1451 t_config = afs_osi_Alloc(allocsize);
1452 if (t_config == NULL) {
1453 RX_AFS_GUNLOCK();
1454 return ENOMEM;
1457 cm_config.nChunkFiles = cm_initParams.cmi_nChunkFiles;
1458 cm_config.nStatCaches = cm_initParams.cmi_nStatCaches;
1459 cm_config.nDataCaches = cm_initParams.cmi_nDataCaches;
1460 cm_config.nVolumeCaches = cm_initParams.cmi_nVolumeCaches;
1461 cm_config.firstChunkSize = cm_initParams.cmi_firstChunkSize;
1462 cm_config.otherChunkSize = cm_initParams.cmi_otherChunkSize;
1463 cm_config.cacheSize = cm_initParams.cmi_cacheSize;
1464 cm_config.setTime = cm_initParams.cmi_setTime;
1465 cm_config.memCache = cm_initParams.cmi_memCache;
1467 afs_MarshallCacheConfig(callerVersion, &cm_config, t_config);
1469 *serverVersion = AFS_CLIENT_RETRIEVAL_FIRST_EDITION;
1470 *configCount = allocsize;
1471 config->cacheConfig_val = t_config;
1472 config->cacheConfig_len = allocsize / sizeof(afs_uint32);
1474 RX_AFS_GUNLOCK();
1476 return 0;
1479 /*------------------------------------------------------------------------
1480 * EXPORTED SRXAFSCB_FetchData
1482 * Description:
1483 * Routine to do third party move from a remioserver to the original
1484 * issuer of an ArchiveData request. Presently supported only by the
1485 * "fs" command, not by the AFS client.
1487 * Arguments:
1488 * rxcall: Ptr to Rx call on which this request came in.
1489 * Fid: pointer to AFSFid structure.
1490 * Fd: File descriptor inside fs command.
1491 * Position: Offset in the file.
1492 * Length: Data length to transfer.
1493 * TotalLength: Pointer to total file length field
1495 * Returns:
1496 * 0 on success
1498 * Environment:
1499 * Nothing interesting.
1501 * Side Effects:
1502 *------------------------------------------------------------------------*/
1504 SRXAFSCB_FetchData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1505 afs_int64 Position, afs_int64 Length,
1506 afs_int64 * TotalLength)
1508 return ENOSYS;
1511 /*------------------------------------------------------------------------
1512 * EXPORTED SRXAFSCB_StoreData
1514 * Description:
1515 * Routine to do third party move from a remioserver to the original
1516 * issuer of a RetrieveData request. Presently supported only by the
1517 * "fs" command, not by the AFS client.
1519 * Arguments:
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
1527 * Returns:
1528 * 0 on success
1530 * Environment:
1531 * Nothing interesting.
1533 * Side Effects:
1534 * As advertised.
1535 *------------------------------------------------------------------------*/
1537 SRXAFSCB_StoreData(struct rx_call *rxcall, struct AFSFid *Fid, afs_int32 Fd,
1538 afs_int64 Position, afs_int64 Length,
1539 afs_int64 * TotalLength)
1541 return ENOSYS;
1544 /*------------------------------------------------------------------------
1545 * EXPORTED SRXAFSCB_GetCellByNum
1547 * Description:
1548 * Routine to get information about a cell specified by its
1549 * cell number (returned by GetCE/GetCE64).
1551 * Arguments:
1552 * a_call : Ptr to Rx call on which this request came in.
1553 * a_cellnum : Input cell number
1554 * a_name : Output cell name (one zero byte when no such cell).
1555 * a_hosts : Output cell database servers in host byte order.
1557 * Returns:
1558 * 0 on success
1560 * Environment:
1561 * Nothing interesting.
1563 * Side Effects:
1564 * As advertised.
1565 *------------------------------------------------------------------------*/
1568 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
1569 char **a_name, serverList * a_hosts)
1571 afs_int32 i, sn;
1572 struct cell *tcell;
1574 RX_AFS_GLOCK();
1575 AFS_STATCNT(SRXAFSCB_GetCellByNum);
1577 a_hosts->serverList_val = 0;
1578 a_hosts->serverList_len = 0;
1580 tcell = afs_GetCellStale(a_cellnum, READ_LOCK);
1581 if (!tcell) {
1582 *a_name = afs_strdup("");
1583 RX_AFS_GUNLOCK();
1584 return 0;
1587 ObtainReadLock(&tcell->lock);
1588 *a_name = afs_strdup(tcell->cellName);
1590 for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++);
1591 a_hosts->serverList_len = sn;
1592 a_hosts->serverList_val = afs_osi_Alloc(sn * sizeof(afs_int32));
1593 osi_Assert(a_hosts->serverList_val != NULL);
1595 for (i = 0; i < sn; i++)
1596 a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip);
1597 ReleaseReadLock(&tcell->lock);
1598 afs_PutCell(tcell, READ_LOCK);
1600 RX_AFS_GUNLOCK();
1601 return 0;
1605 SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call,
1606 struct interfaceAddr *addr,
1607 Capabilities * capabilities)
1609 int i;
1610 int code = 0;
1611 afs_uint32 *dataBuffP;
1612 afs_int32 dataBytes;
1614 RX_AFS_GLOCK();
1616 AFS_STATCNT(SRXAFSCB_WhoAreYou);
1618 ObtainReadLock(&afs_xinterface);
1620 /* return all network interface addresses */
1621 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
1622 addr->uuid = afs_cb_interface.uuid;
1623 for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
1624 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
1625 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
1626 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
1629 ReleaseReadLock(&afs_xinterface);
1631 RX_AFS_GUNLOCK();
1633 dataBytes = 1 * sizeof(afs_uint32);
1634 dataBuffP = afs_osi_Alloc(dataBytes);
1635 osi_Assert(dataBuffP != NULL);
1636 dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS;
1637 capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32);
1638 capabilities->Capabilities_val = dataBuffP;
1640 return code;
1644 #if 0 && defined(AFS_LINUX24_ENV)
1645 extern struct vcache *afs_globalVp;
1647 int recurse_dcache_parent(parent, a_index, addr, inode, flags, time, fileName)
1648 struct dentry * parent;
1649 afs_int32 a_index;
1650 afs_int32 *addr;
1651 afs_int32 *inode;
1652 afs_int32 *flags;
1653 afs_int32 *time;
1654 char ** fileName;
1656 struct dentry *this_parent = parent;
1657 struct list_head *next;
1658 int found = 0;
1659 struct dentry *dentry;
1661 repeat:
1662 next = this_parent->d_subdirs.next;
1663 resume:
1664 while (next != &this_parent->d_subdirs) {
1665 struct list_head *tmp = next;
1666 dentry = list_entry(tmp, struct dentry, d_child);
1667 if (a_index == 0)
1668 goto searchdone3;
1669 a_index--;
1670 next = tmp->next;
1672 * Descend a level if the d_subdirs list is non-empty.
1674 if (!list_empty(&dentry->d_subdirs)) {
1675 this_parent = dentry;
1676 goto repeat;
1680 * All done at this level ... ascend and resume the search.
1682 if (this_parent != parent) {
1683 next = this_parent->d_child.next;
1684 this_parent = this_parent->d_parent;
1685 goto resume;
1687 goto ret;
1689 searchdone3:
1690 if (d_unhashed(dentry))
1691 *flags = 1;
1692 else
1693 *flags = 0;
1695 *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
1696 *inode = ITOAFS(dentry->d_inode);
1697 *addr = atomic_read(&(dentry)->d_count);
1698 *time = dentry->d_time;
1700 return 0;
1701 ret:
1702 return 1;
1704 #endif
1707 SRXAFSCB_GetDE(struct rx_call *a_call, afs_int32 a_index, afs_int32 *addr,
1708 afs_int32 *inode, afs_int32 *flags, afs_int32 *time,
1709 char ** fileName)
1710 { /*SRXAFSCB_GetDE*/
1711 int code = 0; /*Return code*/
1712 #if 0 && defined(AFS_LINUX24_ENV)
1713 int i; /*Loop variable*/
1714 struct vcache *tvc = afs_globalVp;
1715 struct dentry *dentry;
1716 struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
1718 #ifdef RX_ENABLE_LOCKS
1719 AFS_GLOCK();
1720 #endif /* RX_ENABLE_LOCKS */
1722 #if defined(AFS_LINUX24_ENV)
1723 spin_lock(&dcache_lock);
1724 #endif
1726 cur = head;
1727 while ((cur = cur->next) != head) {
1728 dentry = list_entry(cur, struct dentry, d_alias);
1730 dget_locked(dentry);
1732 #if defined(AFS_LINUX24_ENV)
1733 spin_unlock(&dcache_lock);
1734 #endif
1735 if (a_index == 0)
1736 goto searchdone2;
1737 a_index--;
1739 if (recurse_dcache_parent(dentry, a_index, addr, inode, flags, time, fileName) == 0) {
1740 dput(dentry);
1741 code = 0;
1742 goto fcnDone;
1744 dput(dentry);
1746 searchdone2:
1747 if (cur == head) {
1748 /*Past EOF*/
1749 code = 1;
1750 *fileName = afs_strdup("");
1751 goto fcnDone;
1754 if (d_unhashed(dentry))
1755 *flags = 1;
1756 else
1757 *flags = 0;
1759 *fileName = afs_strdup(dentry->d_name.name?dentry->d_name.name:"");
1760 *inode = ITOAFS(dentry->d_inode);
1761 *addr = atomic_read(&(dentry)->d_count);
1762 *time = dentry->d_time;
1764 dput(dentry);
1765 code = 0;
1767 fcnDone:
1769 #ifdef RX_ENABLE_LOCKS
1770 AFS_GUNLOCK();
1771 #endif /* RX_ENABLE_LOCKS */
1772 #endif
1773 return(code);
1775 } /*SRXAFSCB_GetDE*/