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 #ifdef AFS_PTHREAD_ENV
24 # include <opr/lock.h>
28 #include <afs/afsutil.h>
31 #include <rx/rx_queue.h>
32 #include <afs/afsint.h>
33 #include <afs/prs_fs.h>
37 #include <afs/cellconfig.h>
41 #include <afs/ihandle.h>
43 #include <afs/ntops.h>
45 #include <afs/vnode.h>
46 #include <afs/volume.h>
50 #include "volser_internal.h"
52 static struct volser_trans
*allTrans
= 0;
53 static afs_int32 transCounter
= 1;
55 /* create a new transaction, returning ptr to same with high ref count */
57 NewTrans(VolumeId avol
, afs_int32 apart
)
59 /* set volid, next, partition */
60 struct volser_trans
*tt
, *newtt
;
63 newtt
= calloc(1, sizeof(struct volser_trans
));
65 /* don't allow the same volume to be attached twice */
66 for (tt
= allTrans
; tt
; tt
= tt
->next
) {
67 if ((tt
->volid
== avol
) && (tt
->partition
== apart
)) {
70 return (struct volser_trans
*)0; /* volume busy */
75 tt
->partition
= apart
;
77 tt
->rxCallPtr
= (struct rx_call
*)0;
78 strcpy(tt
->lastProcName
, "");
79 gettimeofday(&tp
, NULL
);
80 tt
->creationTime
= tp
.tv_sec
;
81 tt
->time
= FT_ApproxTime();
82 tt
->tid
= transCounter
++;
84 VTRANS_OBJ_LOCK_INIT(tt
);
90 /* find a trans, again returning with high ref count */
92 FindTrans(afs_int32 atrans
)
94 struct volser_trans
*tt
;
96 for (tt
= allTrans
; tt
; tt
= tt
->next
) {
97 if (tt
->tid
== atrans
) {
98 tt
->time
= FT_ApproxTime();
105 return (struct volser_trans
*)0;
108 /* delete transaction if refcount == 1, otherwise queue delete for later. Does implicit TRELE */
110 DeleteTrans(struct volser_trans
*atrans
, afs_int32 lock
)
112 struct volser_trans
*tt
, **lt
;
115 if (lock
) VTRANS_LOCK
;
116 if (atrans
->refCount
> 1) {
117 /* someone else is using it now */
119 atrans
->tflags
|= TTDeleted
;
120 if (lock
) VTRANS_UNLOCK
;
124 /* otherwise we zap it ourselves */
126 for (tt
= *lt
; tt
; lt
= &tt
->next
, tt
= *lt
) {
129 VDetachVolume(&error
, tt
->volume
);
132 rxi_CallError(tt
->rxCallPtr
, RX_CALL_DEAD
);
134 VTRANS_OBJ_LOCK_DESTROY(tt
);
136 if (lock
) VTRANS_UNLOCK
;
140 if (lock
) VTRANS_UNLOCK
;
141 return -1; /* failed to find the transaction in the generic list */
144 /* THOLD is a macro defined in volser.h */
146 /* put a transaction back */
148 TRELE(struct volser_trans
*at
)
151 if (at
->refCount
== 0) {
152 Log("TRELE: bad refcount\n");
154 return VOLSERTRELE_ERROR
;
157 at
->time
= FT_ApproxTime(); /* we're still using it */
158 if (at
->refCount
== 1 && (at
->tflags
& TTDeleted
)) {
163 /* otherwise simply drop refcount */
169 /* look for old transactions and delete them */
170 #define OLDTRANSTIME 600 /* seconds */
171 #define OLDTRANSWARN 300 /* seconds */
172 static int GCDeletes
= 0;
176 struct volser_trans
*tt
, *nt
;
179 now
= FT_ApproxTime();
182 for (tt
= allTrans
; tt
; tt
= nt
) {
183 nt
= tt
->next
; /* remember in case we zap it */
184 if (tt
->time
+ OLDTRANSWARN
< now
) {
185 Log("trans %u on volume %" AFS_VOLID_FMT
" %s than %d seconds\n", tt
->tid
,
186 afs_printable_VolumeId_lu(tt
->volid
),
187 ((tt
->refCount
> 0) ? "is older" : "has been idle for more"),
188 (((now
- tt
->time
) / GCWAKEUP
) * GCWAKEUP
));
190 if (tt
->refCount
> 0)
192 if (tt
->time
+ OLDTRANSTIME
< now
) {
193 Log("trans %u on volume %" AFS_VOLID_FMT
" has timed out\n", tt
->tid
, afs_printable_VolumeId_lu(tt
->volid
));
195 tt
->refCount
++; /* we're using it now */
197 if (tt
->volume
&& V_destroyMe(tt
->volume
) == DESTROY_ME
198 && !(tt
->vflags
& VTDeleted
)) {
202 Log("Deleting timed-out temporary volume %lu\n",
203 (long unsigned) tt
->volid
);
206 tt
->vflags
|= VTDeleted
;
207 VTRANS_OBJ_UNLOCK(tt
);
210 VPurgeVolume(&error
, tt
->volume
);
214 DeleteTrans(tt
, 0); /* drops refCount or deletes it */
222 /*return the head of the transaction list */
223 struct volser_trans
*