]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
ubik: Unlock version lock before udisk_end
authorAndrew Deason <adeason@sinenomine.net>
Tue, 14 Oct 2014 18:17:27 +0000 (13:17 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Tue, 2 Dec 2014 22:57:00 +0000 (17:57 -0500)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
src/ubik/ubik.c

index bc203b00b08a09cf954199e8c11c76c6f8012d70..a22aaffa626f7caef74d673404b872fcdf24ec82 100644 (file)
@@ -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;
 }