From 249a5934605106f9025643321eb8e24f113fdd2a Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 10 Mar 2013 10:49:42 -0400 Subject: [PATCH] Windows: IsSpaceAvail lock order violation cm_IsSpaceAvailable() obtains the cm_scache.rw lock of the volume root directory. Therefore it is a lock order violation to call the function while any other cm_scache.rw lock is held belonging to an object in the same volume. vnode 1 is always less than any other vnode value. Change-Id: Id34591b6ccec8d7e8e0fe48e3357c991cd99acfb Reviewed-on: http://gerrit.openafs.org/9552 Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- src/WINNT/afsd/cm_vnodeops.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 512289483..963140e63 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -2828,6 +2828,7 @@ long cm_SetLength(cm_scache_t *scp, osi_hyper_t *sizep, cm_user_t *userp, { long code; int shrinking; + int available; /* start by locking out buffer creation */ lock_ObtainWrite(&scp->bufCreateLock); @@ -2899,9 +2900,19 @@ long cm_SetLength(cm_scache_t *scp, osi_hyper_t *sizep, cm_user_t *userp, scp->mask |= CM_SCACHEMASK_LENGTH; } else if (LargeIntegerGreaterThan(*sizep, scp->length)) { - /* really extending the file */ - /* Check to see if we have sufficient quota */ - if (cm_IsSpaceAvailable(&scp->fid, sizep, userp, reqp)) { + /* + * Really extending the file so must check to see if we + * have sufficient quota. cm_IsSpaceAvailable() obtains + * the cm_scache.rw lock on the volume root directory. + * vnode 1 < scp->fid.vnode therefore calling cm_IsSpaceAvailable + * while holding scp->rw is a lock order violation. + * Dropping it is ok because we are holding scp->bufCreateLock + * which prevents the size of the file from changing. + */ + lock_ReleaseWrite(&scp->rw); + available = cm_IsSpaceAvailable(&scp->fid, sizep, userp, reqp); + lock_ObtainWrite(&scp->rw); + if (available) { scp->length = *sizep; scp->mask |= CM_SCACHEMASK_LENGTH; } else { -- 2.39.5