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
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h"
17 #include "rx/rx_globals.h"
18 #if !defined(UKERNEL) && !defined(AFS_LINUX20_ENV)
21 #include "h/hashing.h"
23 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN60_ENV)
24 #include "netinet/in_var.h"
26 #endif /* !defined(UKERNEL) */
27 #ifdef AFS_LINUX22_ENV
28 #include "h/smp_lock.h"
32 struct afs_icl_set *afs_iclSetp = (struct afs_icl_set *)0;
33 struct afs_icl_set *afs_iclLongTermSetp = (struct afs_icl_set *)0;
35 #if defined(AFS_SGI61_ENV)
36 /* For SGI 6.2, this can is changed to 1 if it's a 32 bit kernel. */
37 #if defined(AFS_SGI62_ENV) && defined(KERNEL) && !defined(_K64U64)
38 int afs_icl_sizeofLong = 1;
40 int afs_icl_sizeofLong = 2;
43 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
44 int afs_icl_sizeofLong = 2;
46 int afs_icl_sizeofLong = 1;
50 int afs_icl_inited = 0;
52 /* init function, called once, under afs_icl_lock */
60 /* Function called at shutdown - zap everything */
64 struct afs_icl_log *logp;
65 struct afs_icl_set *setp;
67 setp = afs_icl_FindSet("cm");
69 /* Release the reference from Find, and the initial one */
70 afs_icl_SetFree(setp);
71 afs_icl_SetFree(setp);
73 setp = afs_icl_FindSet("cmlongterm");
75 /* Release the reference from Find, and the initial one */
76 afs_icl_SetFree(setp);
77 afs_icl_SetFree(setp);
79 logp = afs_icl_FindLog("cmfx");
81 /* Release the reference from Find, and the initial one */
82 afs_icl_LogFree(logp);
83 afs_icl_LogFree(logp);
88 afs_icl_InitLogs(void)
90 struct afs_icl_log *logp;
93 /* initialize the ICL system */
94 code = afs_icl_CreateLog("cmfx", 60 * 1024, &logp);
97 afs_icl_CreateSetWithFlags("cm", logp, NULL,
98 ICL_CRSET_FLAG_DEFAULT_OFF,
101 afs_icl_CreateSet("cmlongterm", logp, NULL,
102 &afs_iclLongTermSetp);
107 struct afs_icl_log *afs_icl_FindLog(char *);
108 struct afs_icl_set *afs_icl_FindSet(char *);
111 #ifdef AFS_DARWIN100_ENV
112 #define AFSKPTR(X) k ## X
114 Afscall_icl(long opcode, long p1, long p2, long p3, long p4, long *retval)
116 return Afscall64_icl(opcode,
117 CAST_USER_ADDR_T((p1)),
118 CAST_USER_ADDR_T((p2)),
119 CAST_USER_ADDR_T((p3)),
120 CAST_USER_ADDR_T((p4)),
124 #define AFSKPTR(X) ((caddr_t)X)
128 #ifdef AFS_DARWIN100_ENV
129 Afscall64_icl(int opcode, user_addr_t kp1, user_addr_t kp2, user_addr_t kp3, user_addr_t kp4, int *retval)
131 Afscall_icl(long opcode, long p1, long p2, long p3, long p4, long *retval)
134 afs_int32 *lp, elts, flags;
135 register afs_int32 code;
136 struct afs_icl_log *logp;
137 struct afs_icl_set *setp;
138 #if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
140 #else /* AFS_SGI61_ENV */
141 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
146 #endif /* AFS_SGI61_ENV */
148 afs_int32 startCookie;
150 struct afs_icl_log *tlp;
151 #ifdef AFS_DARWIN100_ENV
152 afs_uint32 p1 = (afs_uint32)kp1;
153 afs_uint32 p2 = (afs_uint32)kp2;
154 afs_uint32 p3 = (afs_uint32)kp3;
155 afs_uint32 p4 = (afs_uint32)kp4;
159 if (!afs_suser(CRED())) { /* only root can run this code */
163 if (!afs_suser(NULL)) { /* only root can run this code */
164 #if defined(KERNEL_HAVE_UERROR)
173 case ICL_OP_COPYOUTCLR: /* copy out data then clear */
174 case ICL_OP_COPYOUT: /* copy ouy data */
175 /* copyout: p1=logname, p2=&buffer, p3=size(words), p4=&cookie
176 * return flags<<24 + nwords.
177 * updates cookie to updated start (not end) if we had to
180 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
183 AFS_COPYIN(AFSKPTR(p4), (char *)&startCookie, sizeof(afs_int32), code);
186 logp = afs_icl_FindLog(tname);
189 #define BUFFERSIZE AFS_LRALLOCSIZ
190 lp = (afs_int32 *) osi_AllocLargeSpace(AFS_LRALLOCSIZ);
191 elts = BUFFERSIZE / sizeof(afs_int32);
194 flags = (opcode == ICL_OP_COPYOUT) ? 0 : ICL_COPYOUTF_CLRAFTERREAD;
196 afs_icl_CopyOut(logp, lp, &elts, (afs_uint32 *) & startCookie,
199 osi_FreeLargeSpace((struct osi_buffer *)lp);
202 AFS_COPYOUT((char *)lp, AFSKPTR(p2), elts * sizeof(afs_int32), code);
205 AFS_COPYOUT((char *)&startCookie, AFSKPTR(p4), sizeof(afs_int32),
209 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
211 *retval = ((long)((flags << 24) | (elts & 0xffffff))) << 32;
214 *retval = (flags << 24) | (elts & 0xffffff);
216 afs_icl_LogRele(logp);
217 osi_FreeLargeSpace((struct osi_buffer *)lp);
220 case ICL_OP_ENUMLOGS: /* enumerate logs */
221 /* enumerate logs: p1=index, p2=&name, p3=sizeof(name), p4=&size.
222 * return 0 for success, otherwise error.
224 for (tlp = afs_icl_allLogs; tlp; tlp = tlp->nextp) {
229 return ENOENT; /* past the end of file */
230 temp = strlen(tlp->name) + 1;
233 AFS_COPYOUT(tlp->name, AFSKPTR(p2), temp, code);
234 if (!code) /* copy out size of log */
235 AFS_COPYOUT((char *)&tlp->logSize, AFSKPTR(p4), sizeof(afs_int32),
239 case ICL_OP_ENUMLOGSBYSET: /* enumerate logs by set name */
240 /* enumerate logs: p1=setname, p2=index, p3=&name, p4=sizeof(name).
241 * return 0 for success, otherwise error.
243 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
246 setp = afs_icl_FindSet(tname);
249 if (p2 > ICL_LOGSPERSET)
251 if (!(tlp = setp->logs[p2]))
253 temp = strlen(tlp->name) + 1;
256 AFS_COPYOUT(tlp->name, AFSKPTR(p3), temp, code);
259 case ICL_OP_CLRLOG: /* clear specified log */
260 /* zero out the specified log: p1=logname */
261 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
264 logp = afs_icl_FindLog(tname);
267 code = afs_icl_ZeroLog(logp);
268 afs_icl_LogRele(logp);
271 case ICL_OP_CLRSET: /* clear specified set */
272 /* zero out the specified set: p1=setname */
273 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
276 setp = afs_icl_FindSet(tname);
279 code = afs_icl_ZeroSet(setp);
280 afs_icl_SetRele(setp);
283 case ICL_OP_CLRALL: /* clear all logs */
284 /* zero out all logs -- no args */
286 ObtainWriteLock(&afs_icl_lock, 178);
287 for (tlp = afs_icl_allLogs; tlp; tlp = tlp->nextp) {
288 tlp->refCount++; /* hold this guy */
289 ReleaseWriteLock(&afs_icl_lock);
290 /* don't clear persistent logs */
291 if ((tlp->states & ICL_LOGF_PERSISTENT) == 0)
292 code = afs_icl_ZeroLog(tlp);
293 ObtainWriteLock(&afs_icl_lock, 179);
294 if (--tlp->refCount == 0)
299 ReleaseWriteLock(&afs_icl_lock);
302 case ICL_OP_ENUMSETS: /* enumerate all sets */
303 /* enumerate sets: p1=index, p2=&name, p3=sizeof(name), p4=&states.
304 * return 0 for success, otherwise error.
306 for (setp = afs_icl_allSets; setp; setp = setp->nextp) {
311 return ENOENT; /* past the end of file */
312 temp = strlen(setp->name) + 1;
315 AFS_COPYOUT(setp->name, AFSKPTR(p2), temp, code);
316 if (!code) /* copy out size of log */
317 AFS_COPYOUT((char *)&setp->states, AFSKPTR(p4), sizeof(afs_int32),
321 case ICL_OP_SETSTAT: /* set status on a set */
322 /* activate the specified set: p1=setname, p2=op */
323 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
326 setp = afs_icl_FindSet(tname);
329 code = afs_icl_SetSetStat(setp, p2);
330 afs_icl_SetRele(setp);
333 case ICL_OP_SETSTATALL: /* set status on all sets */
334 /* activate the specified set: p1=op */
336 ObtainWriteLock(&afs_icl_lock, 180);
337 for (setp = afs_icl_allSets; setp; setp = setp->nextp) {
338 setp->refCount++; /* hold this guy */
339 ReleaseWriteLock(&afs_icl_lock);
340 /* don't set states on persistent sets */
341 if ((setp->states & ICL_SETF_PERSISTENT) == 0)
342 code = afs_icl_SetSetStat(setp, p1);
343 ObtainWriteLock(&afs_icl_lock, 181);
344 if (--setp->refCount == 0)
345 afs_icl_ZapSet(setp);
349 ReleaseWriteLock(&afs_icl_lock);
352 case ICL_OP_SETLOGSIZE: /* set size of log */
353 /* set the size of the specified log: p1=logname, p2=size (in words) */
354 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
357 logp = afs_icl_FindLog(tname);
360 code = afs_icl_LogSetSize(logp, p2);
361 afs_icl_LogRele(logp);
364 case ICL_OP_GETLOGINFO: /* get size of log */
365 /* zero out the specified log: p1=logname, p2=&logSize, p3=&allocated */
366 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
369 logp = afs_icl_FindLog(tname);
372 allocated = !!logp->datap;
373 AFS_COPYOUT((char *)&logp->logSize, AFSKPTR(p2), sizeof(afs_int32),
376 AFS_COPYOUT((char *)&allocated, AFSKPTR(p3), sizeof(afs_int32),
378 afs_icl_LogRele(logp);
381 case ICL_OP_GETSETINFO: /* get state of set */
382 /* zero out the specified set: p1=setname, p2=&state */
383 AFS_COPYINSTR(AFSKPTR(p1), tname, sizeof(tname), &temp, code);
386 setp = afs_icl_FindSet(tname);
389 AFS_COPYOUT((char *)&setp->states, AFSKPTR(p2), sizeof(afs_int32),
391 afs_icl_SetRele(setp);
402 afs_lock_t afs_icl_lock;
404 /* exported routine: a 4 parameter event */
406 afs_icl_Event4(register struct afs_icl_set *setp, afs_int32 eventID,
407 afs_int32 lAndT, long p1, long p2, long p3, long p4)
411 register afs_int32 tmask;
414 /* If things aren't init'ed yet (or the set is inactive), don't panic */
415 if (!ICL_SETACTIVE(setp))
419 mask = lAndT >> 24 & 0xff; /* mask of which logs to log to */
420 ix = ICL_EVENTBYTE(eventID);
421 ObtainReadLock(&setp->lock);
422 if (setp->eventFlags[ix] & ICL_EVENTMASK(eventID)) {
423 for (i = 0, tmask = 1; i < ICL_LOGSPERSET; i++, tmask <<= 1) {
425 afs_icl_AppendRecord(setp->logs[i], eventID, lAndT & 0xffffff,
430 break; /* break early */
433 ReleaseReadLock(&setp->lock);
437 /* Next 4 routines should be implemented via var-args or something.
438 * Whole purpose is to avoid compiler warnings about parameter # mismatches.
439 * Otherwise, could call afs_icl_Event4 directly.
442 afs_icl_Event3(register struct afs_icl_set *setp, afs_int32 eventID,
443 afs_int32 lAndT, long p1, long p2, long p3)
445 return afs_icl_Event4(setp, eventID, lAndT, p1, p2, p3, (long)0);
449 afs_icl_Event2(register struct afs_icl_set *setp, afs_int32 eventID,
450 afs_int32 lAndT, long p1, long p2)
452 return afs_icl_Event4(setp, eventID, lAndT, p1, p2, (long)0, (long)0);
456 afs_icl_Event1(register struct afs_icl_set *setp, afs_int32 eventID,
457 afs_int32 lAndT, long p1)
459 return afs_icl_Event4(setp, eventID, lAndT, p1, (long)0, (long)0,
464 afs_icl_Event0(register struct afs_icl_set *setp, afs_int32 eventID,
467 return afs_icl_Event4(setp, eventID, lAndT, (long)0, (long)0, (long)0,
471 struct afs_icl_log *afs_icl_allLogs = 0;
473 /* function to purge records from the start of the log, until there
474 * is at least minSpace long's worth of space available without
475 * making the head and the tail point to the same word.
477 * Log must be write-locked.
480 afs_icl_GetLogSpace(register struct afs_icl_log *logp, afs_int32 minSpace)
482 register unsigned int tsize;
484 while (logp->logSize - logp->logElements <= minSpace) {
486 tsize = ((logp->datap[logp->firstUsed]) >> 24) & 0xff;
487 logp->logElements -= tsize;
488 logp->firstUsed += tsize;
489 if (logp->firstUsed >= logp->logSize)
490 logp->firstUsed -= logp->logSize;
491 logp->baseCookie += tsize;
495 /* append string astr to buffer, including terminating null char.
497 * log must be write-locked.
499 #define ICL_CHARSPERLONG 4
501 afs_icl_AppendString(struct afs_icl_log *logp, char *astr)
503 char *op; /* ptr to char to write */
505 register int bib; /* bytes in buffer */
508 op = (char *)&(logp->datap[logp->firstFree]);
512 if (++bib >= ICL_CHARSPERLONG) {
515 if (++(logp->firstFree) >= logp->logSize) {
517 op = (char *)&(logp->datap[0]);
525 /* if we've used this word at all, allocate it */
526 if (++(logp->firstFree) >= logp->logSize) {
533 /* add a long to the log, ignoring overflow (checked already) */
534 #define ICL_APPENDINT32(lp, x) \
536 (lp)->datap[(lp)->firstFree] = (x); \
537 if (++((lp)->firstFree) >= (lp)->logSize) { \
538 (lp)->firstFree = 0; \
540 (lp)->logElements++; \
543 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_DARWIN_ENV) && defined(__amd64__)
544 #define ICL_APPENDLONG(lp, x) \
546 ICL_APPENDINT32((lp), ((x) >> 32) & 0xffffffffL); \
547 ICL_APPENDINT32((lp), (x) & 0xffffffffL); \
551 #define ICL_APPENDLONG(lp, x) ICL_APPENDINT32((lp), (x))
554 /* routine to tell whether we're dealing with the address or the
558 afs_icl_UseAddr(int type)
560 if (type == ICL_TYPE_HYPER || type == ICL_TYPE_STRING
561 || type == ICL_TYPE_FID || type == ICL_TYPE_INT64)
567 /* Function to append a record to the log. Written for speed
568 * since we know that we're going to have to make this work fast
569 * pretty soon, anyway. The log must be unlocked.
573 afs_icl_AppendRecord(register struct afs_icl_log *logp, afs_int32 op,
574 afs_int32 types, long p1, long p2, long p3, long p4)
576 int rsize; /* record size in longs */
577 register int tsize; /* temp size */
581 t4 = types & 0x3f; /* decode types */
589 osi_GetTime(&tv); /* It panics for solaris if inside */
590 ObtainWriteLock(&logp->lock, 182);
592 ReleaseWriteLock(&logp->lock);
596 /* get timestamp as # of microseconds since some time that doesn't
597 * change that often. This algorithm ticks over every 20 minutes
598 * or so (1000 seconds). Write a timestamp record if it has.
600 if (tv.tv_sec - logp->lastTS > 1024) {
601 /* the timer has wrapped -- write a timestamp record */
602 if (logp->logSize - logp->logElements <= 5)
603 afs_icl_GetLogSpace(logp, 5);
605 ICL_APPENDINT32(logp,
606 (afs_int32) (5 << 24) + (ICL_TYPE_UNIXDATE << 18));
607 ICL_APPENDINT32(logp, (afs_int32) ICL_INFO_TIMESTAMP);
608 ICL_APPENDINT32(logp, (afs_int32) 0); /* use thread ID zero for clocks */
609 ICL_APPENDINT32(logp,
610 (afs_int32) (tv.tv_sec & 0x3ff) * 1000000 +
612 ICL_APPENDINT32(logp, (afs_int32) tv.tv_sec);
614 logp->lastTS = tv.tv_sec;
617 rsize = 4; /* base case */
619 /* compute size of parameter p1. Only tricky case is string.
620 * In that case, we have to call strlen to get the string length.
622 ICL_SIZEHACK(t1, p1);
625 /* compute size of parameter p2. Only tricky case is string.
626 * In that case, we have to call strlen to get the string length.
628 ICL_SIZEHACK(t2, p2);
631 /* compute size of parameter p3. Only tricky case is string.
632 * In that case, we have to call strlen to get the string length.
634 ICL_SIZEHACK(t3, p3);
637 /* compute size of parameter p4. Only tricky case is string.
638 * In that case, we have to call strlen to get the string length.
640 ICL_SIZEHACK(t4, p4);
643 /* At this point, we've computed all of the parameter sizes, and
644 * have in rsize the size of the entire record we want to append.
645 * Next, we check that we actually have room in the log to do this
646 * work, and then we do the append.
649 ReleaseWriteLock(&logp->lock);
650 return; /* log record too big to express */
653 if (logp->logSize - logp->logElements <= rsize)
654 afs_icl_GetLogSpace(logp, rsize);
656 ICL_APPENDINT32(logp,
657 (afs_int32) (rsize << 24) + (t1 << 18) + (t2 << 12) +
659 ICL_APPENDINT32(logp, (afs_int32) op);
660 ICL_APPENDINT32(logp, (afs_int32) osi_ThreadUnique());
661 ICL_APPENDINT32(logp,
662 (afs_int32) (tv.tv_sec & 0x3ff) * 1000000 + tv.tv_usec);
665 /* marshall parameter 1 now */
666 if (t1 == ICL_TYPE_STRING) {
667 afs_icl_AppendString(logp, (char *)p1);
668 } else if (t1 == ICL_TYPE_HYPER) {
669 ICL_APPENDINT32(logp,
670 (afs_int32) ((struct afs_hyper_t *)p1)->high);
671 ICL_APPENDINT32(logp,
672 (afs_int32) ((struct afs_hyper_t *)p1)->low);
673 } else if (t1 == ICL_TYPE_INT64) {
674 #ifndef WORDS_BIGENDIAN
675 #ifdef AFS_64BIT_CLIENT
676 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[1]);
677 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[0]);
678 #else /* AFS_64BIT_CLIENT */
679 ICL_APPENDINT32(logp, (afs_int32) p1);
680 ICL_APPENDINT32(logp, (afs_int32) 0);
681 #endif /* AFS_64BIT_CLIENT */
682 #else /* AFSLITTLE_ENDIAN */
683 #ifdef AFS_64BIT_CLIENT
684 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[0]);
685 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[1]);
686 #else /* AFS_64BIT_CLIENT */
687 ICL_APPENDINT32(logp, (afs_int32) 0);
688 ICL_APPENDINT32(logp, (afs_int32) p1);
689 #endif /* AFS_64BIT_CLIENT */
690 #endif /* AFSLITTLE_ENDIAN */
691 } else if (t1 == ICL_TYPE_FID) {
692 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[0]);
693 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[1]);
694 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[2]);
695 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[3]);
697 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
698 else if (t1 == ICL_TYPE_INT32)
699 ICL_APPENDINT32(logp, (afs_int32) p1);
702 ICL_APPENDLONG(logp, p1);
705 /* marshall parameter 2 now */
706 if (t2 == ICL_TYPE_STRING)
707 afs_icl_AppendString(logp, (char *)p2);
708 else if (t2 == ICL_TYPE_HYPER) {
709 ICL_APPENDINT32(logp,
710 (afs_int32) ((struct afs_hyper_t *)p2)->high);
711 ICL_APPENDINT32(logp,
712 (afs_int32) ((struct afs_hyper_t *)p2)->low);
713 } else if (t2 == ICL_TYPE_INT64) {
714 #ifndef WORDS_BIGENDIAN
715 #ifdef AFS_64BIT_CLIENT
716 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[1]);
717 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[0]);
718 #else /* AFS_64BIT_CLIENT */
719 ICL_APPENDINT32(logp, (afs_int32) p2);
720 ICL_APPENDINT32(logp, (afs_int32) 0);
721 #endif /* AFS_64BIT_CLIENT */
722 #else /* AFSLITTLE_ENDIAN */
723 #ifdef AFS_64BIT_CLIENT
724 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[0]);
725 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[1]);
726 #else /* AFS_64BIT_CLIENT */
727 ICL_APPENDINT32(logp, (afs_int32) 0);
728 ICL_APPENDINT32(logp, (afs_int32) p2);
729 #endif /* AFS_64BIT_CLIENT */
730 #endif /* AFSLITTLE_ENDIAN */
731 } else if (t2 == ICL_TYPE_FID) {
732 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[0]);
733 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[1]);
734 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[2]);
735 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[3]);
737 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
738 else if (t2 == ICL_TYPE_INT32)
739 ICL_APPENDINT32(logp, (afs_int32) p2);
742 ICL_APPENDLONG(logp, p2);
745 /* marshall parameter 3 now */
746 if (t3 == ICL_TYPE_STRING)
747 afs_icl_AppendString(logp, (char *)p3);
748 else if (t3 == ICL_TYPE_HYPER) {
749 ICL_APPENDINT32(logp,
750 (afs_int32) ((struct afs_hyper_t *)p3)->high);
751 ICL_APPENDINT32(logp,
752 (afs_int32) ((struct afs_hyper_t *)p3)->low);
753 } else if (t3 == ICL_TYPE_INT64) {
754 #ifndef WORDS_BIGENDIAN
755 #ifdef AFS_64BIT_CLIENT
756 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[1]);
757 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[0]);
758 #else /* AFS_64BIT_CLIENT */
759 ICL_APPENDINT32(logp, (afs_int32) p3);
760 ICL_APPENDINT32(logp, (afs_int32) 0);
761 #endif /* AFS_64BIT_CLIENT */
762 #else /* AFSLITTLE_ENDIAN */
763 #ifdef AFS_64BIT_CLIENT
764 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[0]);
765 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[1]);
766 #else /* AFS_64BIT_CLIENT */
767 ICL_APPENDINT32(logp, (afs_int32) 0);
768 ICL_APPENDINT32(logp, (afs_int32) p3);
769 #endif /* AFS_64BIT_CLIENT */
770 #endif /* AFSLITTLE_ENDIAN */
771 } else if (t3 == ICL_TYPE_FID) {
772 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[0]);
773 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[1]);
774 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[2]);
775 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[3]);
777 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
778 else if (t3 == ICL_TYPE_INT32)
779 ICL_APPENDINT32(logp, (afs_int32) p3);
782 ICL_APPENDLONG(logp, p3);
785 /* marshall parameter 4 now */
786 if (t4 == ICL_TYPE_STRING)
787 afs_icl_AppendString(logp, (char *)p4);
788 else if (t4 == ICL_TYPE_HYPER) {
789 ICL_APPENDINT32(logp,
790 (afs_int32) ((struct afs_hyper_t *)p4)->high);
791 ICL_APPENDINT32(logp,
792 (afs_int32) ((struct afs_hyper_t *)p4)->low);
793 } else if (t4 == ICL_TYPE_INT64) {
794 #ifndef WORDS_BIGENDIAN
795 #ifdef AFS_64BIT_CLIENT
796 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[1]);
797 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[0]);
798 #else /* AFS_64BIT_CLIENT */
799 ICL_APPENDINT32(logp, (afs_int32) p4);
800 ICL_APPENDINT32(logp, (afs_int32) 0);
801 #endif /* AFS_64BIT_CLIENT */
802 #else /* AFSLITTLE_ENDIAN */
803 #ifdef AFS_64BIT_CLIENT
804 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[0]);
805 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[1]);
806 #else /* AFS_64BIT_CLIENT */
807 ICL_APPENDINT32(logp, (afs_int32) 0);
808 ICL_APPENDINT32(logp, (afs_int32) p4);
809 #endif /* AFS_64BIT_CLIENT */
810 #endif /* AFSLITTLE_ENDIAN */
811 } else if (t4 == ICL_TYPE_FID) {
812 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[0]);
813 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[1]);
814 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[2]);
815 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[3]);
817 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
818 else if (t4 == ICL_TYPE_INT32)
819 ICL_APPENDINT32(logp, (afs_int32) p4);
822 ICL_APPENDLONG(logp, p4);
824 ReleaseWriteLock(&logp->lock);
827 /* create a log with size logSize; return it in *outLogpp and tag
828 * it with name "name."
831 afs_icl_CreateLog(char *name, afs_int32 logSize,
832 struct afs_icl_log **outLogpp)
834 return afs_icl_CreateLogWithFlags(name, logSize, /*flags */ 0, outLogpp);
837 /* create a log with size logSize; return it in *outLogpp and tag
838 * it with name "name." 'flags' can be set to make the log unclearable.
841 afs_icl_CreateLogWithFlags(char *name, afs_int32 logSize, afs_uint32 flags,
842 struct afs_icl_log **outLogpp)
844 register struct afs_icl_log *logp;
846 /* add into global list under lock */
847 ObtainWriteLock(&afs_icl_lock, 183);
851 for (logp = afs_icl_allLogs; logp; logp = logp->nextp) {
852 if (strcmp(logp->name, name) == 0) {
853 /* found it already created, just return it */
856 if (flags & ICL_CRLOG_FLAG_PERSISTENT) {
857 ObtainWriteLock(&logp->lock, 184);
858 logp->states |= ICL_LOGF_PERSISTENT;
859 ReleaseWriteLock(&logp->lock);
861 ReleaseWriteLock(&afs_icl_lock);
866 logp = (struct afs_icl_log *)
867 osi_AllocSmallSpace(sizeof(struct afs_icl_log));
868 memset((caddr_t) logp, 0, sizeof(*logp));
871 logp->name = osi_AllocSmallSpace(strlen(name) + 1);
872 strcpy(logp->name, name);
873 LOCK_INIT(&logp->lock, "logp lock");
874 logp->logSize = logSize;
875 logp->datap = NULL; /* don't allocate it until we need it */
877 if (flags & ICL_CRLOG_FLAG_PERSISTENT)
878 logp->states |= ICL_LOGF_PERSISTENT;
880 logp->nextp = afs_icl_allLogs;
881 afs_icl_allLogs = logp;
882 ReleaseWriteLock(&afs_icl_lock);
888 /* called with a log, a pointer to a buffer, the size of the buffer
889 * (in *bufSizep), the starting cookie (in *cookiep, use 0 at the start)
890 * and returns data in the provided buffer, and returns output flags
891 * in *flagsp. The flag ICL_COPYOUTF_MISSEDSOME is set if we can't
892 * find the record with cookie value cookie.
895 afs_icl_CopyOut(register struct afs_icl_log *logp, afs_int32 * bufferp,
896 afs_int32 * bufSizep, afs_uint32 * cookiep,
899 afs_int32 nwords; /* number of words to copy out */
900 afs_uint32 startCookie; /* first cookie to use */
901 afs_int32 outWords; /* words we've copied out */
902 afs_int32 inWords; /* max words to copy out */
903 afs_int32 code; /* return code */
904 afs_int32 ix; /* index we're copying from */
905 afs_int32 outFlags; /* return flags */
906 afs_int32 inFlags; /* flags passed in */
909 inWords = *bufSizep; /* max to copy out */
910 outWords = 0; /* amount copied out */
911 startCookie = *cookiep;
916 ObtainWriteLock(&logp->lock, 185);
918 ReleaseWriteLock(&logp->lock);
922 /* first, compute the index of the start cookie we've been passed */
924 /* (re-)compute where we should start */
925 if (startCookie < logp->baseCookie) {
926 if (startCookie) /* missed some output */
927 outFlags |= ICL_COPYOUTF_MISSEDSOME;
928 /* skip to the first available record */
929 startCookie = logp->baseCookie;
930 *cookiep = startCookie;
933 /* compute where we find the first element to copy out */
934 ix = logp->firstUsed + startCookie - logp->baseCookie;
935 if (ix >= logp->logSize)
938 /* if have some data now, break out and process it */
939 if (startCookie - logp->baseCookie < logp->logElements)
942 /* At end of log, so clear it if we need to */
943 if (inFlags & ICL_COPYOUTF_CLRAFTERREAD) {
944 logp->firstUsed = logp->firstFree = 0;
945 logp->logElements = 0;
947 /* otherwise, either wait for the data to arrive, or return */
948 if (!(inFlags & ICL_COPYOUTF_WAITIO)) {
949 ReleaseWriteLock(&logp->lock);
953 logp->states |= ICL_LOGF_WAITING;
954 ReleaseWriteLock(&logp->lock);
955 afs_osi_Sleep(&logp->lock);
956 ObtainWriteLock(&logp->lock, 186);
958 /* copy out data from ix to logSize or firstFree, depending
959 * upon whether firstUsed <= firstFree (no wrap) or otherwise.
960 * be careful not to copy out more than nwords.
962 if (ix >= logp->firstUsed) {
963 if (logp->firstUsed <= logp->firstFree)
965 end = logp->firstFree; /* first element not to copy */
968 nwords = inWords; /* don't copy more than this */
969 if (end - ix < nwords)
972 memcpy((char *)bufferp, (char *)&logp->datap[ix],
973 sizeof(afs_int32) * nwords);
978 /* if we're going to copy more out below, we'll start here */
981 /* now, if active part of the log has wrapped, there's more stuff
982 * starting at the head of the log. Copy out more from there.
984 if (logp->firstUsed > logp->firstFree && ix < logp->firstFree
986 /* (more to) copy out from the wrapped section at the
987 * start of the log. May get here even if didn't copy any
988 * above, if the cookie points directly into the wrapped section.
991 if (logp->firstFree - ix < nwords)
992 nwords = logp->firstFree - ix;
993 memcpy((char *)bufferp, (char *)&logp->datap[ix],
994 sizeof(afs_int32) * nwords);
1000 ReleaseWriteLock(&logp->lock);
1004 *bufSizep = outWords;
1010 /* return basic parameter information about a log */
1012 afs_icl_GetLogParms(struct afs_icl_log *logp, afs_int32 * maxSizep,
1013 afs_int32 * curSizep)
1015 ObtainReadLock(&logp->lock);
1016 *maxSizep = logp->logSize;
1017 *curSizep = logp->logElements;
1018 ReleaseReadLock(&logp->lock);
1023 /* hold and release logs */
1025 afs_icl_LogHold(register struct afs_icl_log *logp)
1027 ObtainWriteLock(&afs_icl_lock, 187);
1029 ReleaseWriteLock(&afs_icl_lock);
1033 /* hold and release logs, called with lock already held */
1035 afs_icl_LogHoldNL(register struct afs_icl_log *logp)
1041 /* keep track of how many sets believe the log itself is allocated */
1043 afs_icl_LogUse(register struct afs_icl_log *logp)
1045 ObtainWriteLock(&logp->lock, 188);
1046 if (logp->setCount == 0) {
1047 /* this is the first set actually using the log -- allocate it */
1048 if (logp->logSize == 0) {
1049 /* we weren't passed in a hint and it wasn't set */
1050 logp->logSize = ICL_DEFAULT_LOGSIZE;
1053 (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * logp->logSize);
1054 #ifdef KERNEL_HAVE_PIN
1055 pin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1059 ReleaseWriteLock(&logp->lock);
1063 /* decrement the number of real users of the log, free if possible */
1065 afs_icl_LogFreeUse(register struct afs_icl_log *logp)
1067 ObtainWriteLock(&logp->lock, 189);
1068 if (--logp->setCount == 0) {
1069 /* no more users -- free it (but keep log structure around) */
1070 afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1071 #ifdef KERNEL_HAVE_PIN
1072 unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1074 logp->firstUsed = logp->firstFree = 0;
1075 logp->logElements = 0;
1078 ReleaseWriteLock(&logp->lock);
1082 /* set the size of the log to 'logSize' */
1084 afs_icl_LogSetSize(register struct afs_icl_log *logp, afs_int32 logSize)
1086 ObtainWriteLock(&logp->lock, 190);
1088 /* nothing to worry about since it's not allocated */
1089 logp->logSize = logSize;
1092 logp->firstUsed = logp->firstFree = 0;
1093 logp->logElements = 0;
1095 /* free and allocate a new one */
1096 afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1097 #ifdef KERNEL_HAVE_PIN
1098 unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1101 (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * logSize);
1102 #ifdef KERNEL_HAVE_PIN
1103 pin((char *)logp->datap, sizeof(afs_int32) * logSize);
1105 logp->logSize = logSize;
1107 ReleaseWriteLock(&logp->lock);
1112 /* free a log. Called with afs_icl_lock locked. */
1114 afs_icl_ZapLog(register struct afs_icl_log *logp)
1116 register struct afs_icl_log **lpp, *tp;
1118 for (lpp = &afs_icl_allLogs, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1120 /* found the dude we want to remove */
1122 osi_FreeSmallSpace(logp->name);
1123 afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1124 #ifdef KERNEL_HAVE_PIN
1125 unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1127 osi_FreeSmallSpace(logp);
1128 break; /* won't find it twice */
1134 /* do the release, watching for deleted entries */
1136 afs_icl_LogRele(register struct afs_icl_log *logp)
1138 ObtainWriteLock(&afs_icl_lock, 191);
1139 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1140 afs_icl_ZapLog(logp); /* destroys logp's lock! */
1142 ReleaseWriteLock(&afs_icl_lock);
1146 /* do the release, watching for deleted entries, log already held */
1148 afs_icl_LogReleNL(register struct afs_icl_log *logp)
1150 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1151 afs_icl_ZapLog(logp); /* destroys logp's lock! */
1156 /* zero out the log */
1158 afs_icl_ZeroLog(register struct afs_icl_log *logp)
1160 ObtainWriteLock(&logp->lock, 192);
1161 logp->firstUsed = logp->firstFree = 0;
1162 logp->logElements = 0;
1163 logp->baseCookie = 0;
1164 ReleaseWriteLock(&logp->lock);
1168 /* free a log entry, and drop its reference count */
1170 afs_icl_LogFree(register struct afs_icl_log *logp)
1172 ObtainWriteLock(&logp->lock, 193);
1173 logp->states |= ICL_LOGF_DELETED;
1174 ReleaseWriteLock(&logp->lock);
1175 afs_icl_LogRele(logp);
1179 /* find a log by name, returning it held */
1180 struct afs_icl_log *
1181 afs_icl_FindLog(char *name)
1183 register struct afs_icl_log *tp;
1184 ObtainWriteLock(&afs_icl_lock, 194);
1185 for (tp = afs_icl_allLogs; tp; tp = tp->nextp) {
1186 if (strcmp(tp->name, name) == 0) {
1187 /* this is the dude we want */
1192 ReleaseWriteLock(&afs_icl_lock);
1197 afs_icl_EnumerateLogs(int (*aproc)
1198 (char *name, char *arock, struct afs_icl_log * tp),
1201 register struct afs_icl_log *tp;
1202 register afs_int32 code;
1205 ObtainWriteLock(&afs_icl_lock, 195);
1206 for (tp = afs_icl_allLogs; tp; tp = tp->nextp) {
1207 tp->refCount++; /* hold this guy */
1208 ReleaseWriteLock(&afs_icl_lock);
1209 ObtainReadLock(&tp->lock);
1210 code = (*aproc) (tp->name, arock, tp);
1211 ReleaseReadLock(&tp->lock);
1212 ObtainWriteLock(&afs_icl_lock, 196);
1213 if (--tp->refCount == 0)
1218 ReleaseWriteLock(&afs_icl_lock);
1222 struct afs_icl_set *afs_icl_allSets = 0;
1225 afs_icl_CreateSet(char *name, struct afs_icl_log *baseLogp,
1226 struct afs_icl_log *fatalLogp,
1227 struct afs_icl_set **outSetpp)
1229 return afs_icl_CreateSetWithFlags(name, baseLogp, fatalLogp,
1230 /*flags */ 0, outSetpp);
1233 /* create a set, given pointers to base and fatal logs, if any.
1234 * Logs are unlocked, but referenced, and *outSetpp is returned
1235 * referenced. Function bumps reference count on logs, since it
1236 * addds references from the new afs_icl_set. When the set is destroyed,
1237 * those references will be released.
1240 afs_icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
1241 struct afs_icl_log *fatalLogp, afs_uint32 flags,
1242 struct afs_icl_set **outSetpp)
1244 register struct afs_icl_set *setp;
1246 afs_int32 states = ICL_DEFAULT_SET_STATES;
1248 ObtainWriteLock(&afs_icl_lock, 197);
1249 if (!afs_icl_inited)
1252 for (setp = afs_icl_allSets; setp; setp = setp->nextp) {
1253 if (strcmp(setp->name, name) == 0) {
1256 if (flags & ICL_CRSET_FLAG_PERSISTENT) {
1257 ObtainWriteLock(&setp->lock, 198);
1258 setp->states |= ICL_SETF_PERSISTENT;
1259 ReleaseWriteLock(&setp->lock);
1261 ReleaseWriteLock(&afs_icl_lock);
1266 /* determine initial state */
1267 if (flags & ICL_CRSET_FLAG_DEFAULT_ON)
1268 states = ICL_SETF_ACTIVE;
1269 else if (flags & ICL_CRSET_FLAG_DEFAULT_OFF)
1270 states = ICL_SETF_FREED;
1271 if (flags & ICL_CRSET_FLAG_PERSISTENT)
1272 states |= ICL_SETF_PERSISTENT;
1274 setp = (struct afs_icl_set *)osi_AllocSmallSpace(sizeof(struct afs_icl_set));
1275 memset((caddr_t) setp, 0, sizeof(*setp));
1277 if (states & ICL_SETF_FREED)
1278 states &= ~ICL_SETF_ACTIVE; /* if freed, can't be active */
1279 setp->states = states;
1281 LOCK_INIT(&setp->lock, "setp lock");
1282 /* next lock is obtained in wrong order, hierarchy-wise, but
1283 * it doesn't matter, since no one can find this lock yet, since
1284 * the afs_icl_lock is still held, and thus the obtain can't block.
1286 ObtainWriteLock(&setp->lock, 199);
1287 setp->name = osi_AllocSmallSpace(strlen(name) + 1);
1288 strcpy(setp->name, name);
1289 setp->nevents = ICL_DEFAULTEVENTS;
1290 setp->eventFlags = afs_osi_Alloc(ICL_DEFAULTEVENTS);
1291 #ifdef KERNEL_HAVE_PIN
1292 pin((char *)setp->eventFlags, ICL_DEFAULTEVENTS);
1294 for (i = 0; i < ICL_DEFAULTEVENTS; i++)
1295 setp->eventFlags[i] = 0xff; /* default to enabled */
1297 /* update this global info under the afs_icl_lock */
1298 setp->nextp = afs_icl_allSets;
1299 afs_icl_allSets = setp;
1300 ReleaseWriteLock(&afs_icl_lock);
1302 /* set's basic lock is still held, so we can finish init */
1304 setp->logs[0] = baseLogp;
1305 afs_icl_LogHold(baseLogp);
1306 if (!(setp->states & ICL_SETF_FREED))
1307 afs_icl_LogUse(baseLogp); /* log is actually being used */
1310 setp->logs[1] = fatalLogp;
1311 afs_icl_LogHold(fatalLogp);
1312 if (!(setp->states & ICL_SETF_FREED))
1313 afs_icl_LogUse(fatalLogp); /* log is actually being used */
1315 ReleaseWriteLock(&setp->lock);
1321 /* function to change event enabling information for a particular set */
1323 afs_icl_SetEnable(struct afs_icl_set *setp, afs_int32 eventID, int setValue)
1327 ObtainWriteLock(&setp->lock, 200);
1328 if (!ICL_EVENTOK(setp, eventID)) {
1329 ReleaseWriteLock(&setp->lock);
1332 tp = &setp->eventFlags[ICL_EVENTBYTE(eventID)];
1334 *tp |= ICL_EVENTMASK(eventID);
1336 *tp &= ~(ICL_EVENTMASK(eventID));
1337 ReleaseWriteLock(&setp->lock);
1341 /* return indication of whether a particular event ID is enabled
1342 * for tracing. If *getValuep is set to 0, the event is disabled,
1343 * otherwise it is enabled. All events start out enabled by default.
1346 afs_icl_GetEnable(struct afs_icl_set *setp, afs_int32 eventID, int *getValuep)
1348 ObtainReadLock(&setp->lock);
1349 if (!ICL_EVENTOK(setp, eventID)) {
1350 ReleaseWriteLock(&setp->lock);
1353 if (setp->eventFlags[ICL_EVENTBYTE(eventID)] & ICL_EVENTMASK(eventID))
1357 ReleaseReadLock(&setp->lock);
1361 /* hold and release event sets */
1363 afs_icl_SetHold(register struct afs_icl_set *setp)
1365 ObtainWriteLock(&afs_icl_lock, 201);
1367 ReleaseWriteLock(&afs_icl_lock);
1371 /* free a set. Called with afs_icl_lock locked */
1373 afs_icl_ZapSet(register struct afs_icl_set *setp)
1375 register struct afs_icl_set **lpp, *tp;
1377 register struct afs_icl_log *tlp;
1379 for (lpp = &afs_icl_allSets, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1381 /* found the dude we want to remove */
1383 osi_FreeSmallSpace(setp->name);
1384 afs_osi_Free(setp->eventFlags, ICL_DEFAULTEVENTS);
1385 #ifdef KERNEL_HAVE_PIN
1386 unpin((char *)setp->eventFlags, ICL_DEFAULTEVENTS);
1388 for (i = 0; i < ICL_LOGSPERSET; i++) {
1389 if ((tlp = setp->logs[i]))
1390 afs_icl_LogReleNL(tlp);
1392 osi_FreeSmallSpace(setp);
1393 break; /* won't find it twice */
1399 /* do the release, watching for deleted entries */
1401 afs_icl_SetRele(register struct afs_icl_set *setp)
1403 ObtainWriteLock(&afs_icl_lock, 202);
1404 if (--setp->refCount == 0 && (setp->states & ICL_SETF_DELETED)) {
1405 afs_icl_ZapSet(setp); /* destroys setp's lock! */
1407 ReleaseWriteLock(&afs_icl_lock);
1411 /* free a set entry, dropping its reference count */
1413 afs_icl_SetFree(register struct afs_icl_set *setp)
1415 ObtainWriteLock(&setp->lock, 203);
1416 setp->states |= ICL_SETF_DELETED;
1417 ReleaseWriteLock(&setp->lock);
1418 afs_icl_SetRele(setp);
1422 /* find a set by name, returning it held */
1423 struct afs_icl_set *
1424 afs_icl_FindSet(char *name)
1426 register struct afs_icl_set *tp;
1427 ObtainWriteLock(&afs_icl_lock, 204);
1428 for (tp = afs_icl_allSets; tp; tp = tp->nextp) {
1429 if (strcmp(tp->name, name) == 0) {
1430 /* this is the dude we want */
1435 ReleaseWriteLock(&afs_icl_lock);
1439 /* zero out all the logs in the set */
1441 afs_icl_ZeroSet(struct afs_icl_set *setp)
1446 struct afs_icl_log *logp;
1448 ObtainReadLock(&setp->lock);
1449 for (i = 0; i < ICL_LOGSPERSET; i++) {
1450 logp = setp->logs[i];
1452 afs_icl_LogHold(logp);
1453 tcode = afs_icl_ZeroLog(logp);
1455 code = tcode; /* save the last bad one */
1456 afs_icl_LogRele(logp);
1459 ReleaseReadLock(&setp->lock);
1464 afs_icl_EnumerateSets(int (*aproc)
1465 (char *name, char *arock, struct afs_icl_log * tp),
1468 register struct afs_icl_set *tp, *np;
1469 register afs_int32 code;
1472 ObtainWriteLock(&afs_icl_lock, 205);
1473 for (tp = afs_icl_allSets; tp; tp = np) {
1474 tp->refCount++; /* hold this guy */
1475 ReleaseWriteLock(&afs_icl_lock);
1476 code = (*aproc) (tp->name, arock, (struct afs_icl_log *)tp);
1477 ObtainWriteLock(&afs_icl_lock, 206);
1478 np = tp->nextp; /* tp may disappear next, but not np */
1479 if (--tp->refCount == 0 && (tp->states & ICL_SETF_DELETED))
1484 ReleaseWriteLock(&afs_icl_lock);
1489 afs_icl_AddLogToSet(struct afs_icl_set *setp, struct afs_icl_log *newlogp)
1494 ObtainWriteLock(&setp->lock, 207);
1495 for (i = 0; i < ICL_LOGSPERSET; i++) {
1496 if (!setp->logs[i]) {
1497 setp->logs[i] = newlogp;
1499 afs_icl_LogHold(newlogp);
1500 if (!(setp->states & ICL_SETF_FREED)) {
1501 /* bump up the number of sets using the log */
1502 afs_icl_LogUse(newlogp);
1507 ReleaseWriteLock(&setp->lock);
1512 afs_icl_SetSetStat(struct afs_icl_set *setp, int op)
1516 struct afs_icl_log *logp;
1518 ObtainWriteLock(&setp->lock, 208);
1520 case ICL_OP_SS_ACTIVATE: /* activate a log */
1522 * If we are not already active, see if we have released
1523 * our demand that the log be allocated (FREED set). If
1524 * we have, reassert our desire.
1526 if (!(setp->states & ICL_SETF_ACTIVE)) {
1527 if (setp->states & ICL_SETF_FREED) {
1528 /* have to reassert desire for logs */
1529 for (i = 0; i < ICL_LOGSPERSET; i++) {
1530 logp = setp->logs[i];
1532 afs_icl_LogHold(logp);
1533 afs_icl_LogUse(logp);
1534 afs_icl_LogRele(logp);
1537 setp->states &= ~ICL_SETF_FREED;
1539 setp->states |= ICL_SETF_ACTIVE;
1544 case ICL_OP_SS_DEACTIVATE: /* deactivate a log */
1545 /* this doesn't require anything beyond clearing the ACTIVE flag */
1546 setp->states &= ~ICL_SETF_ACTIVE;
1550 case ICL_OP_SS_FREE: /* deassert design for log */
1552 * if we are already in this state, do nothing; otherwise
1553 * deassert desire for log
1555 if (setp->states & ICL_SETF_ACTIVE)
1558 if (!(setp->states & ICL_SETF_FREED)) {
1559 for (i = 0; i < ICL_LOGSPERSET; i++) {
1560 logp = setp->logs[i];
1562 afs_icl_LogHold(logp);
1563 afs_icl_LogFreeUse(logp);
1564 afs_icl_LogRele(logp);
1567 setp->states |= ICL_SETF_FREED;
1576 ReleaseWriteLock(&setp->lock);