ubik: Don't leak UBIK_VERSION_LOCK if udisk_LogEnd fails
authorSimon Wilkinson <sxw@your-file-system.com>
Mon, 25 Aug 2014 15:25:43 +0000 (16:25 +0100)
committerJeffrey Altman <jaltman@your-file-system.com>
Thu, 4 Sep 2014 12:52:19 +0000 (08:52 -0400)
If the call to udisk_LogEnd() fails (probably due to an I/O error)
don't leak the UBIK_VERSION_LOCK.

This is the possible cause of a vlserver deadlock, which had
approximately 4800 threads blocked. Analysis of backtrace of all
of these threads showed that all blocked threads were waiting in
ubik.c:555 (blocked on DBHOLD) with the exception of:

One in beacon.c:388 (blocked on UBIK_VERSION_LOCK)
One in recovery.c:503 (blocked on DBHOLD)
One in ubik.c:125 (blocked on DBHOLD)
One in ubik.c:585 (blocked on UBIK_VERSION_LOCK)

The last of these is the critical one, because it already holds
the lock that DBHOLD waits on - so despite the vast majority of
threads being blocked in DBHOLD, it's actually UBIK_VERSION_LOCK
that we're waiting on.

There is no sign of a thread which is still active which currently
holds UBIK_VERSION_LOCK.

Change-Id: I1627b448d359152237912d4d78c9fa52c7149aa0
Reviewed-on: http://gerrit.openafs.org/11427
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Perry Ruiter <pruiter@sinenomine.net>
Reviewed-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/ubik/disk.c

index b0da8dc..f4434e9 100644 (file)
@@ -910,7 +910,8 @@ udisk_commit(struct ubik_trans *atrans)
        code = udisk_LogEnd(dbase, &dbase->version);
        if (code) {
            dbase->version.counter--;
-           return (code);
+           UBIK_VERSION_UNLOCK;
+           return code;
        }
        UBIK_VERSION_UNLOCK;