#define CM_ERROR_BAD_LEVEL (CM_ERROR_BASE+52)
#define CM_ERROR_NOT_A_DFSLINK (CM_ERROR_BASE+53)
#define CM_ERROR_INEXACT_MATCH (CM_ERROR_BASE+54)
+#define CM_ERROR_BPLUS_NOMATCH (CM_ERROR_BASE+55)
/* Used by cm_FollowMountPoint and cm_GetVolumeByName */
#define RWVOL 0
afs_uint64 dir_create_time = 0;
afs_uint64 dir_remove_time = 0;
-afs_int32 cm_BPlusTrees = 0;
+afs_uint64 dir_enums = 0;
+
+afs_int32 cm_BPlusTrees = 1;
void cm_DirDumpStats(void)
{
afsi_log("Dir Lookup Hits: %-8d", dir_lookup_hits);
afsi_log(" Misses: %-8d", dir_lookup_misses);
+ afsi_log(" Enums: %-8d", dir_enums);
afsi_log(" Create: %-8d", dir_create_entry);
afsi_log(" Remove: %-8d", dir_remove_entry);
extern void
cm_DirDumpStats(void);
+
+extern afs_int64 dir_enums;
#endif /* __CM_DIR_ENV__ */
return 0;
}
- return CM_ERROR_NOSUCHFILE;
+ return CM_ERROR_BPLUS_NOMATCH;
}
#endif
}
goto haveFid;
}
- return CM_ERROR_NOSUCHFILE;
+ return CM_ERROR_BPLUS_NOMATCH;
}
#endif
}
else
osi_Log0(afsd_logp, "CALL RemoveFile SUCCESS");
- lock_ObtainWrite(&dscp->dirlock);
- dirop.lockType = CM_DIRLOCK_WRITE;
+ if (dirop.scp) {
+ lock_ObtainWrite(&dirop.scp->dirlock);
+ dirop.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&dscp->mx);
cm_dnlcRemove(dscp, namep);
cm_SyncOpDone(dscp, NULL, sflags);
cm_ReleaseSCache(dirScp);
if (psp)
cm_FreeSpace(psp);
- if (code == CM_ERROR_NOSUCHFILE && tscp->fileType == CM_SCACHETYPE_SYMLINK) {
+ if ((code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) &&
+ tscp->fileType == CM_SCACHETYPE_SYMLINK)
+ {
osi_Log0(afsd_logp,"cm_NameI code CM_ERROR_NOSUCHPATH");
return CM_ERROR_NOSUCHPATH;
} else {
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_DIRSEARCH,
userp, NULL, reqp, outScpp);
- if (code == CM_ERROR_NOSUCHFILE)
+ if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH)
code = CM_ERROR_NOSUCHPATH;
/* this stuff is allocated no matter what happened on the namei call,
else
osi_Log0(afsd_logp, "CALL CreateFile SUCCESS");
- lock_ObtainWrite(&dscp->dirlock);
- dirop.lockType = CM_DIRLOCK_WRITE;
+ if (dirop.scp) {
+ lock_ObtainWrite(&dirop.scp->dirlock);
+ dirop.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
else
osi_Log0(afsd_logp, "CALL MakeDir SUCCESS");
- lock_ObtainWrite(&dscp->dirlock);
- dirop.lockType = CM_DIRLOCK_WRITE;
+ if (dirop.scp) {
+ lock_ObtainWrite(&dirop.scp->dirlock);
+ dirop.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
else
osi_Log0(afsd_logp, "CALL Link SUCCESS");
- lock_ObtainWrite(&dscp->dirlock);
- dirop.lockType = CM_DIRLOCK_WRITE;
+ if (dirop.scp) {
+ lock_ObtainWrite(&dirop.scp->dirlock);
+ dirop.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+ }
+ lock_ReleaseMutex(&dscp->mx);
+
+ if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
cm_DirCreateEntry(&dirop, namep, &sscp->fid);
#ifdef USE_BPLUS
}
}
cm_EndDirOp(&dirop);
- lock_ReleaseMutex(&dscp->mx);
return code;
}
else
osi_Log0(afsd_logp, "CALL Symlink SUCCESS");
- lock_ObtainWrite(&dscp->dirlock);
- dirop.lockType = CM_DIRLOCK_WRITE;
+ if (dirop.scp) {
+ lock_ObtainWrite(&dirop.scp->dirlock);
+ dirop.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+ }
+ lock_ReleaseMutex(&dscp->mx);
+
+ if (code == 0) {
if (cm_CheckDirOpForSingleChange(&dirop)) {
newFid.cell = dscp->fid.cell;
newFid.volume = dscp->fid.volume;
}
}
cm_EndDirOp(&dirop);
- lock_ReleaseMutex(&dscp->mx);
/* now try to create the new dir's entry, too, but be careful to
* make sure that we don't merge in old info. Since we weren't locking
else
osi_Log0(afsd_logp, "CALL RemoveDir SUCCESS");
- lock_ObtainWrite(&dscp->dirlock);
- dirop.lockType = CM_DIRLOCK_WRITE;
+ if (dirop.scp) {
+ lock_ObtainWrite(&dirop.scp->dirlock);
+ dirop.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&dscp->mx);
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0) {
osi_Log0(afsd_logp, "CALL Rename SUCCESS");
/* update the individual stat cache entries for the directories */
- lock_ObtainWrite(&oldDscp->dirlock);
- oldDirOp.lockType = CM_DIRLOCK_WRITE;
+ if (oldDirOp.scp) {
+ lock_ObtainWrite(&oldDirOp.scp->dirlock);
+ oldDirOp.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&oldDscp->mx);
cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA);
/* and update it for the new one, too, if necessary */
if (!oneDir) {
- lock_ObtainWrite(&newDscp->dirlock);
- newDirOp.lockType = CM_DIRLOCK_WRITE;
+ if (newDirOp.scp) {
+ lock_ObtainWrite(&newDirOp.scp->dirlock);
+ newDirOp.lockType = CM_DIRLOCK_WRITE;
+ }
lock_ObtainMutex(&newDscp->mx);
cm_SyncOpDone(newDscp, NULL, CM_SCACHESYNC_STOREDATA);
if (code == 0)
else if (code == CM_ERROR_READONLY) {
NTStatus = 0xC00000A2L; /* Write protected */
}
- else if (code == CM_ERROR_NOSUCHFILE) {
+ else if (code == CM_ERROR_NOSUCHFILE ||
+ code == CM_ERROR_BPLUS_NOMATCH) {
NTStatus = 0xC000000FL; /* No such file */
}
else if (code == CM_ERROR_NOSUCHPATH) {
class = 3;
error = 19; /* read only */
}
- else if (code == CM_ERROR_NOSUCHFILE) {
+ else if (code == CM_ERROR_NOSUCHFILE ||
+ code == CM_ERROR_BPLUS_NOMATCH) {
class = 1;
error = 2; /* ENOENT! */
}
/* Check if the file already exists; if so return error */
code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
- if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
+ if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) &&
+ (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
+ {
osi_Log2(smb_logp, " lookup returns %ld for [%s]", code,
osi_LogSaveString(smb_logp, newLastNamep));
/* Check if the file already exists; if so return error */
code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
- if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
+ if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) &&
+ (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
+ {
osi_Log2(smb_logp, " lookup returns %ld for [%s]", code,
osi_LogSaveString(smb_logp, newLastNamep));
lastNamep++;
code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp);
if (scp) cm_ReleaseSCache(scp);
- if (code != CM_ERROR_NOSUCHFILE) {
+ if (code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
if (code == 0) code = CM_ERROR_EXISTS;
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
#endif
code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp);
- if (code && code != CM_ERROR_NOSUCHFILE) {
+ if (code && code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
return code;
lastNamep++;
code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp,
&req, &scp);
- if (code && code != CM_ERROR_NOSUCHFILE) {
+ if (code && code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
smb_FreeTran2Packet(outp);
/* if a case sensitive match failed, we try a case insensitive one
next. */
- if (code == CM_ERROR_NOSUCHFILE) {
+ if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) {
code = cm_Lookup(scp, maskp, CM_FLAG_NOMOUNTCHASE | CM_FLAG_CASEFOLD, userp, &req, &targetscp);
}
smb_ReceiveTran2SearchDir(). */
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if (code != CM_ERROR_NOSUCHFILE) {
+ if (code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
smb_SendTran2Error(vcp, p, opx, code);
code = 0;
}
osi_Log0(smb_logp, "T2SDSingle done.");
- if (code != CM_ERROR_NOSUCHFILE) {
+ if (code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
if (code)
smb_SendTran2Error(vcp, p, opx, code);
else
/* we only failover if we see a CM_ERROR_NOSUCHFILE */
if (code != CM_ERROR_NOSUCHFILE) {
+#ifdef USE_BPLUS
+ if (code == CM_ERROR_BPLUS_NOMATCH)
+ code = CM_ERROR_NOSUCHFILE;
+#endif
return code;
}
}
#endif
+ dir_enums++;
dsp = smb_NewDirSearch(1);
dsp->attribute = attribute;
lastNamep++;
code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp,
&req, &scp);
- if (code && code != CM_ERROR_NOSUCHFILE) {
+ if (code && code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
return code;
#endif /* DFS_SUPPORT */
code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, CM_FLAG_FOLLOW,
userp, &req, &scp);
- if (code == CM_ERROR_NOSUCHFILE) {
+ if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) {
code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp);
if (code == 0 && realDirFlag == 1) {
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, &req, &scp);
}
- if (code && code != CM_ERROR_NOSUCHFILE) {
+ if (code && (code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH)) {
if (dscp)
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
* it will appear as a directory name of the nul-string
* and a code of CM_ERROR_NOSUCHFILE
*/
- if ( !*treeStartp && code == CM_ERROR_NOSUCHFILE)
+ if ( !*treeStartp && (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH))
code = CM_ERROR_EXISTS;
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
#endif /* DFS_SUPPORT */
code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, CM_FLAG_FOLLOW,
userp, &req, &scp);
- if (code == CM_ERROR_NOSUCHFILE) {
+ if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) {
code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp);
if (code == 0 && realDirFlag == 1) {
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, &req, &scp);
}
- if (code && code != CM_ERROR_NOSUCHFILE) {
+ if (code && code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);