2 * (C) COPYRIGHT IBM CORPORATION 1988
3 * LICENSED MATERIALS - PROPERTY OF IBM
8 * Instituition: ITC, CMU
12 #include <afs/param.h>
14 #include <afs/afsutil.h>
21 static struct volser_trans *allTrans=0;
22 static afs_int32 transCounter = 1;
24 /* create a new transaction, returning ptr to same with high ref count */
25 struct volser_trans *NewTrans(avol, apart)
28 /* set volid, next, partition */
29 register struct volser_trans *tt;
33 /* don't allow the same volume to be attached twice */
34 for(tt=allTrans;tt;tt=tt->next) {
35 if ((tt->volid == avol) && (tt->partition == apart)){
36 return (struct volser_trans *) 0; /* volume busy */
39 tt = (struct volser_trans *) malloc(sizeof(struct volser_trans));
40 bzero(tt, sizeof(struct volser_trans));
42 tt->partition = apart;
44 tt->tid = transCounter++;
46 tt->rxCallPtr = (struct rx_call *)0;
47 strcpy(tt->lastProcName,"");
48 gettimeofday(&tp,&tzp);
49 tt->creationTime = tp.tv_sec;
51 tt->time = FT_ApproxTime();
55 /* find a trans, again returning with high ref count */
56 struct volser_trans *FindTrans(atrans)
57 register afs_int32 atrans; {
58 register struct volser_trans *tt;
59 for(tt=allTrans;tt;tt=tt->next) {
60 if (tt->tid == atrans) {
61 tt->time = FT_ApproxTime();
66 return (struct volser_trans *) 0;
69 /* delete transaction if refcount == 1, otherwise queue delete for later. Does implicit TRELE */
71 register struct volser_trans *atrans; {
72 register struct volser_trans *tt, **lt;
75 if (atrans->refCount > 1) {
76 /* someone else is using it now */
78 atrans->tflags |= TTDeleted;
81 /* otherwise we zap it ourselves */
83 for(tt = *lt; tt; lt = &tt->next, tt = *lt) {
86 VDetachVolume(&error, tt->volume);
87 tt->volume = (struct Volume *) 0;
93 return -1; /* failed to find the transaction in the generic list */
96 /* THOLD is a macro defined in volser.h */
98 /* put a transaction back */
100 register struct volser_trans *at; {
101 if (at->refCount == 0){
102 Log("TRELE: bad refcount\n");
103 return VOLSERTRELE_ERROR;
106 at->time = FT_ApproxTime(); /* we're still using it */
107 if (at->refCount == 1 && (at->tflags & TTDeleted)) {
111 /* otherwise simply drop refcount */
116 /* look for old transactions and delete them */
117 #define OLDTRANSTIME 600 /* seconds */
118 #define OLDTRANSWARN 300 /* seconds */
119 static int GCDeletes = 0;
122 register struct volser_trans *tt, *nt;
125 now = FT_ApproxTime();
127 for(tt = allTrans; tt; tt=nt) {
128 nt = tt->next; /* remember in case we zap it */
129 if (tt->time + OLDTRANSWARN < now) {
130 Log("trans %u on volume %u %s than %d seconds\n",
132 ((tt->refCount>0)?"is older":"has been idle for more"),
133 (((now-tt->time)/GCWAKEUP)*GCWAKEUP));
135 if (tt->refCount > 0) continue;
136 if (tt->time + OLDTRANSTIME < now) {
137 Log("trans %u on volume %u has timed out\n", tt->tid, tt->volid);
138 tt->refCount++; /* we're using it now */
139 DeleteTrans(tt); /* drops refCount or deletes it */
145 /*return the head of the transaction list */
146 struct volser_trans *TransList()