From 4103aee514615c46e919202fb7842b9b2e254ff9 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Tue, 14 Oct 2014 13:17:27 -0500 Subject: [PATCH] ubik: Unlock version lock before udisk_end Currently, BeginTrans calls udisk_end with UBIK_VERSION_LOCK held when it gets an error from DISK_Begin. However, udisk_end itself acquires UBIK_VERSION_LOCK to update the database flags, so this causes a deadlock. So, unlock UBIK_VERSION_LOCK before calling udisk_end. Also unlock it before calling DISK_Abort, udisk_abort, and DISK_Begin, as well, since none of those modify fields protected by UBIK_VERSION_LOCK. (Any read access is allowed because we DBHOLD the database.) This commit unlocks the lock immediately after we are done modifying versioning information, which is right after we change writeTidCounter for write transactions. Change-Id: I31343d67c82734ff88b76bec740ef16767bb9667 Reviewed-on: http://gerrit.openafs.org/11541 Tested-by: BuildBot Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: Benjamin Kaduk Reviewed-by: Jeffrey Altman --- src/ubik/ubik.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ubik/ubik.c b/src/ubik/ubik.c index bc203b00b..a22aaffa6 100644 --- a/src/ubik/ubik.c +++ b/src/ubik/ubik.c @@ -667,7 +667,11 @@ BeginTrans(struct ubik_dbase *dbase, afs_int32 transMode, if (transMode == UBIK_WRITETRANS) { /* for a write trans, we have to keep track of the write tid counter too */ dbase->writeTidCounter = tt->tid.counter; + } + + UBIK_VERSION_UNLOCK; + if (transMode == UBIK_WRITETRANS) { /* next try to start transaction on appropriate number of machines */ code = ContactQuorum_NoArguments(DISK_Begin, tt, 0); if (code) { @@ -675,14 +679,12 @@ BeginTrans(struct ubik_dbase *dbase, afs_int32 transMode, udisk_abort(tt); ContactQuorum_NoArguments(DISK_Abort, tt, 0); /* force aborts to the others */ udisk_end(tt); - UBIK_VERSION_UNLOCK; DBRELE(dbase); return code; } } *transPtr = tt; - UBIK_VERSION_UNLOCK; DBRELE(dbase); return 0; } -- 2.39.5