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
13 * Instituition: ITC, CMU
17 #include <afsconfig.h>
18 #include <afs/param.h>
23 #include <afs/afsutil.h>
30 static struct volser_trans *allTrans=0;
31 static afs_int32 transCounter = 1;
33 /* create a new transaction, returning ptr to same with high ref count */
34 struct volser_trans *NewTrans(avol, apart)
37 /* set volid, next, partition */
38 register struct volser_trans *tt;
42 /* don't allow the same volume to be attached twice */
43 for(tt=allTrans;tt;tt=tt->next) {
44 if ((tt->volid == avol) && (tt->partition == apart)){
45 return (struct volser_trans *) 0; /* volume busy */
48 tt = (struct volser_trans *) malloc(sizeof(struct volser_trans));
49 memset(tt, 0, sizeof(struct volser_trans));
51 tt->partition = apart;
53 tt->tid = transCounter++;
55 tt->rxCallPtr = (struct rx_call *)0;
56 strcpy(tt->lastProcName,"");
57 gettimeofday(&tp,&tzp);
58 tt->creationTime = tp.tv_sec;
60 tt->time = FT_ApproxTime();
64 /* find a trans, again returning with high ref count */
65 struct volser_trans *FindTrans(atrans)
66 register afs_int32 atrans; {
67 register struct volser_trans *tt;
68 for(tt=allTrans;tt;tt=tt->next) {
69 if (tt->tid == atrans) {
70 tt->time = FT_ApproxTime();
75 return (struct volser_trans *) 0;
78 /* delete transaction if refcount == 1, otherwise queue delete for later. Does implicit TRELE */
80 register struct volser_trans *atrans; {
81 register struct volser_trans *tt, **lt;
84 if (atrans->refCount > 1) {
85 /* someone else is using it now */
87 atrans->tflags |= TTDeleted;
90 /* otherwise we zap it ourselves */
92 for(tt = *lt; tt; lt = &tt->next, tt = *lt) {
95 VDetachVolume(&error, tt->volume);
96 tt->volume = (struct Volume *) 0;
102 return -1; /* failed to find the transaction in the generic list */
105 /* THOLD is a macro defined in volser.h */
107 /* put a transaction back */
109 register struct volser_trans *at; {
110 if (at->refCount == 0){
111 Log("TRELE: bad refcount\n");
112 return VOLSERTRELE_ERROR;
115 at->time = FT_ApproxTime(); /* we're still using it */
116 if (at->refCount == 1 && (at->tflags & TTDeleted)) {
120 /* otherwise simply drop refcount */
125 /* look for old transactions and delete them */
126 #define OLDTRANSTIME 600 /* seconds */
127 #define OLDTRANSWARN 300 /* seconds */
128 static int GCDeletes = 0;
131 register struct volser_trans *tt, *nt;
134 now = FT_ApproxTime();
136 for(tt = allTrans; tt; tt=nt) {
137 nt = tt->next; /* remember in case we zap it */
138 if (tt->time + OLDTRANSWARN < now) {
139 Log("trans %u on volume %u %s than %d seconds\n",
141 ((tt->refCount>0)?"is older":"has been idle for more"),
142 (((now-tt->time)/GCWAKEUP)*GCWAKEUP));
144 if (tt->refCount > 0) continue;
145 if (tt->time + OLDTRANSTIME < now) {
146 Log("trans %u on volume %u has timed out\n", tt->tid, tt->volid);
147 tt->refCount++; /* we're using it now */
148 DeleteTrans(tt); /* drops refCount or deletes it */
154 /*return the head of the transaction list */
155 struct volser_trans *TransList()