From: Simon Wilkinson Date: Mon, 25 Aug 2014 15:15:26 +0000 (+0100) Subject: ubik: Don't leak UBIK_VERSION_LOCK if setlabel fails X-Git-Tag: upstream/1.8.0_pre1^2~590 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=b9bbd21e88e2050957c1a7d49f3ad603cae763b2;p=packages%2Fo%2Fopenafs.git ubik: Don't leak UBIK_VERSION_LOCK if setlabel fails If a call to the setlabel() physical IO function fails, 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: Ie6093409e9375d50fa69733908b5ce99586e1b1d Reviewed-on: http://gerrit.openafs.org/11426 Tested-by: BuildBot Reviewed-by: Perry Ruiter Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: Jeffrey Altman --- diff --git a/src/ubik/disk.c b/src/ubik/disk.c index acf007700..b0da8dc66 100644 --- a/src/ubik/disk.c +++ b/src/ubik/disk.c @@ -881,8 +881,11 @@ udisk_commit(struct ubik_trans *atrans) newversion.counter = 1; code = (*dbase->setlabel) (dbase, 0, &newversion); - if (code) - return (code); + if (code) { + UBIK_VERSION_UNLOCK; + return code; + } + version_globals.ubik_epochTime = newversion.epoch; dbase->version = newversion; UBIK_VERSION_UNLOCK;