#include <afs/param.h>
#include <afs/stds.h>
-#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
-#endif /* !DJGPP */
#include <string.h>
#include <stdlib.h>
#include <osi.h>
#include "afsd.h"
+#include <WINNT/afsreg.h>
osi_rwlock_t cm_dnlcLock;
* 1. If nameHash[i] is NULL, list is empty
* 2. A single element in a hash bucket has itself as prev and next.
*/
-#ifndef DJGPP
-#define dnlcNotify(x,debug){ \
- HANDLE hh; \
- char *ptbuf[1]; \
- ptbuf[0] = x; \
- if ( debug ) { \
- hh = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); \
- ReportEvent(hh,EVENTLOG_ERROR_TYPE,0,__LINE__, \
- NULL, 1, 0, ptbuf, NULL); \
- DeregisterEventSource(hh); \
- } \
- }
-#else
-#define dnlcNotify(x,debug)
-#endif /* !DJGPP */
/* Must be called with cm_dnlcLock write locked */
static cm_nc_t *
tnc = cm_data.nameHash[nameptr];
if (!tnc)
{
- dnlcNotify("null tnc in GetMeAnEntry",1);
osi_Log0(afsd_logp,"null tnc in GetMeAnEntry");
return 0;
}
}
static void
-InsertEntry(tnc)
- cm_nc_t *tnc;
+InsertEntry(cm_nc_t *tnc)
{
unsigned int key;
key = tnc->key & (NHSIZE -1);
unsigned int key, skey, new=0;
char *ts = aname;
int safety;
+ int writeLocked = 0;
if (!cm_useDnlc)
return ;
-
+
+ if (!strcmp(aname,".") || !strcmp(aname,".."))
+ return ;
+
if ( cm_debugDnlc )
osi_Log3(afsd_logp,"cm_dnlcEnter dir %x name %s scache %x",
adp, osi_LogSaveString(afsd_logp,aname), avc);
return ;
skey = key & (NHSIZE -1);
- lock_ObtainWrite(&cm_dnlcLock);
- dnlcstats.enters++;
-
+ InterlockedIncrement(&dnlcstats.enters);
+ lock_ObtainRead(&cm_dnlcLock);
+ retry:
for (tnc = cm_data.nameHash[skey], safety=0; tnc; tnc = tnc->next, safety++ )
if ((tnc->dirp == adp) && (!strcmp(tnc->name, aname)))
break; /* preexisting entry */
}
else if (safety > NCSIZE)
{
- dnlcstats.cycles++;
- lock_ReleaseWrite(&cm_dnlcLock);
+ InterlockedIncrement(&dnlcstats.cycles);
+ if (writeLocked)
+ lock_ReleaseWrite(&cm_dnlcLock);
+ else
+ lock_ReleaseRead(&cm_dnlcLock);
- dnlcNotify("DNLC cycle",1);
if ( cm_debugDnlc )
osi_Log0(afsd_logp, "DNLC cycle");
cm_dnlcPurge();
if ( !tnc )
{
+ if ( !writeLocked ) {
+ lock_ConvertRToW(&cm_dnlcLock);
+ writeLocked = 1;
+ goto retry;
+ }
new = 1; /* entry does not exist, we are creating a new entry*/
tnc = GetMeAnEntry();
}
InsertEntry(tnc);
}
- lock_ReleaseWrite(&cm_dnlcLock);
+ if (writeLocked)
+ lock_ReleaseWrite(&cm_dnlcLock);
+ else
+ lock_ReleaseRead(&cm_dnlcLock);
if ( !tnc)
cm_dnlcPurge();
int safety, match;
if (!cm_useDnlc)
- return 0;
+ return NULL;
+
if ( cm_debugDnlc )
osi_Log2(afsd_logp, "cm_dnlcLookup dir %x name %s",
adp, osi_LogSaveString(afsd_logp,aname));
dnlcHash( ts, key ); /* leaves ts pointing at the NULL */
- if (ts - aname >= CM_AFSNCNAMESIZE)
- return 0;
+
+ if (ts - aname >= CM_AFSNCNAMESIZE) {
+ InterlockedIncrement(&dnlcstats.lookups);
+ InterlockedIncrement(&dnlcstats.misses);
+ return NULL;
+ }
skey = key & (NHSIZE -1);
lock_ObtainRead(&cm_dnlcLock);
- dnlcstats.lookups++; /* Is a dnlcread lock sufficient? */
+ InterlockedIncrement(&dnlcstats.lookups);
ts = 0;
tnc_begin = cm_data.nameHash[skey];
- for ( tvc = (cm_scache_t *) 0, tnc = tnc_begin, safety=0;
+ for ( tvc = (cm_scache_t *) NULL, tnc = tnc_begin, safety=0;
tnc; tnc = tnc->next, safety++ )
{
if (tnc->dirp == adp)
}
else if (tnc->next == tnc_begin || safety > NCSIZE)
{
- dnlcstats.cycles++;
+ InterlockedIncrement(&dnlcstats.cycles);
lock_ReleaseRead(&cm_dnlcLock);
- dnlcNotify("DNLC cycle",1);
if ( cm_debugDnlc )
osi_Log0(afsd_logp, "DNLC cycle");
cm_dnlcPurge();
- return(0);
+ return(NULL);
}
}
}
if (!tvc)
- dnlcstats.misses++; /* Is a dnlcread lock sufficient? */
+ InterlockedIncrement(&dnlcstats.misses);
else
{
sp->found = 1;
static int
-RemoveEntry (tnc, key)
- cm_nc_t *tnc;
- unsigned int key;
+RemoveEntry (cm_nc_t *tnc, unsigned int key)
{
if (!tnc->prev) /* things on freelist always have null prev ptrs */
{
- dnlcNotify("Bogus dnlc freelist", 1);
osi_Log0(afsd_logp,"Bogus dnlc freelist");
return 1; /* error */
}
void
-cm_dnlcRemove ( adp, aname)
- cm_scache_t *adp;
- char *aname;
+cm_dnlcRemove (cm_scache_t *adp, char *aname)
{
unsigned int key, skey, error=0;
int found= 0, safety;
skey = key & (NHSIZE -1);
lock_ObtainWrite(&cm_dnlcLock);
- dnlcstats.removes++;
+ InterlockedIncrement(&dnlcstats.removes);
for (tnc = cm_data.nameHash[skey], safety=0; tnc; safety++)
{
tnc = tnc->next;
if ( safety > NCSIZE )
{
- dnlcstats.cycles++;
+ InterlockedIncrement(&dnlcstats.cycles);
lock_ReleaseWrite(&cm_dnlcLock);
- dnlcNotify("DNLC cycle",1);
if ( cm_debugDnlc )
osi_Log0(afsd_logp, "DNLC cycle");
cm_dnlcPurge();
/* remove anything pertaining to this directory */
void
-cm_dnlcPurgedp (adp)
- cm_scache_t *adp;
+cm_dnlcPurgedp (cm_scache_t *adp)
{
int i;
int err=0;
osi_Log1(afsd_logp, "cm_dnlcPurgedp dir %x", adp);
lock_ObtainWrite(&cm_dnlcLock);
- dnlcstats.purgeds++;
+ InterlockedIncrement(&dnlcstats.purgeds);
for (i=0; i<NCSIZE && !err; i++)
{
/* remove anything pertaining to this file */
void
-cm_dnlcPurgevp ( avc )
- cm_scache_t *avc;
+cm_dnlcPurgevp (cm_scache_t *avc)
{
int i;
int err=0;
osi_Log1(afsd_logp, "cm_dnlcPurgevp scache %x", avc);
lock_ObtainWrite(&cm_dnlcLock);
- dnlcstats.purgevs++;
+ InterlockedIncrement(&dnlcstats.purgevs);
for (i=0; i<NCSIZE && !err ; i++)
{
osi_Log0(afsd_logp, "cm_dnlcPurge");
lock_ObtainWrite(&cm_dnlcLock);
- dnlcstats.purges++;
+ InterlockedIncrement(&dnlcstats.purges);
cm_data.ncfreelist = (cm_nc_t *) 0;
memset (cm_data.nameCache, 0, sizeof(cm_nc_t) * NCSIZE);
}
/* remove everything referencing a specific volume */
+/* is this function ever called? */
void
-cm_dnlcPurgeVol( fidp )
- AFSFid *fidp;
+cm_dnlcPurgeVol(AFSFid *fidp)
{
if (!cm_useDnlc)
return ;
- dnlcstats.purgevols++;
+ InterlockedIncrement(&dnlcstats.purgevols);
cm_dnlcPurge();
}
cm_dnlcInit(int newFile)
{
int i;
-
- if (!cm_useDnlc)
- return ;
+ HKEY parmKey;
+ DWORD dummyLen;
+ DWORD dwValue;
+ DWORD code;
+
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ dummyLen = sizeof(DWORD);
+ code = RegQueryValueEx(parmKey, "UseDNLC", NULL, NULL,
+ (BYTE *) &dwValue, &dummyLen);
+ if (code == ERROR_SUCCESS)
+ cm_useDnlc = dwValue ? 1 : 0;
+ afsi_log("CM UseDNLC = %d", cm_useDnlc);
+
+ dummyLen = sizeof(DWORD);
+ code = RegQueryValueEx(parmKey, "DebugDNLC", NULL, NULL,
+ (BYTE *) &dwValue, &dummyLen);
+ if (code == ERROR_SUCCESS)
+ cm_debugDnlc = dwValue ? 1 : 0;
+ afsi_log("CM DebugDNLC = %d", cm_debugDnlc);
+ RegCloseKey (parmKey);
+ }
if ( cm_debugDnlc )
osi_Log0(afsd_logp,"cm_dnlcInit");