windows-aclent-remove-extraneous-code-20071024

Microsoft provided a dump showing cm_data.aclLRUEndp == NULL in
GetFreeACLEnt().  Couldn't find any reason why that would be true.
However, there is extraneous code that manipulates the value of
aclLRUEndp when it should be left to osi_QRemoveHT() to update
the pointer values.

Also add an additional explicit test for aclLRUEndp == NULL in
GetFreeACLEnt().
This commit is contained in:
Jeffrey Altman 2007-10-25 05:47:23 +00:00
parent 511aed14e0
commit fb7595ad1d
5 changed files with 303 additions and 8 deletions

View File

@ -1362,7 +1362,6 @@ int afsd_InitSMB(char **reasonP, void *aMBfunc)
void afsd_printStack(HANDLE hThread, CONTEXT *c)
{
#if defined(_X86_)
HANDLE hProcess = GetCurrentProcess();
int frameNum;
#if defined(_AMD64_)
@ -1409,9 +1408,9 @@ void afsd_printStack(HANDLE hThread, CONTEXT *c)
#error The STACKFRAME initialization in afsd_printStack() for this platform
#error must be properly configured
#elif defined(_AMD64_)
s.AddrPC.Offset = 0;
s.AddrPC.Offset = c->Rip;
s.AddrPC.Mode = AddrModeFlat;
s.AddrFrame.Offset = 0;
s.AddrFrame.Offset = c->Rbp;
s.AddrFrame.Mode = AddrModeFlat;
#else
s.AddrPC.Offset = c->Eip;
@ -1511,7 +1510,6 @@ void afsd_printStack(HANDLE hThread, CONTEXT *c)
SymCleanup(hProcess);
GlobalFree(pSym);
#endif /* _X86_ */
}
#ifdef _DEBUG
@ -1660,6 +1658,9 @@ LONG __stdcall afsd_ExceptionFilter(EXCEPTION_POINTERS *ep)
#endif
#if defined(_X86)
ep->ContextRecord->Eip++;
#endif
#if defined(_AMD64_)
ep->ContextRecord->Rip++;
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}

View File

@ -90,9 +90,6 @@ long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, afs_uint32 *rightsp)
} else {
*rightsp = aclp->randomAccess;
if (cm_data.aclLRUp != aclp) {
if (cm_data.aclLRUEndp == aclp)
cm_data.aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
/* move to the head of the LRU queue */
osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
osi_QAddH((osi_queue_t **) &cm_data.aclLRUp,
@ -121,8 +118,10 @@ static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp)
if (cm_data.aclLRUp == NULL)
osi_panic("empty aclent LRU", __FILE__, __LINE__);
if (cm_data.aclLRUEndp == NULL)
osi_panic("inconsistent aclent LRUEndp == NULL", __FILE__, __LINE__);
aclp = cm_data.aclLRUEndp;
cm_data.aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
if (aclp->backp && scp != aclp->backp) {

View File

@ -1743,6 +1743,9 @@ long cm_BPlusDirBuildTree(cm_scache_t *scp, cm_user_t *userp, cm_req_t* reqp)
bplus_build_time += (end.QuadPart - start.QuadPart);
#if 0
cm_BPlusDirEnumTest(scp, 1);
#endif
return rc;
}
@ -1802,4 +1805,260 @@ void cm_BPlusDumpStats(void)
afsi_log(" Build: %-16I64d", bplus_build_time);
afsi_log(" Free: %-16I64d", bplus_free_time);
}
static cm_direnum_t *
cm_BPlusEnumAlloc(afs_uint32 entries)
{
cm_direnum_t * enump;
size_t size;
if (entries == 0)
return NULL;
size = sizeof(cm_direnum_t)+(entries-1)*sizeof(cm_direnum_entry_t);
enump = (cm_direnum_t *)malloc(size);
memset(enump, 0, size);
enump->count = entries;
return enump;
}
long
cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked,
char * maskp, cm_direnum_t **enumpp)
{
afs_uint32 count = 0, slot, numentries;
Nptr leafNode = NONODE, nextLeafNode;
Nptr firstDataNode, dataNode, nextDataNode;
cm_direnum_t * enump;
long rc = 0;
char buffer[512];
OutputDebugString("cm_BPlusDirEnumerate start");
/* Read lock the bplus tree so the data can't change */
if (!locked)
lock_ObtainRead(&scp->dirlock);
if (scp->dirBplus == NULL) {
OutputDebugString("cm_BPlusDirEnumerate No BPlus Tree");
goto done;
}
/* Compute the number of entries */
for (count = 0, leafNode = getleaf(scp->dirBplus); leafNode; leafNode = nextLeafNode) {
for ( slot = 1, numentries = numentries(leafNode); slot <= numentries; slot++) {
firstDataNode = getnode(leafNode, slot);
for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) {
if (maskp == NULL) {
/* name is in getdatakey(dataNode) */
if (getdatavalue(dataNode).longname != NULL ||
cm_Is8Dot3(getdatakey(dataNode).name))
count++;
} else {
if (cm_Is8Dot3(getdatakey(dataNode).name) &&
smb_V3MatchMask(getdatakey(dataNode).name, maskp, CM_FLAG_CASEFOLD) ||
getdatavalue(dataNode).longname == NULL &&
smb_V3MatchMask(getdatavalue(dataNode).longname, maskp, CM_FLAG_CASEFOLD))
count++;
}
nextDataNode = getdatanext(dataNode);
}
}
nextLeafNode = getnextnode(leafNode);
}
sprintf(buffer, "BPlusTreeEnumerate count = %d", count);
OutputDebugString(buffer);
/* Allocate the enumeration object */
enump = cm_BPlusEnumAlloc(count);
if (enump == NULL) {
OutputDebugString("cm_BPlusDirEnumerate Alloc failed");
rc = ENOMEM;
goto done;
}
/* Copy the name and fid for each longname entry into the enumeration */
for (count = 0, leafNode = getleaf(scp->dirBplus); leafNode; leafNode = nextLeafNode) {
for ( slot = 1, numentries = numentries(leafNode); slot <= numentries; slot++) {
firstDataNode = getnode(leafNode, slot);
for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) {
char * name;
int hasShortName;
int includeIt = 0;
if (maskp == NULL) {
if (getdatavalue(dataNode).longname != NULL ||
cm_Is8Dot3(getdatakey(dataNode).name))
{
includeIt = 1;
}
} else {
if (cm_Is8Dot3(getdatakey(dataNode).name) &&
smb_V3MatchMask(getdatakey(dataNode).name, maskp, CM_FLAG_CASEFOLD) ||
getdatavalue(dataNode).longname == NULL &&
smb_V3MatchMask(getdatavalue(dataNode).longname, maskp, CM_FLAG_CASEFOLD))
{
includeIt = 1;
}
}
if (includeIt) {
if (getdatavalue(dataNode).longname) {
name = strdup(getdatavalue(dataNode).longname);
hasShortName = 1;
} else {
name = strdup(getdatakey(dataNode).name);
hasShortName = 0;
}
if (name == NULL) {
OutputDebugString("cm_BPlusDirEnumerate strdup failed");
rc = ENOMEM;
goto done;
}
enump->entry[count].name = name;
enump->entry[count].fid = getdatavalue(dataNode).fid;
if (hasShortName)
strncpy(enump->entry[count].shortName, getdatakey(dataNode).name,
sizeof(enump->entry[count].shortName));
else
enump->entry[count].shortName[0] = '\0';
count++;
}
nextDataNode = getdatanext(dataNode);
}
}
nextLeafNode = getnextnode(leafNode);
}
done:
if (!locked)
lock_ReleaseRead(&scp->dirlock);
/* if we failed, cleanup any mess */
if (rc != 0) {
OutputDebugString("cm_BPlusDirEnumerate rc != 0");
if (enump) {
for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
free(enump->entry[count].name);
}
free(enump);
enump = NULL;
}
}
OutputDebugString("cm_BPlusDirEnumerate end");
*enumpp = enump;
return rc;
}
long
cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp)
{
if (enump == NULL || entrypp == NULL || enump->next > enump->count) {
if (entrypp)
*entrypp = NULL;
OutputDebugString("cm_BPlusDirNextEnumEntry invalid input");
return CM_ERROR_INVAL; \
}
*entrypp = &enump->entry[enump->next++];
if ( enump->next == enump->count ) {
OutputDebugString("cm_BPlusDirNextEnumEntry STOPNOW");
return CM_ERROR_STOPNOW;
}
else {
OutputDebugString("cm_BPlusDirNextEnumEntry SUCCESS");
return 0;
}
}
long
cm_BPlusDirFreeEnumeration(cm_direnum_t *enump)
{
afs_uint32 count;
OutputDebugString("cm_BPlusDirFreeEnumeration");
if (enump) {
for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
free(enump->entry[count].name);
}
free(enump);
}
return 0;
}
long
cm_BPlusDirEnumTest(cm_scache_t * dscp, afs_uint32 locked)
{
cm_direnum_t * enump = NULL;
cm_direnum_entry_t * entryp;
long code;
OutputDebugString("cm_BPlusDirEnumTest start");
for (code = cm_BPlusDirEnumerate(dscp, locked, NULL, &enump); code == 0; ) {
code = cm_BPlusDirNextEnumEntry(enump, &entryp);
if (code == 0 || code == CM_ERROR_STOPNOW) {
char buffer[1024];
cm_scache_t *scp;
char * type = "ScpNotFound";
afs_int32 dv = -1;
scp = cm_FindSCache(&entryp->fid);
if (scp) {
switch (scp->fileType) {
case CM_SCACHETYPE_FILE :
type = "File";
break;
case CM_SCACHETYPE_DIRECTORY :
type = "Directory";
break;
case CM_SCACHETYPE_SYMLINK :
type = "Symlink";
break;
case CM_SCACHETYPE_MOUNTPOINT:
type = "MountPoint";
break;
case CM_SCACHETYPE_DFSLINK :
type = "Dfs";
break;
case CM_SCACHETYPE_INVALID :
type = "Invalid";
break;
default:
type = "Unknown";
break;
}
dv = scp->dataVersion;
cm_ReleaseSCache(scp);
}
sprintf(buffer, "'%s' Fid = (%d,%d,%d,%d) Short = '%s' Type %s DV %d",
entryp->name,
entryp->fid.cell, entryp->fid.volume, entryp->fid.vnode, entryp->fid.unique,
entryp->shortName,
type,
dv);
OutputDebugString(buffer);
}
}
if (enump)
cm_BPlusDirFreeEnumeration(enump);
OutputDebugString("cm_BPlusDirEnumTest end");
return 0;
}
#endif /* USE_BPLUS */

View File

@ -145,6 +145,25 @@ long cm_BPlusDirBuildTree(cm_scache_t *scp, cm_user_t *userp, cm_req_t* reqp);
void cm_BPlusDumpStats(void);
int cm_MemDumpBPlusStats(FILE *outputFile, char *cookie, int lock);
/******************* directory enumeration operations ****************/
typedef struct cm_direnum_entry {
char * name;
cm_fid_t fid;
char shortName[13];
} cm_direnum_entry_t;
typedef struct cm_direnum {
afs_uint32 count;
afs_uint32 next;
cm_direnum_entry_t entry[1];
} cm_direnum_t;
long cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, char *maskp, cm_direnum_t **enumpp);
long cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp);
long cm_BPlusDirFreeEnumeration(cm_direnum_t *enump);
long cm_BPlusDirEnumTest(cm_scache_t * dscp, afs_uint32 locked);
extern afs_uint32 bplus_free_tree;
extern afs_uint32 bplus_dv_error;
extern afs_uint64 bplus_free_time;

View File

@ -194,3 +194,20 @@ void cm_CheckTokenCache(time_t now)
}
lock_ReleaseWrite(&smb_rctLock);
}
#ifdef USE_ROOT_TOKENS
/*
* Service/Parameters/RootTokens/<cellname>/
* -> UseLSA
* -> Keytab (required if UseLSA is 0)
* -> Principal (required if there is more than one principal in the keytab)
* -> Realm (required if realm is not upper-case of <cellname>
* -> RequireEncryption
*/
void
cm_RefreshRootTokens(void)
{
}
#endif