From 5e52289abf12261b9575a0226ae8c7b5e37e6e51 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Sat, 22 Nov 2003 02:57:04 +0000 Subject: [PATCH] tvolser-update-20031121 add transaction mutex to handle global list of transactions --- src/vol/volume.c | 3 +++ src/vol/volume.h | 7 ++++++ src/volser/volmain.c | 14 +++++++++-- src/volser/voltrans.c | 57 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/vol/volume.c b/src/vol/volume.c index 1d53d06f0..87138fca2 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -149,6 +149,7 @@ RCSID pthread_mutex_t vol_glock_mutex; pthread_mutex_t vol_attach_mutex; pthread_mutex_t vol_fsync_mutex; +pthread_mutex_t vol_trans_mutex; pthread_cond_t vol_put_volume_cond; pthread_cond_t vol_sleep_cond; #endif /* AFS_PTHREAD_ENV */ @@ -246,6 +247,8 @@ VInitVolumePackage(ProgramType pt, int nLargeVnodes, int nSmallVnodes, #ifdef AFS_PTHREAD_ENV assert(pthread_mutex_init(&vol_glock_mutex, NULL) == 0); assert(pthread_mutex_init(&vol_attach_mutex, NULL) == 0); + assert(pthread_mutex_init(&vol_fsync_mutex, NULL) == 0); + assert(pthread_mutex_init(&vol_trans_mutex, NULL) == 0); assert(pthread_cond_init(&vol_put_volume_cond, NULL) == 0); assert(pthread_cond_init(&vol_sleep_cond, NULL) == 0); #else /* AFS_PTHREAD_ENV */ diff --git a/src/vol/volume.h b/src/vol/volume.h index d01e5b56b..c0756092d 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -31,6 +31,7 @@ typedef bit32 FileOffset; /* Offset in this file */ extern pthread_mutex_t vol_glock_mutex; extern pthread_mutex_t vol_attach_mutex; extern pthread_mutex_t vol_fsync_mutex; +extern pthread_mutex_t vol_trans_mutex; extern pthread_cond_t vol_put_volume_cond; extern pthread_cond_t vol_sleep_cond; #define VATTACH_LOCK \ @@ -45,6 +46,10 @@ extern pthread_cond_t vol_sleep_cond; assert(pthread_mutex_lock(&vol_fsync_mutex) == 0); #define VFSYNC_UNLOCK \ assert(pthread_mutex_unlock(&vol_fsync_mutex) == 0); +#define VTRANS_LOCK \ + assert(pthread_mutex_lock(&vol_trans_mutex) == 0); +#define VTRANS_UNLOCK \ + assert(pthread_mutex_unlock(&vol_trans_mutex) == 0); #else /* AFS_PTHREAD_ENV */ #define VATTACH_LOCK #define VATTACH_UNLOCK @@ -52,6 +57,8 @@ extern pthread_cond_t vol_sleep_cond; #define VOL_UNLOCK #define VFSYNC_LOCK #define VFSYNC_UNLOCK +#define VTRANS_LOCK +#define VTRANS_UNLOCK #endif /* AFS_PTHREAD_ENV */ typedef enum { fileServer, volumeUtility, salvager } ProgramType; diff --git a/src/volser/volmain.c b/src/volser/volmain.c index 8fa9058a4..829054c8d 100644 --- a/src/volser/volmain.c +++ b/src/volser/volmain.c @@ -107,14 +107,18 @@ int Testing = 0; /* for ListViceInodes */ static MyBeforeProc(struct rx_call *acall) { + VTRANS_LOCK; runningCalls++; + VTRANS_UNLOCK; return 0; } static MyAfterProc(struct rx_call *acall, afs_int32 code) { + VTRANS_LOCK; runningCalls--; + VTRANS_UNLOCK; return 0; } @@ -126,9 +130,12 @@ TryUnlock() { /* if there are no running calls, and there are no active transactions, then * it should be safe to release any partition locks we've accumulated */ + VTRANS_LOCK; if (runningCalls == 0 && TransList() == (struct volser_trans *)0) { + VTRANS_UNLOCK; VPFullUnlock(); /* in volprocs.c */ - } + } else + VTRANS_UNLOCK; } /* background daemon for timing out transactions */ @@ -170,6 +177,7 @@ BKGSleep() #else /* AFS_PTHREAD_ENV */ IOMGR_Sleep(TTrun); #endif + VTRANS_LOCK; for (tt = TransList(); tt; tt = tt->next) { if ((strcmp(tt->lastProcName, "DeleteVolume") == 0) || (strcmp(tt->lastProcName, "Clone") == 0) @@ -180,8 +188,10 @@ BKGSleep() break; } if (tt) { + VTRANS_UNLOCK; sleep(TTsleep); - } + } else + VTRANS_UNLOCK; } } } diff --git a/src/volser/voltrans.c b/src/volser/voltrans.c index 376858ad5..6dd744c8a 100644 --- a/src/volser/voltrans.c +++ b/src/volser/voltrans.c @@ -26,6 +26,42 @@ RCSID #include #endif +#include +#include +#include +#ifdef AFS_NT40_ENV +#include +#include +#else +#include +#include +#include +#endif +#include +#include +#include +#include +#ifdef AFS_PTHREAD_ENV +#include +#else /* AFS_PTHREAD_ENV */ +#include +#endif /* AFS_PTHREAD_ENV */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef AFS_NT40_ENV +#include +#endif +#include +#include + #ifdef HAVE_STRING_H #include #else @@ -34,7 +70,6 @@ RCSID #endif #endif -#include #include "volser.h" /*@printflike@*/ extern void Log(const char *format, ...); @@ -53,25 +88,30 @@ NewTrans(avol, apart) struct timeval tp; struct timezone tzp; + VTRANS_LOCK; /* don't allow the same volume to be attached twice */ for (tt = allTrans; tt; tt = tt->next) { if ((tt->volid == avol) && (tt->partition == apart)) { + VTRANS_UNLOCK; return (struct volser_trans *)0; /* volume busy */ } } + VTRANS_UNLOCK; tt = (struct volser_trans *)malloc(sizeof(struct volser_trans)); memset(tt, 0, sizeof(struct volser_trans)); tt->volid = avol; tt->partition = apart; - tt->next = allTrans; - tt->tid = transCounter++; tt->refCount = 1; tt->rxCallPtr = (struct rx_call *)0; strcpy(tt->lastProcName, ""); gettimeofday(&tp, &tzp); tt->creationTime = tp.tv_sec; - allTrans = tt; tt->time = FT_ApproxTime(); + VTRANS_LOCK; + tt->tid = transCounter++; + tt->next = allTrans; + allTrans = tt; + VTRANS_UNLOCK; return tt; } @@ -81,13 +121,16 @@ FindTrans(atrans) register afs_int32 atrans; { register struct volser_trans *tt; + VTRANS_LOCK; for (tt = allTrans; tt; tt = tt->next) { if (tt->tid == atrans) { tt->time = FT_ApproxTime(); tt->refCount++; + VTRANS_UNLOCK; return tt; } } + VTRANS_UNLOCK; return (struct volser_trans *)0; } @@ -104,7 +147,9 @@ DeleteTrans(atrans) atrans->tflags |= TTDeleted; return 0; } + /* otherwise we zap it ourselves */ + VTRANS_LOCK; lt = &allTrans; for (tt = *lt; tt; lt = &tt->next, tt = *lt) { if (tt == atrans) { @@ -113,9 +158,11 @@ DeleteTrans(atrans) tt->volume = NULL; *lt = tt->next; free(tt); + VTRANS_UNLOCK; return 0; } } + VTRANS_UNLOCK; return -1; /* failed to find the transaction in the generic list */ } @@ -151,6 +198,7 @@ GCTrans() now = FT_ApproxTime(); + VTRANS_LOCK; for (tt = allTrans; tt; tt = nt) { nt = tt->next; /* remember in case we zap it */ if (tt->time + OLDTRANSWARN < now) { @@ -168,6 +216,7 @@ GCTrans() GCDeletes++; } } + VTRANS_UNLOCK; return 0; } -- 2.39.5