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>
24 #include <afs/afsutil.h>
30 #include <sys/types.h>
37 #include <netinet/in.h>
42 #include <afs/afsint.h>
44 #ifdef AFS_PTHREAD_ENV
46 #else /* AFS_PTHREAD_ENV */
47 #include <afs/assert.h>
48 #endif /* AFS_PTHREAD_ENV */
49 #include <afs/prs_fs.h>
54 #include <afs/cellconfig.h>
58 #include <afs/ihandle.h>
60 #include <afs/ntops.h>
62 #include <afs/vnode.h>
63 #include <afs/volume.h>
75 /*@printflike@*/ extern void Log(const char *format, ...);
77 static struct volser_trans *allTrans = 0;
78 static afs_int32 transCounter = 1;
80 /* create a new transaction, returning ptr to same with high ref count */
86 /* set volid, next, partition */
87 register struct volser_trans *tt;
92 /* don't allow the same volume to be attached twice */
93 for (tt = allTrans; tt; tt = tt->next) {
94 if ((tt->volid == avol) && (tt->partition == apart)) {
96 return (struct volser_trans *)0; /* volume busy */
100 tt = (struct volser_trans *)malloc(sizeof(struct volser_trans));
101 memset(tt, 0, sizeof(struct volser_trans));
103 tt->partition = apart;
105 tt->rxCallPtr = (struct rx_call *)0;
106 strcpy(tt->lastProcName, "");
107 gettimeofday(&tp, &tzp);
108 tt->creationTime = tp.tv_sec;
109 tt->time = FT_ApproxTime();
111 tt->tid = transCounter++;
118 /* find a trans, again returning with high ref count */
119 struct volser_trans *
121 register afs_int32 atrans;
123 register struct volser_trans *tt;
125 for (tt = allTrans; tt; tt = tt->next) {
126 if (tt->tid == atrans) {
127 tt->time = FT_ApproxTime();
134 return (struct volser_trans *)0;
137 /* delete transaction if refcount == 1, otherwise queue delete for later. Does implicit TRELE */
139 register struct volser_trans *atrans;
141 register struct volser_trans *tt, **lt;
144 if (atrans->refCount > 1) {
145 /* someone else is using it now */
147 atrans->tflags |= TTDeleted;
151 /* otherwise we zap it ourselves */
154 for (tt = *lt; tt; lt = &tt->next, tt = *lt) {
157 VDetachVolume(&error, tt->volume);
166 return -1; /* failed to find the transaction in the generic list */
169 /* THOLD is a macro defined in volser.h */
171 /* put a transaction back */
173 register struct volser_trans *at;
175 if (at->refCount == 0) {
176 Log("TRELE: bad refcount\n");
177 return VOLSERTRELE_ERROR;
180 at->time = FT_ApproxTime(); /* we're still using it */
181 if (at->refCount == 1 && (at->tflags & TTDeleted)) {
185 /* otherwise simply drop refcount */
190 /* look for old transactions and delete them */
191 #define OLDTRANSTIME 600 /* seconds */
192 #define OLDTRANSWARN 300 /* seconds */
193 static int GCDeletes = 0;
196 register struct volser_trans *tt, *nt;
199 now = FT_ApproxTime();
202 for (tt = allTrans; tt; tt = nt) {
203 nt = tt->next; /* remember in case we zap it */
204 if (tt->time + OLDTRANSWARN < now) {
205 Log("trans %u on volume %u %s than %d seconds\n", tt->tid,
207 ((tt->refCount > 0) ? "is older" : "has been idle for more"),
208 (((now - tt->time) / GCWAKEUP) * GCWAKEUP));
210 if (tt->refCount > 0)
212 if (tt->time + OLDTRANSTIME < now) {
213 Log("trans %u on volume %u has timed out\n", tt->tid, tt->volid);
214 tt->refCount++; /* we're using it now */
215 DeleteTrans(tt); /* drops refCount or deletes it */
223 /*return the head of the transaction list */
224 struct volser_trans *