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"
16 #include "afs/sysincludes.h" /* Standard vendor system headers */
17 #include "afsincludes.h" /* Afs-based standard headers */
18 #include "afs/afs_stats.h"
19 #include "rx/rx_globals.h"
20 #if !defined(UKERNEL) && !defined(AFS_LINUX20_ENV)
23 #include "h/hashing.h"
25 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN60_ENV)
26 #include "netinet/in_var.h"
28 #endif /* !defined(UKERNEL) */
29 #ifdef AFS_LINUX22_ENV
30 #include "h/smp_lock.h"
34 struct afs_icl_set *afs_iclSetp = (struct afs_icl_set *)0;
35 struct afs_icl_set *afs_iclLongTermSetp = (struct afs_icl_set *)0;
37 #if defined(AFS_OSF_ENV) || defined(AFS_SGI61_ENV)
38 /* For SGI 6.2, this can is changed to 1 if it's a 32 bit kernel. */
39 #if defined(AFS_SGI62_ENV) && defined(KERNEL) && !defined(_K64U64)
40 int afs_icl_sizeofLong = 1;
42 int afs_icl_sizeofLong = 2;
45 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
46 int afs_icl_sizeofLong = 2;
48 int afs_icl_sizeofLong = 1;
52 int afs_icl_inited = 0;
54 /* init function, called once, under afs_icl_lock */
63 afs_icl_InitLogs(void)
65 struct afs_icl_log *logp;
68 /* initialize the ICL system */
69 code = afs_icl_CreateLog("cmfx", 60 * 1024, &logp);
72 afs_icl_CreateSetWithFlags("cm", logp, NULL,
73 ICL_CRSET_FLAG_DEFAULT_OFF,
76 afs_icl_CreateSet("cmlongterm", logp, NULL,
77 &afs_iclLongTermSetp);
82 struct afs_icl_log *afs_icl_FindLog();
83 struct afs_icl_set *afs_icl_FindSet();
87 Afscall_icl(long opcode, long p1, long p2, long p3, long p4, long *retval)
89 afs_int32 *lp, elts, flags;
90 register afs_int32 code;
91 struct afs_icl_log *logp;
92 struct afs_icl_set *setp;
93 #if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
95 #else /* AFS_SGI61_ENV */
96 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
101 #endif /* AFS_SGI61_ENV */
103 afs_int32 startCookie;
105 struct afs_icl_log *tlp;
108 if (!afs_suser(CRED())) { /* only root can run this code */
112 if (!afs_suser(NULL)) { /* only root can run this code */
113 #if defined(KERNEL_HAVE_UERROR)
122 case ICL_OP_COPYOUTCLR: /* copy out data then clear */
123 case ICL_OP_COPYOUT: /* copy ouy data */
124 /* copyout: p1=logname, p2=&buffer, p3=size(words), p4=&cookie
125 * return flags<<24 + nwords.
126 * updates cookie to updated start (not end) if we had to
129 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
132 AFS_COPYIN((char *)p4, (char *)&startCookie, sizeof(afs_int32), code);
135 logp = afs_icl_FindLog(tname);
138 #define BUFFERSIZE AFS_LRALLOCSIZ
139 lp = (afs_int32 *) osi_AllocLargeSpace(AFS_LRALLOCSIZ);
140 elts = BUFFERSIZE / sizeof(afs_int32);
143 flags = (opcode == ICL_OP_COPYOUT) ? 0 : ICL_COPYOUTF_CLRAFTERREAD;
145 afs_icl_CopyOut(logp, lp, &elts, (afs_uint32 *) & startCookie,
148 osi_FreeLargeSpace((struct osi_buffer *)lp);
151 AFS_COPYOUT((char *)lp, (char *)p2, elts * sizeof(afs_int32), code);
154 AFS_COPYOUT((char *)&startCookie, (char *)p4, sizeof(afs_int32),
158 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
160 *retval = ((long)((flags << 24) | (elts & 0xffffff))) << 32;
163 *retval = (flags << 24) | (elts & 0xffffff);
165 afs_icl_LogRele(logp);
166 osi_FreeLargeSpace((struct osi_buffer *)lp);
169 case ICL_OP_ENUMLOGS: /* enumerate logs */
170 /* enumerate logs: p1=index, p2=&name, p3=sizeof(name), p4=&size.
171 * return 0 for success, otherwise error.
173 for (tlp = afs_icl_allLogs; tlp; tlp = tlp->nextp) {
178 return ENOENT; /* past the end of file */
179 temp = strlen(tlp->name) + 1;
182 AFS_COPYOUT(tlp->name, (char *)p2, temp, code);
183 if (!code) /* copy out size of log */
184 AFS_COPYOUT((char *)&tlp->logSize, (char *)p4, sizeof(afs_int32),
188 case ICL_OP_ENUMLOGSBYSET: /* enumerate logs by set name */
189 /* enumerate logs: p1=setname, p2=index, p3=&name, p4=sizeof(name).
190 * return 0 for success, otherwise error.
192 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
195 setp = afs_icl_FindSet(tname);
198 if (p2 > ICL_LOGSPERSET)
200 if (!(tlp = setp->logs[p2]))
202 temp = strlen(tlp->name) + 1;
205 AFS_COPYOUT(tlp->name, (char *)p3, temp, code);
208 case ICL_OP_CLRLOG: /* clear specified log */
209 /* zero out the specified log: p1=logname */
210 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
213 logp = afs_icl_FindLog(tname);
216 code = afs_icl_ZeroLog(logp);
217 afs_icl_LogRele(logp);
220 case ICL_OP_CLRSET: /* clear specified set */
221 /* zero out the specified set: p1=setname */
222 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
225 setp = afs_icl_FindSet(tname);
228 code = afs_icl_ZeroSet(setp);
229 afs_icl_SetRele(setp);
232 case ICL_OP_CLRALL: /* clear all logs */
233 /* zero out all logs -- no args */
235 ObtainWriteLock(&afs_icl_lock, 178);
236 for (tlp = afs_icl_allLogs; tlp; tlp = tlp->nextp) {
237 tlp->refCount++; /* hold this guy */
238 ReleaseWriteLock(&afs_icl_lock);
239 /* don't clear persistent logs */
240 if ((tlp->states & ICL_LOGF_PERSISTENT) == 0)
241 code = afs_icl_ZeroLog(tlp);
242 ObtainWriteLock(&afs_icl_lock, 179);
243 if (--tlp->refCount == 0)
248 ReleaseWriteLock(&afs_icl_lock);
251 case ICL_OP_ENUMSETS: /* enumerate all sets */
252 /* enumerate sets: p1=index, p2=&name, p3=sizeof(name), p4=&states.
253 * return 0 for success, otherwise error.
255 for (setp = afs_icl_allSets; setp; setp = setp->nextp) {
260 return ENOENT; /* past the end of file */
261 temp = strlen(setp->name) + 1;
264 AFS_COPYOUT(setp->name, (char *)p2, temp, code);
265 if (!code) /* copy out size of log */
266 AFS_COPYOUT((char *)&setp->states, (char *)p4, sizeof(afs_int32),
270 case ICL_OP_SETSTAT: /* set status on a set */
271 /* activate the specified set: p1=setname, p2=op */
272 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
275 setp = afs_icl_FindSet(tname);
278 code = afs_icl_SetSetStat(setp, p2);
279 afs_icl_SetRele(setp);
282 case ICL_OP_SETSTATALL: /* set status on all sets */
283 /* activate the specified set: p1=op */
285 ObtainWriteLock(&afs_icl_lock, 180);
286 for (setp = afs_icl_allSets; setp; setp = setp->nextp) {
287 setp->refCount++; /* hold this guy */
288 ReleaseWriteLock(&afs_icl_lock);
289 /* don't set states on persistent sets */
290 if ((setp->states & ICL_SETF_PERSISTENT) == 0)
291 code = afs_icl_SetSetStat(setp, p1);
292 ObtainWriteLock(&afs_icl_lock, 181);
293 if (--setp->refCount == 0)
294 afs_icl_ZapSet(setp);
298 ReleaseWriteLock(&afs_icl_lock);
301 case ICL_OP_SETLOGSIZE: /* set size of log */
302 /* set the size of the specified log: p1=logname, p2=size (in words) */
303 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
306 logp = afs_icl_FindLog(tname);
309 code = afs_icl_LogSetSize(logp, p2);
310 afs_icl_LogRele(logp);
313 case ICL_OP_GETLOGINFO: /* get size of log */
314 /* zero out the specified log: p1=logname, p2=&logSize, p3=&allocated */
315 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
318 logp = afs_icl_FindLog(tname);
321 allocated = !!logp->datap;
322 AFS_COPYOUT((char *)&logp->logSize, (char *)p2, sizeof(afs_int32),
325 AFS_COPYOUT((char *)&allocated, (char *)p3, sizeof(afs_int32),
327 afs_icl_LogRele(logp);
330 case ICL_OP_GETSETINFO: /* get state of set */
331 /* zero out the specified set: p1=setname, p2=&state */
332 AFS_COPYINSTR((char *)p1, tname, sizeof(tname), &temp, code);
335 setp = afs_icl_FindSet(tname);
338 AFS_COPYOUT((char *)&setp->states, (char *)p2, sizeof(afs_int32),
340 afs_icl_SetRele(setp);
351 afs_lock_t afs_icl_lock;
353 /* exported routine: a 4 parameter event */
355 afs_icl_Event4(register struct afs_icl_set *setp, afs_int32 eventID,
356 afs_int32 lAndT, long p1, long p2, long p3, long p4)
360 register afs_int32 tmask;
363 /* If things aren't init'ed yet (or the set is inactive), don't panic */
364 if (!ICL_SETACTIVE(setp))
368 mask = lAndT >> 24 & 0xff; /* mask of which logs to log to */
369 ix = ICL_EVENTBYTE(eventID);
370 ObtainReadLock(&setp->lock);
371 if (setp->eventFlags[ix] & ICL_EVENTMASK(eventID)) {
372 for (i = 0, tmask = 1; i < ICL_LOGSPERSET; i++, tmask <<= 1) {
374 afs_icl_AppendRecord(setp->logs[i], eventID, lAndT & 0xffffff,
379 break; /* break early */
382 ReleaseReadLock(&setp->lock);
386 /* Next 4 routines should be implemented via var-args or something.
387 * Whole purpose is to avoid compiler warnings about parameter # mismatches.
388 * Otherwise, could call afs_icl_Event4 directly.
391 afs_icl_Event3(register struct afs_icl_set *setp, afs_int32 eventID,
392 afs_int32 lAndT, long p1, long p2, long p3)
394 return afs_icl_Event4(setp, eventID, lAndT, p1, p2, p3, (long)0);
398 afs_icl_Event2(register struct afs_icl_set *setp, afs_int32 eventID,
399 afs_int32 lAndT, long p1, long p2)
401 return afs_icl_Event4(setp, eventID, lAndT, p1, p2, (long)0, (long)0);
405 afs_icl_Event1(register struct afs_icl_set *setp, afs_int32 eventID,
406 afs_int32 lAndT, long p1)
408 return afs_icl_Event4(setp, eventID, lAndT, p1, (long)0, (long)0,
413 afs_icl_Event0(register struct afs_icl_set *setp, afs_int32 eventID,
416 return afs_icl_Event4(setp, eventID, lAndT, (long)0, (long)0, (long)0,
420 struct afs_icl_log *afs_icl_allLogs = 0;
422 /* function to purge records from the start of the log, until there
423 * is at least minSpace long's worth of space available without
424 * making the head and the tail point to the same word.
426 * Log must be write-locked.
429 afs_icl_GetLogSpace(register struct afs_icl_log *logp, afs_int32 minSpace)
431 register unsigned int tsize;
433 while (logp->logSize - logp->logElements <= minSpace) {
435 tsize = ((logp->datap[logp->firstUsed]) >> 24) & 0xff;
436 logp->logElements -= tsize;
437 logp->firstUsed += tsize;
438 if (logp->firstUsed >= logp->logSize)
439 logp->firstUsed -= logp->logSize;
440 logp->baseCookie += tsize;
444 /* append string astr to buffer, including terminating null char.
446 * log must be write-locked.
448 #define ICL_CHARSPERLONG 4
450 afs_icl_AppendString(struct afs_icl_log *logp, char *astr)
452 char *op; /* ptr to char to write */
454 register int bib; /* bytes in buffer */
457 op = (char *)&(logp->datap[logp->firstFree]);
461 if (++bib >= ICL_CHARSPERLONG) {
464 if (++(logp->firstFree) >= logp->logSize) {
466 op = (char *)&(logp->datap[0]);
474 /* if we've used this word at all, allocate it */
475 if (++(logp->firstFree) >= logp->logSize) {
482 /* add a long to the log, ignoring overflow (checked already) */
483 #define ICL_APPENDINT32(lp, x) \
485 (lp)->datap[(lp)->firstFree] = (x); \
486 if (++((lp)->firstFree) >= (lp)->logSize) { \
487 (lp)->firstFree = 0; \
489 (lp)->logElements++; \
492 #if defined(AFS_OSF_ENV) || (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
493 #define ICL_APPENDLONG(lp, x) \
495 ICL_APPENDINT32((lp), ((x) >> 32) & 0xffffffffL); \
496 ICL_APPENDINT32((lp), (x) & 0xffffffffL); \
499 #else /* AFS_OSF_ENV */
500 #define ICL_APPENDLONG(lp, x) ICL_APPENDINT32((lp), (x))
501 #endif /* AFS_OSF_ENV */
503 /* routine to tell whether we're dealing with the address or the
507 afs_icl_UseAddr(int type)
509 if (type == ICL_TYPE_HYPER || type == ICL_TYPE_STRING
510 || type == ICL_TYPE_FID || type == ICL_TYPE_INT64)
516 /* Function to append a record to the log. Written for speed
517 * since we know that we're going to have to make this work fast
518 * pretty soon, anyway. The log must be unlocked.
522 afs_icl_AppendRecord(register struct afs_icl_log *logp, afs_int32 op,
523 afs_int32 types, long p1, long p2, long p3, long p4)
525 int rsize; /* record size in longs */
526 register int tsize; /* temp size */
530 t4 = types & 0x3f; /* decode types */
538 osi_GetTime(&tv); /* It panics for solaris if inside */
539 ObtainWriteLock(&logp->lock, 182);
541 ReleaseWriteLock(&logp->lock);
545 /* get timestamp as # of microseconds since some time that doesn't
546 * change that often. This algorithm ticks over every 20 minutes
547 * or so (1000 seconds). Write a timestamp record if it has.
549 if (tv.tv_sec - logp->lastTS > 1024) {
550 /* the timer has wrapped -- write a timestamp record */
551 if (logp->logSize - logp->logElements <= 5)
552 afs_icl_GetLogSpace(logp, 5);
554 ICL_APPENDINT32(logp,
555 (afs_int32) (5 << 24) + (ICL_TYPE_UNIXDATE << 18));
556 ICL_APPENDINT32(logp, (afs_int32) ICL_INFO_TIMESTAMP);
557 ICL_APPENDINT32(logp, (afs_int32) 0); /* use thread ID zero for clocks */
558 ICL_APPENDINT32(logp,
559 (afs_int32) (tv.tv_sec & 0x3ff) * 1000000 +
561 ICL_APPENDINT32(logp, (afs_int32) tv.tv_sec);
563 logp->lastTS = tv.tv_sec;
566 rsize = 4; /* base case */
568 /* compute size of parameter p1. Only tricky case is string.
569 * In that case, we have to call strlen to get the string length.
571 ICL_SIZEHACK(t1, p1);
574 /* compute size of parameter p2. Only tricky case is string.
575 * In that case, we have to call strlen to get the string length.
577 ICL_SIZEHACK(t2, p2);
580 /* compute size of parameter p3. Only tricky case is string.
581 * In that case, we have to call strlen to get the string length.
583 ICL_SIZEHACK(t3, p3);
586 /* compute size of parameter p4. Only tricky case is string.
587 * In that case, we have to call strlen to get the string length.
589 ICL_SIZEHACK(t4, p4);
592 /* At this point, we've computed all of the parameter sizes, and
593 * have in rsize the size of the entire record we want to append.
594 * Next, we check that we actually have room in the log to do this
595 * work, and then we do the append.
598 ReleaseWriteLock(&logp->lock);
599 return; /* log record too big to express */
602 if (logp->logSize - logp->logElements <= rsize)
603 afs_icl_GetLogSpace(logp, rsize);
605 ICL_APPENDINT32(logp,
606 (afs_int32) (rsize << 24) + (t1 << 18) + (t2 << 12) +
608 ICL_APPENDINT32(logp, (afs_int32) op);
609 ICL_APPENDINT32(logp, (afs_int32) osi_ThreadUnique());
610 ICL_APPENDINT32(logp,
611 (afs_int32) (tv.tv_sec & 0x3ff) * 1000000 + tv.tv_usec);
614 /* marshall parameter 1 now */
615 if (t1 == ICL_TYPE_STRING) {
616 afs_icl_AppendString(logp, (char *)p1);
617 } else if (t1 == ICL_TYPE_HYPER) {
618 ICL_APPENDINT32(logp,
619 (afs_int32) ((struct afs_hyper_t *)p1)->high);
620 ICL_APPENDINT32(logp,
621 (afs_int32) ((struct afs_hyper_t *)p1)->low);
622 } else if (t1 == ICL_TYPE_INT64) {
623 #ifndef WORDS_BIGENDIAN
624 #ifdef AFS_64BIT_CLIENT
625 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[1]);
626 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[0]);
627 #else /* AFS_64BIT_CLIENT */
628 ICL_APPENDINT32(logp, (afs_int32) p1);
629 ICL_APPENDINT32(logp, (afs_int32) 0);
630 #endif /* AFS_64BIT_CLIENT */
631 #else /* AFSLITTLE_ENDIAN */
632 #ifdef AFS_64BIT_CLIENT
633 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[0]);
634 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[1]);
635 #else /* AFS_64BIT_CLIENT */
636 ICL_APPENDINT32(logp, (afs_int32) 0);
637 ICL_APPENDINT32(logp, (afs_int32) p1);
638 #endif /* AFS_64BIT_CLIENT */
639 #endif /* AFSLITTLE_ENDIAN */
640 } else if (t1 == ICL_TYPE_FID) {
641 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[0]);
642 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[1]);
643 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[2]);
644 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p1)[3]);
646 #if defined(AFS_OSF_ENV) || (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
647 else if (t1 == ICL_TYPE_INT32)
648 ICL_APPENDINT32(logp, (afs_int32) p1);
649 #endif /* AFS_OSF_ENV */
651 ICL_APPENDLONG(logp, p1);
654 /* marshall parameter 2 now */
655 if (t2 == ICL_TYPE_STRING)
656 afs_icl_AppendString(logp, (char *)p2);
657 else if (t2 == ICL_TYPE_HYPER) {
658 ICL_APPENDINT32(logp,
659 (afs_int32) ((struct afs_hyper_t *)p2)->high);
660 ICL_APPENDINT32(logp,
661 (afs_int32) ((struct afs_hyper_t *)p2)->low);
662 } else if (t2 == ICL_TYPE_INT64) {
663 #ifndef WORDS_BIGENDIAN
664 #ifdef AFS_64BIT_CLIENT
665 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[1]);
666 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[0]);
667 #else /* AFS_64BIT_CLIENT */
668 ICL_APPENDINT32(logp, (afs_int32) p2);
669 ICL_APPENDINT32(logp, (afs_int32) 0);
670 #endif /* AFS_64BIT_CLIENT */
671 #else /* AFSLITTLE_ENDIAN */
672 #ifdef AFS_64BIT_CLIENT
673 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[0]);
674 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[1]);
675 #else /* AFS_64BIT_CLIENT */
676 ICL_APPENDINT32(logp, (afs_int32) 0);
677 ICL_APPENDINT32(logp, (afs_int32) p2);
678 #endif /* AFS_64BIT_CLIENT */
679 #endif /* AFSLITTLE_ENDIAN */
680 } else if (t2 == ICL_TYPE_FID) {
681 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[0]);
682 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[1]);
683 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[2]);
684 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p2)[3]);
686 #if defined(AFS_OSF_ENV) || (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
687 else if (t2 == ICL_TYPE_INT32)
688 ICL_APPENDINT32(logp, (afs_int32) p2);
689 #endif /* AFS_OSF_ENV */
691 ICL_APPENDLONG(logp, p2);
694 /* marshall parameter 3 now */
695 if (t3 == ICL_TYPE_STRING)
696 afs_icl_AppendString(logp, (char *)p3);
697 else if (t3 == ICL_TYPE_HYPER) {
698 ICL_APPENDINT32(logp,
699 (afs_int32) ((struct afs_hyper_t *)p3)->high);
700 ICL_APPENDINT32(logp,
701 (afs_int32) ((struct afs_hyper_t *)p3)->low);
702 } else if (t3 == ICL_TYPE_INT64) {
703 #ifndef WORDS_BIGENDIAN
704 #ifdef AFS_64BIT_CLIENT
705 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[1]);
706 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[0]);
707 #else /* AFS_64BIT_CLIENT */
708 ICL_APPENDINT32(logp, (afs_int32) p3);
709 ICL_APPENDINT32(logp, (afs_int32) 0);
710 #endif /* AFS_64BIT_CLIENT */
711 #else /* AFSLITTLE_ENDIAN */
712 #ifdef AFS_64BIT_CLIENT
713 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[0]);
714 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[1]);
715 #else /* AFS_64BIT_CLIENT */
716 ICL_APPENDINT32(logp, (afs_int32) 0);
717 ICL_APPENDINT32(logp, (afs_int32) p3);
718 #endif /* AFS_64BIT_CLIENT */
719 #endif /* AFSLITTLE_ENDIAN */
720 } else if (t3 == ICL_TYPE_FID) {
721 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[0]);
722 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[1]);
723 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[2]);
724 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p3)[3]);
726 #if defined(AFS_OSF_ENV) || (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
727 else if (t3 == ICL_TYPE_INT32)
728 ICL_APPENDINT32(logp, (afs_int32) p3);
729 #endif /* AFS_OSF_ENV */
731 ICL_APPENDLONG(logp, p3);
734 /* marshall parameter 4 now */
735 if (t4 == ICL_TYPE_STRING)
736 afs_icl_AppendString(logp, (char *)p4);
737 else if (t4 == ICL_TYPE_HYPER) {
738 ICL_APPENDINT32(logp,
739 (afs_int32) ((struct afs_hyper_t *)p4)->high);
740 ICL_APPENDINT32(logp,
741 (afs_int32) ((struct afs_hyper_t *)p4)->low);
742 } else if (t4 == ICL_TYPE_INT64) {
743 #ifndef WORDS_BIGENDIAN
744 #ifdef AFS_64BIT_CLIENT
745 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[1]);
746 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[0]);
747 #else /* AFS_64BIT_CLIENT */
748 ICL_APPENDINT32(logp, (afs_int32) p4);
749 ICL_APPENDINT32(logp, (afs_int32) 0);
750 #endif /* AFS_64BIT_CLIENT */
751 #else /* AFSLITTLE_ENDIAN */
752 #ifdef AFS_64BIT_CLIENT
753 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[0]);
754 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[1]);
755 #else /* AFS_64BIT_CLIENT */
756 ICL_APPENDINT32(logp, (afs_int32) 0);
757 ICL_APPENDINT32(logp, (afs_int32) p4);
758 #endif /* AFS_64BIT_CLIENT */
759 #endif /* AFSLITTLE_ENDIAN */
760 } else if (t4 == ICL_TYPE_FID) {
761 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[0]);
762 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[1]);
763 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[2]);
764 ICL_APPENDINT32(logp, (afs_int32) ((afs_int32 *) p4)[3]);
766 #if defined(AFS_OSF_ENV) || (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG==64)) || (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL))
767 else if (t4 == ICL_TYPE_INT32)
768 ICL_APPENDINT32(logp, (afs_int32) p4);
769 #endif /* AFS_OSF_ENV */
771 ICL_APPENDLONG(logp, p4);
773 ReleaseWriteLock(&logp->lock);
776 /* create a log with size logSize; return it in *outLogpp and tag
777 * it with name "name."
780 afs_icl_CreateLog(char *name, afs_int32 logSize,
781 struct afs_icl_log **outLogpp)
783 return afs_icl_CreateLogWithFlags(name, logSize, /*flags */ 0, outLogpp);
786 /* create a log with size logSize; return it in *outLogpp and tag
787 * it with name "name." 'flags' can be set to make the log unclearable.
790 afs_icl_CreateLogWithFlags(char *name, afs_int32 logSize, afs_uint32 flags,
791 struct afs_icl_log **outLogpp)
793 register struct afs_icl_log *logp;
795 /* add into global list under lock */
796 ObtainWriteLock(&afs_icl_lock, 183);
800 for (logp = afs_icl_allLogs; logp; logp = logp->nextp) {
801 if (strcmp(logp->name, name) == 0) {
802 /* found it already created, just return it */
805 if (flags & ICL_CRLOG_FLAG_PERSISTENT) {
806 ObtainWriteLock(&logp->lock, 184);
807 logp->states |= ICL_LOGF_PERSISTENT;
808 ReleaseWriteLock(&logp->lock);
810 ReleaseWriteLock(&afs_icl_lock);
815 logp = (struct afs_icl_log *)
816 osi_AllocSmallSpace(sizeof(struct afs_icl_log));
817 memset((caddr_t) logp, 0, sizeof(*logp));
820 logp->name = osi_AllocSmallSpace(strlen(name) + 1);
821 strcpy(logp->name, name);
822 LOCK_INIT(&logp->lock, "logp lock");
823 logp->logSize = logSize;
824 logp->datap = NULL; /* don't allocate it until we need it */
826 if (flags & ICL_CRLOG_FLAG_PERSISTENT)
827 logp->states |= ICL_LOGF_PERSISTENT;
829 logp->nextp = afs_icl_allLogs;
830 afs_icl_allLogs = logp;
831 ReleaseWriteLock(&afs_icl_lock);
837 /* called with a log, a pointer to a buffer, the size of the buffer
838 * (in *bufSizep), the starting cookie (in *cookiep, use 0 at the start)
839 * and returns data in the provided buffer, and returns output flags
840 * in *flagsp. The flag ICL_COPYOUTF_MISSEDSOME is set if we can't
841 * find the record with cookie value cookie.
844 afs_icl_CopyOut(register struct afs_icl_log *logp, afs_int32 * bufferp,
845 afs_int32 * bufSizep, afs_uint32 * cookiep,
848 afs_int32 nwords; /* number of words to copy out */
849 afs_uint32 startCookie; /* first cookie to use */
850 afs_int32 outWords; /* words we've copied out */
851 afs_int32 inWords; /* max words to copy out */
852 afs_int32 code; /* return code */
853 afs_int32 ix; /* index we're copying from */
854 afs_int32 outFlags; /* return flags */
855 afs_int32 inFlags; /* flags passed in */
858 inWords = *bufSizep; /* max to copy out */
859 outWords = 0; /* amount copied out */
860 startCookie = *cookiep;
865 ObtainWriteLock(&logp->lock, 185);
867 ReleaseWriteLock(&logp->lock);
871 /* first, compute the index of the start cookie we've been passed */
873 /* (re-)compute where we should start */
874 if (startCookie < logp->baseCookie) {
875 if (startCookie) /* missed some output */
876 outFlags |= ICL_COPYOUTF_MISSEDSOME;
877 /* skip to the first available record */
878 startCookie = logp->baseCookie;
879 *cookiep = startCookie;
882 /* compute where we find the first element to copy out */
883 ix = logp->firstUsed + startCookie - logp->baseCookie;
884 if (ix >= logp->logSize)
887 /* if have some data now, break out and process it */
888 if (startCookie - logp->baseCookie < logp->logElements)
891 /* At end of log, so clear it if we need to */
892 if (inFlags & ICL_COPYOUTF_CLRAFTERREAD) {
893 logp->firstUsed = logp->firstFree = 0;
894 logp->logElements = 0;
896 /* otherwise, either wait for the data to arrive, or return */
897 if (!(inFlags & ICL_COPYOUTF_WAITIO)) {
898 ReleaseWriteLock(&logp->lock);
902 logp->states |= ICL_LOGF_WAITING;
903 ReleaseWriteLock(&logp->lock);
904 afs_osi_Sleep(&logp->lock);
905 ObtainWriteLock(&logp->lock, 186);
907 /* copy out data from ix to logSize or firstFree, depending
908 * upon whether firstUsed <= firstFree (no wrap) or otherwise.
909 * be careful not to copy out more than nwords.
911 if (ix >= logp->firstUsed) {
912 if (logp->firstUsed <= logp->firstFree)
914 end = logp->firstFree; /* first element not to copy */
917 nwords = inWords; /* don't copy more than this */
918 if (end - ix < nwords)
921 memcpy((char *)bufferp, (char *)&logp->datap[ix],
922 sizeof(afs_int32) * nwords);
927 /* if we're going to copy more out below, we'll start here */
930 /* now, if active part of the log has wrapped, there's more stuff
931 * starting at the head of the log. Copy out more from there.
933 if (logp->firstUsed > logp->firstFree && ix < logp->firstFree
935 /* (more to) copy out from the wrapped section at the
936 * start of the log. May get here even if didn't copy any
937 * above, if the cookie points directly into the wrapped section.
940 if (logp->firstFree - ix < nwords)
941 nwords = logp->firstFree - ix;
942 memcpy((char *)bufferp, (char *)&logp->datap[ix],
943 sizeof(afs_int32) * nwords);
949 ReleaseWriteLock(&logp->lock);
953 *bufSizep = outWords;
959 /* return basic parameter information about a log */
961 afs_icl_GetLogParms(struct afs_icl_log *logp, afs_int32 * maxSizep,
962 afs_int32 * curSizep)
964 ObtainReadLock(&logp->lock);
965 *maxSizep = logp->logSize;
966 *curSizep = logp->logElements;
967 ReleaseReadLock(&logp->lock);
972 /* hold and release logs */
974 afs_icl_LogHold(register struct afs_icl_log *logp)
976 ObtainWriteLock(&afs_icl_lock, 187);
978 ReleaseWriteLock(&afs_icl_lock);
982 /* hold and release logs, called with lock already held */
984 afs_icl_LogHoldNL(register struct afs_icl_log *logp)
990 /* keep track of how many sets believe the log itself is allocated */
992 afs_icl_LogUse(register struct afs_icl_log *logp)
994 ObtainWriteLock(&logp->lock, 188);
995 if (logp->setCount == 0) {
996 /* this is the first set actually using the log -- allocate it */
997 if (logp->logSize == 0) {
998 /* we weren't passed in a hint and it wasn't set */
999 logp->logSize = ICL_DEFAULT_LOGSIZE;
1002 (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * logp->logSize);
1003 #ifdef KERNEL_HAVE_PIN
1004 pin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1008 ReleaseWriteLock(&logp->lock);
1012 /* decrement the number of real users of the log, free if possible */
1014 afs_icl_LogFreeUse(register struct afs_icl_log *logp)
1016 ObtainWriteLock(&logp->lock, 189);
1017 if (--logp->setCount == 0) {
1018 /* no more users -- free it (but keep log structure around) */
1019 afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1020 #ifdef KERNEL_HAVE_PIN
1021 unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1023 logp->firstUsed = logp->firstFree = 0;
1024 logp->logElements = 0;
1027 ReleaseWriteLock(&logp->lock);
1031 /* set the size of the log to 'logSize' */
1033 afs_icl_LogSetSize(register struct afs_icl_log *logp, afs_int32 logSize)
1035 ObtainWriteLock(&logp->lock, 190);
1037 /* nothing to worry about since it's not allocated */
1038 logp->logSize = logSize;
1041 logp->firstUsed = logp->firstFree = 0;
1042 logp->logElements = 0;
1044 /* free and allocate a new one */
1045 afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1046 #ifdef KERNEL_HAVE_PIN
1047 unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1050 (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * logSize);
1051 #ifdef KERNEL_HAVE_PIN
1052 pin((char *)logp->datap, sizeof(afs_int32) * logSize);
1054 logp->logSize = logSize;
1056 ReleaseWriteLock(&logp->lock);
1061 /* free a log. Called with afs_icl_lock locked. */
1063 afs_icl_ZapLog(register struct afs_icl_log *logp)
1065 register struct afs_icl_log **lpp, *tp;
1067 for (lpp = &afs_icl_allLogs, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1069 /* found the dude we want to remove */
1071 osi_FreeSmallSpace(logp->name);
1072 afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
1073 #ifdef KERNEL_HAVE_PIN
1074 unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
1076 osi_FreeSmallSpace(logp);
1077 break; /* won't find it twice */
1083 /* do the release, watching for deleted entries */
1085 afs_icl_LogRele(register struct afs_icl_log *logp)
1087 ObtainWriteLock(&afs_icl_lock, 191);
1088 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1089 afs_icl_ZapLog(logp); /* destroys logp's lock! */
1091 ReleaseWriteLock(&afs_icl_lock);
1095 /* do the release, watching for deleted entries, log already held */
1097 afs_icl_LogReleNL(register struct afs_icl_log *logp)
1099 if (--logp->refCount == 0 && (logp->states & ICL_LOGF_DELETED)) {
1100 afs_icl_ZapLog(logp); /* destroys logp's lock! */
1105 /* zero out the log */
1107 afs_icl_ZeroLog(register struct afs_icl_log *logp)
1109 ObtainWriteLock(&logp->lock, 192);
1110 logp->firstUsed = logp->firstFree = 0;
1111 logp->logElements = 0;
1112 logp->baseCookie = 0;
1113 ReleaseWriteLock(&logp->lock);
1117 /* free a log entry, and drop its reference count */
1119 afs_icl_LogFree(register struct afs_icl_log *logp)
1121 ObtainWriteLock(&logp->lock, 193);
1122 logp->states |= ICL_LOGF_DELETED;
1123 ReleaseWriteLock(&logp->lock);
1124 afs_icl_LogRele(logp);
1128 /* find a log by name, returning it held */
1129 struct afs_icl_log *
1130 afs_icl_FindLog(char *name)
1132 register struct afs_icl_log *tp;
1133 ObtainWriteLock(&afs_icl_lock, 194);
1134 for (tp = afs_icl_allLogs; tp; tp = tp->nextp) {
1135 if (strcmp(tp->name, name) == 0) {
1136 /* this is the dude we want */
1141 ReleaseWriteLock(&afs_icl_lock);
1146 afs_icl_EnumerateLogs(int (*aproc)
1147 (char *name, char *arock, struct afs_icl_log * tp),
1150 register struct afs_icl_log *tp;
1151 register afs_int32 code;
1154 ObtainWriteLock(&afs_icl_lock, 195);
1155 for (tp = afs_icl_allLogs; tp; tp = tp->nextp) {
1156 tp->refCount++; /* hold this guy */
1157 ReleaseWriteLock(&afs_icl_lock);
1158 ObtainReadLock(&tp->lock);
1159 code = (*aproc) (tp->name, arock, tp);
1160 ReleaseReadLock(&tp->lock);
1161 ObtainWriteLock(&afs_icl_lock, 196);
1162 if (--tp->refCount == 0)
1167 ReleaseWriteLock(&afs_icl_lock);
1171 struct afs_icl_set *afs_icl_allSets = 0;
1174 afs_icl_CreateSet(char *name, struct afs_icl_log *baseLogp,
1175 struct afs_icl_log *fatalLogp,
1176 struct afs_icl_set **outSetpp)
1178 return afs_icl_CreateSetWithFlags(name, baseLogp, fatalLogp,
1179 /*flags */ 0, outSetpp);
1182 /* create a set, given pointers to base and fatal logs, if any.
1183 * Logs are unlocked, but referenced, and *outSetpp is returned
1184 * referenced. Function bumps reference count on logs, since it
1185 * addds references from the new afs_icl_set. When the set is destroyed,
1186 * those references will be released.
1189 afs_icl_CreateSetWithFlags(char *name, struct afs_icl_log *baseLogp,
1190 struct afs_icl_log *fatalLogp, afs_uint32 flags,
1191 struct afs_icl_set **outSetpp)
1193 register struct afs_icl_set *setp;
1195 afs_int32 states = ICL_DEFAULT_SET_STATES;
1197 ObtainWriteLock(&afs_icl_lock, 197);
1198 if (!afs_icl_inited)
1201 for (setp = afs_icl_allSets; setp; setp = setp->nextp) {
1202 if (strcmp(setp->name, name) == 0) {
1205 if (flags & ICL_CRSET_FLAG_PERSISTENT) {
1206 ObtainWriteLock(&setp->lock, 198);
1207 setp->states |= ICL_SETF_PERSISTENT;
1208 ReleaseWriteLock(&setp->lock);
1210 ReleaseWriteLock(&afs_icl_lock);
1215 /* determine initial state */
1216 if (flags & ICL_CRSET_FLAG_DEFAULT_ON)
1217 states = ICL_SETF_ACTIVE;
1218 else if (flags & ICL_CRSET_FLAG_DEFAULT_OFF)
1219 states = ICL_SETF_FREED;
1220 if (flags & ICL_CRSET_FLAG_PERSISTENT)
1221 states |= ICL_SETF_PERSISTENT;
1223 setp = (struct afs_icl_set *)afs_osi_Alloc(sizeof(struct afs_icl_set));
1224 memset((caddr_t) setp, 0, sizeof(*setp));
1226 if (states & ICL_SETF_FREED)
1227 states &= ~ICL_SETF_ACTIVE; /* if freed, can't be active */
1228 setp->states = states;
1230 LOCK_INIT(&setp->lock, "setp lock");
1231 /* next lock is obtained in wrong order, hierarchy-wise, but
1232 * it doesn't matter, since no one can find this lock yet, since
1233 * the afs_icl_lock is still held, and thus the obtain can't block.
1235 ObtainWriteLock(&setp->lock, 199);
1236 setp->name = osi_AllocSmallSpace(strlen(name) + 1);
1237 strcpy(setp->name, name);
1238 setp->nevents = ICL_DEFAULTEVENTS;
1239 setp->eventFlags = afs_osi_Alloc(ICL_DEFAULTEVENTS);
1240 #ifdef KERNEL_HAVE_PIN
1241 pin((char *)setp->eventFlags, ICL_DEFAULTEVENTS);
1243 for (i = 0; i < ICL_DEFAULTEVENTS; i++)
1244 setp->eventFlags[i] = 0xff; /* default to enabled */
1246 /* update this global info under the afs_icl_lock */
1247 setp->nextp = afs_icl_allSets;
1248 afs_icl_allSets = setp;
1249 ReleaseWriteLock(&afs_icl_lock);
1251 /* set's basic lock is still held, so we can finish init */
1253 setp->logs[0] = baseLogp;
1254 afs_icl_LogHold(baseLogp);
1255 if (!(setp->states & ICL_SETF_FREED))
1256 afs_icl_LogUse(baseLogp); /* log is actually being used */
1259 setp->logs[1] = fatalLogp;
1260 afs_icl_LogHold(fatalLogp);
1261 if (!(setp->states & ICL_SETF_FREED))
1262 afs_icl_LogUse(fatalLogp); /* log is actually being used */
1264 ReleaseWriteLock(&setp->lock);
1270 /* function to change event enabling information for a particular set */
1272 afs_icl_SetEnable(struct afs_icl_set *setp, afs_int32 eventID, int setValue)
1276 ObtainWriteLock(&setp->lock, 200);
1277 if (!ICL_EVENTOK(setp, eventID)) {
1278 ReleaseWriteLock(&setp->lock);
1281 tp = &setp->eventFlags[ICL_EVENTBYTE(eventID)];
1283 *tp |= ICL_EVENTMASK(eventID);
1285 *tp &= ~(ICL_EVENTMASK(eventID));
1286 ReleaseWriteLock(&setp->lock);
1290 /* return indication of whether a particular event ID is enabled
1291 * for tracing. If *getValuep is set to 0, the event is disabled,
1292 * otherwise it is enabled. All events start out enabled by default.
1295 afs_icl_GetEnable(struct afs_icl_set *setp, afs_int32 eventID, int *getValuep)
1297 ObtainReadLock(&setp->lock);
1298 if (!ICL_EVENTOK(setp, eventID)) {
1299 ReleaseWriteLock(&setp->lock);
1302 if (setp->eventFlags[ICL_EVENTBYTE(eventID)] & ICL_EVENTMASK(eventID))
1306 ReleaseReadLock(&setp->lock);
1310 /* hold and release event sets */
1312 afs_icl_SetHold(register struct afs_icl_set *setp)
1314 ObtainWriteLock(&afs_icl_lock, 201);
1316 ReleaseWriteLock(&afs_icl_lock);
1320 /* free a set. Called with afs_icl_lock locked */
1322 afs_icl_ZapSet(register struct afs_icl_set *setp)
1324 register struct afs_icl_set **lpp, *tp;
1326 register struct afs_icl_log *tlp;
1328 for (lpp = &afs_icl_allSets, tp = *lpp; tp; lpp = &tp->nextp, tp = *lpp) {
1330 /* found the dude we want to remove */
1332 osi_FreeSmallSpace(setp->name);
1333 afs_osi_Free(setp->eventFlags, ICL_DEFAULTEVENTS);
1334 #ifdef KERNEL_HAVE_PIN
1335 unpin((char *)setp->eventFlags, ICL_DEFAULTEVENTS);
1337 for (i = 0; i < ICL_LOGSPERSET; i++) {
1338 if ((tlp = setp->logs[i]))
1339 afs_icl_LogReleNL(tlp);
1341 osi_FreeSmallSpace(setp);
1342 break; /* won't find it twice */
1348 /* do the release, watching for deleted entries */
1350 afs_icl_SetRele(register struct afs_icl_set *setp)
1352 ObtainWriteLock(&afs_icl_lock, 202);
1353 if (--setp->refCount == 0 && (setp->states & ICL_SETF_DELETED)) {
1354 afs_icl_ZapSet(setp); /* destroys setp's lock! */
1356 ReleaseWriteLock(&afs_icl_lock);
1360 /* free a set entry, dropping its reference count */
1362 afs_icl_SetFree(register struct afs_icl_set *setp)
1364 ObtainWriteLock(&setp->lock, 203);
1365 setp->states |= ICL_SETF_DELETED;
1366 ReleaseWriteLock(&setp->lock);
1367 afs_icl_SetRele(setp);
1371 /* find a set by name, returning it held */
1372 struct afs_icl_set *
1373 afs_icl_FindSet(char *name)
1375 register struct afs_icl_set *tp;
1376 ObtainWriteLock(&afs_icl_lock, 204);
1377 for (tp = afs_icl_allSets; tp; tp = tp->nextp) {
1378 if (strcmp(tp->name, name) == 0) {
1379 /* this is the dude we want */
1384 ReleaseWriteLock(&afs_icl_lock);
1388 /* zero out all the logs in the set */
1390 afs_icl_ZeroSet(struct afs_icl_set *setp)
1395 struct afs_icl_log *logp;
1397 ObtainReadLock(&setp->lock);
1398 for (i = 0; i < ICL_LOGSPERSET; i++) {
1399 logp = setp->logs[i];
1401 afs_icl_LogHold(logp);
1402 tcode = afs_icl_ZeroLog(logp);
1404 code = tcode; /* save the last bad one */
1405 afs_icl_LogRele(logp);
1408 ReleaseReadLock(&setp->lock);
1413 afs_icl_EnumerateSets(int (*aproc)
1414 (char *name, char *arock, struct afs_icl_log * tp),
1417 register struct afs_icl_set *tp, *np;
1418 register afs_int32 code;
1421 ObtainWriteLock(&afs_icl_lock, 205);
1422 for (tp = afs_icl_allSets; tp; tp = np) {
1423 tp->refCount++; /* hold this guy */
1424 ReleaseWriteLock(&afs_icl_lock);
1425 code = (*aproc) (tp->name, arock, (struct afs_icl_log *)tp);
1426 ObtainWriteLock(&afs_icl_lock, 206);
1427 np = tp->nextp; /* tp may disappear next, but not np */
1428 if (--tp->refCount == 0 && (tp->states & ICL_SETF_DELETED))
1433 ReleaseWriteLock(&afs_icl_lock);
1438 afs_icl_AddLogToSet(struct afs_icl_set *setp, struct afs_icl_log *newlogp)
1443 ObtainWriteLock(&setp->lock, 207);
1444 for (i = 0; i < ICL_LOGSPERSET; i++) {
1445 if (!setp->logs[i]) {
1446 setp->logs[i] = newlogp;
1448 afs_icl_LogHold(newlogp);
1449 if (!(setp->states & ICL_SETF_FREED)) {
1450 /* bump up the number of sets using the log */
1451 afs_icl_LogUse(newlogp);
1456 ReleaseWriteLock(&setp->lock);
1461 afs_icl_SetSetStat(struct afs_icl_set *setp, int op)
1465 struct afs_icl_log *logp;
1467 ObtainWriteLock(&setp->lock, 208);
1469 case ICL_OP_SS_ACTIVATE: /* activate a log */
1471 * If we are not already active, see if we have released
1472 * our demand that the log be allocated (FREED set). If
1473 * we have, reassert our desire.
1475 if (!(setp->states & ICL_SETF_ACTIVE)) {
1476 if (setp->states & ICL_SETF_FREED) {
1477 /* have to reassert desire for logs */
1478 for (i = 0; i < ICL_LOGSPERSET; i++) {
1479 logp = setp->logs[i];
1481 afs_icl_LogHold(logp);
1482 afs_icl_LogUse(logp);
1483 afs_icl_LogRele(logp);
1486 setp->states &= ~ICL_SETF_FREED;
1488 setp->states |= ICL_SETF_ACTIVE;
1493 case ICL_OP_SS_DEACTIVATE: /* deactivate a log */
1494 /* this doesn't require anything beyond clearing the ACTIVE flag */
1495 setp->states &= ~ICL_SETF_ACTIVE;
1499 case ICL_OP_SS_FREE: /* deassert design for log */
1501 * if we are already in this state, do nothing; otherwise
1502 * deassert desire for log
1504 if (setp->states & ICL_SETF_ACTIVE)
1507 if (!(setp->states & ICL_SETF_FREED)) {
1508 for (i = 0; i < ICL_LOGSPERSET; i++) {
1509 logp = setp->logs[i];
1511 afs_icl_LogHold(logp);
1512 afs_icl_LogFreeUse(logp);
1513 afs_icl_LogRele(logp);
1516 setp->states |= ICL_SETF_FREED;
1525 ReleaseWriteLock(&setp->lock);