VirtualBox

Changeset 2868 in kBuild


Ignore:
Timestamp:
Sep 4, 2016 1:28:12 AM (9 years ago)
Author:
bird
Message:

Only invalidate the PATH_OUT and TEMP in kWorker.

Location:
trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/kWorker.c

    r2867 r2868  
    47164716
    47174717    /*
    4718      * Invalidate the missing cache entries.
     4718     * Invalidate the volatile parts of cache (kBuild output directory,
     4719     * temporary directory, whatever).
    47194720     */
    4720     kFsCacheInvalidateMissing(g_pFsCache);
     4721    kFsCacheInvalidateCustomBoth(g_pFsCache);
    47214722    return 0;
    47224723}
     
    52345235int main(int argc, char **argv)
    52355236{
    5236     KSIZE   cbMsgBuf = 0;
    5237     KU8    *pbMsgBuf = NULL;
    5238     int     i;
    5239     HANDLE  hPipe = INVALID_HANDLE_VALUE;
     5237    KSIZE           cbMsgBuf = 0;
     5238    KU8            *pbMsgBuf = NULL;
     5239    int             i;
     5240    HANDLE          hPipe = INVALID_HANDLE_VALUE;
     5241    const char     *pszTmp;
     5242    KFSLOOKUPERROR  enmIgnored;
    52405243
    52415244    /*
    5242      * Create the cache.
     5245     * Create the cache and mark the temporary directory as using the custom revision.
    52435246     */
    52445247    g_pFsCache = kFsCacheCreate(KFSCACHE_F_MISSING_OBJECTS | KFSCACHE_F_MISSING_PATHS);
    52455248    if (!g_pFsCache)
    52465249        return kwErrPrintfRc(3, "kFsCacheCreate failed!\n");
     5250
     5251    pszTmp = getenv("TEMP");
     5252    if (pszTmp && *pszTmp != '\0')
     5253        kFsCacheSetupCustomRevisionForTree(g_pFsCache, kFsCacheLookupA(g_pFsCache, pszTmp, &enmIgnored));
     5254    pszTmp = getenv("TMP");
     5255    if (pszTmp && *pszTmp != '\0')
     5256        kFsCacheSetupCustomRevisionForTree(g_pFsCache, kFsCacheLookupA(g_pFsCache, pszTmp, &enmIgnored));
     5257    pszTmp = getenv("TMPDIR");
     5258    if (pszTmp && *pszTmp != '\0')
     5259        kFsCacheSetupCustomRevisionForTree(g_pFsCache, kFsCacheLookupA(g_pFsCache, pszTmp, &enmIgnored));
    52475260
    52485261    /*
     
    52715284                return kwErrPrintfRc(2, "--pipe takes an argument!\n");
    52725285        }
     5286        else if (strcmp(argv[i], "--volatile") == 0)
     5287        {
     5288            i++;
     5289            if (i < argc)
     5290                kFsCacheSetupCustomRevisionForTree(g_pFsCache, kFsCacheLookupA(g_pFsCache, argv[i], &enmIgnored));
     5291            else
     5292                return kwErrPrintfRc(2, "--volatile takes an argument!\n");
     5293        }
    52735294        else if (strcmp(argv[i], "--test") == 0)
    52745295            return kwTestRun(argc - i - 1, &argv[i + 1]);
     
    52775298                 || strcmp(argv[i], "-?") == 0)
    52785299        {
    5279             printf("usage: kWorker --pipe <pipe-handle>\n"
     5300            printf("usage: kWorker [--volatile dir] --pipe <pipe-handle>\n"
    52805301                   "usage: kWorker <--help|-h>\n"
    52815302                   "usage: kWorker <--version|-V>\n"
    5282                    "usage: kWorker --test [<times> [--chdir <dir>]] -- args\n"
     5303                   "usage: kWorker [--volatile dir] --test [<times> [--chdir <dir>]] -- args\n"
    52835304                   "\n"
    52845305                   "This is an internal kmk program that is used via the builtin_kSubmit.\n");
  • trunk/src/kmk/dir-nt-bird.c

    r2862 r2868  
    114114                {
    115115                    PKFSOBJ pNameObj = kFsCacheLookupRelativeToDirA(g_pFsCache, (PKFSDIR)pDirObj,
    116                                                                     pszName, strlen(pszName), &enmError);
     116                                                                    pszName, strlen(pszName), &enmError, NULL);
    117117                    if (pNameObj)
    118118                    {
  • trunk/src/kmk/kmkbuiltin/kSubmit.c

    r2858 r2868  
    307307    size_t const    cbExecutableBuf = GET_PATH_MAX;
    308308    PATH_VAR(szExecutable);
     309#define TUPLE(a_sz)     a_sz, sizeof(a_sz) - 1
     310    struct variable *pVarVolatile = lookup_variable(TUPLE("PATH_OUT"));
     311    if (pVarVolatile)
     312    { /* likely */ }
     313    else
     314    {
     315        pVarVolatile = lookup_variable(TUPLE("PATH_OUT_BASE"));
     316        if (!pVarVolatile)
     317            warn("Neither PATH_OUT_BASE nor PATH_OUT was found.");
     318    }
    309319
    310320    /*
     
    373383                {
    374384                    char        szHandleArg[32];
    375                     const char *apszArgs[4] = { szExecutable, "--pipe", szHandleArg, NULL };
     385                    const char *apszArgs[6] =
     386                    {
     387                        szExecutable, "--pipe", szHandleArg,
     388                        pVarVolatile ? "--volatile" : NULL, pVarVolatile ? pVarVolatile->value : NULL,
     389                        NULL
     390                    };
    376391                    _snprintf(szHandleArg, sizeof(szHandleArg), "%p", hWorkerPipe);
    377392
  • trunk/src/lib/nt/kFsCache.c

    r2866 r2868  
    399399 * @param   fAbsolute           Whether it can be refreshed using an absolute
    400400 *                              lookup or requires the slow treatment.
     401 * @parma   idxMissingGen       The missing generation index.
    401402 * @param   idxHashTab          The hash table index of the path.
    402403 * @param   enmError            The lookup error.
    403404 */
    404405static PKFSHASHA kFsCacheCreatePathHashTabEntryA(PKFSCACHE pCache, PKFSOBJ pFsObj, const char *pszPath, KU32 cchPath,
    405                                                  KU32 uHashPath, KU32 idxHashTab, BOOL fAbsolute, KFSLOOKUPERROR enmError)
     406                                                 KU32 uHashPath, KU32 idxHashTab, BOOL fAbsolute, KU32 idxMissingGen,
     407                                                 KFSLOOKUPERROR enmError)
    406408{
    407409    PKFSHASHA pHashEntry = (PKFSHASHA)kHlpAlloc(sizeof(*pHashEntry) + cchPath + 1);
    408410    if (pHashEntry)
    409411    {
    410         pHashEntry->uHashPath   = uHashPath;
    411         pHashEntry->cchPath     = (KU16)cchPath;
    412         pHashEntry->fAbsolute   = fAbsolute;
    413         pHashEntry->pFsObj      = pFsObj;
    414         pHashEntry->enmError    = enmError;
    415         pHashEntry->pszPath     = (const char *)kHlpMemCopy(pHashEntry + 1, pszPath, cchPath + 1);
     412        pHashEntry->uHashPath       = uHashPath;
     413        pHashEntry->cchPath         = (KU16)cchPath;
     414        pHashEntry->fAbsolute       = fAbsolute;
     415        pHashEntry->idxMissingGen   = (KU8)idxMissingGen;
     416        pHashEntry->pFsObj          = pFsObj;
     417        pHashEntry->enmError        = enmError;
     418        pHashEntry->pszPath         = (const char *)kHlpMemCopy(pHashEntry + 1, pszPath, cchPath + 1);
    416419        if (pFsObj)
    417             pHashEntry->uCacheGen = pCache->uGeneration;
     420            pHashEntry->uCacheGen = pFsObj->bObjType != KFSOBJ_TYPE_MISSING
     421                                  ? pCache->auGenerations[       pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     422                                  : pCache->auGenerationsMissing[pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    418423        else if (enmError != KFSLOOKUPERROR_UNSUPPORTED)
    419             pHashEntry->uCacheGen = pCache->uGenerationMissing;
     424            pHashEntry->uCacheGen = pCache->auGenerationsMissing[idxMissingGen];
    420425        else
    421426            pHashEntry->uCacheGen = KFSOBJ_CACHE_GEN_IGNORE;
     
    444449 * @param   fAbsolute           Whether it can be refreshed using an absolute
    445450 *                              lookup or requires the slow treatment.
     451 * @parma   idxMissingGen       The missing generation index.
    446452 * @param   idxHashTab          The hash table index of the path.
    447453 * @param   enmError            The lookup error.
    448454 */
    449455static PKFSHASHW kFsCacheCreatePathHashTabEntryW(PKFSCACHE pCache, PKFSOBJ pFsObj, const wchar_t *pwszPath, KU32 cwcPath,
    450                                                  KU32 uHashPath, KU32 idxHashTab, BOOL fAbsolute, KFSLOOKUPERROR enmError)
     456                                                 KU32 uHashPath, KU32 idxHashTab, BOOL fAbsolute, KU32 idxMissingGen,
     457                                                 KFSLOOKUPERROR enmError)
    451458{
    452459    PKFSHASHW pHashEntry = (PKFSHASHW)kHlpAlloc(sizeof(*pHashEntry) + (cwcPath + 1) * sizeof(wchar_t));
    453460    if (pHashEntry)
    454461    {
    455         pHashEntry->uHashPath   = uHashPath;
    456         pHashEntry->cwcPath     = cwcPath;
    457         pHashEntry->fAbsolute   = fAbsolute;
    458         pHashEntry->pFsObj      = pFsObj;
    459         pHashEntry->enmError    = enmError;
    460         pHashEntry->pwszPath    = (const wchar_t *)kHlpMemCopy(pHashEntry + 1, pwszPath, (cwcPath + 1) * sizeof(wchar_t));
     462        pHashEntry->uHashPath       = uHashPath;
     463        pHashEntry->cwcPath         = cwcPath;
     464        pHashEntry->fAbsolute       = fAbsolute;
     465        pHashEntry->idxMissingGen   = (KU8)idxMissingGen;
     466        pHashEntry->pFsObj          = pFsObj;
     467        pHashEntry->enmError        = enmError;
     468        pHashEntry->pwszPath        = (const wchar_t *)kHlpMemCopy(pHashEntry + 1, pwszPath, (cwcPath + 1) * sizeof(wchar_t));
    461469        if (pFsObj)
    462             pHashEntry->uCacheGen = pCache->uGeneration;
     470            pHashEntry->uCacheGen = pFsObj->bObjType != KFSOBJ_TYPE_MISSING
     471                                  ? pCache->auGenerations[       pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     472                                  : pCache->auGenerationsMissing[pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    463473        else if (enmError != KFSLOOKUPERROR_UNSUPPORTED)
    464             pHashEntry->uCacheGen = pCache->uGenerationMissing;
     474            pHashEntry->uCacheGen = pCache->auGenerationsMissing[idxMissingGen];
    465475        else
    466476            pHashEntry->uCacheGen = KFSOBJ_CACHE_GEN_IGNORE;
     
    555565        pObj->u32Magic      = KFSOBJ_MAGIC;
    556566        pObj->cRefs         = 1;
    557         pObj->uCacheGen     = bObjType != KFSOBJ_TYPE_MISSING ? pCache->uGeneration : pCache->uGenerationMissing;
     567        pObj->uCacheGen     = bObjType != KFSOBJ_TYPE_MISSING
     568                            ? pCache->auGenerations[pParent->Obj.fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     569                            : pCache->auGenerationsMissing[pParent->Obj.fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    558570        pObj->bObjType      = bObjType;
    559571        pObj->fHaveStats    = K_FALSE;
    560572        pObj->abUnused[0]   = K_FALSE;
    561573        pObj->abUnused[1]   = K_FALSE;
    562         pObj->fFlags        = pParent->Obj.fFlags;
     574        pObj->fFlags        = pParent->Obj.fFlags & KFSOBJ_F_INHERITED_MASK;
    563575        pObj->pParent       = pParent;
    564576        pObj->pUserDataHead = NULL;
     
    15021514        pDir->fNeedRePopulating = K_FALSE;
    15031515        if (pDir->Obj.uCacheGen != KFSOBJ_CACHE_GEN_IGNORE)
    1504             pDir->Obj.uCacheGen = pCache->uGeneration;
     1516            pDir->Obj.uCacheGen = pCache->auGenerations[pDir->Obj.fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    15051517        return K_TRUE;
    15061518    }
     
    15441556        && !pDir->fNeedRePopulating
    15451557        && (   pDir->Obj.uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    1546             || pDir->Obj.uCacheGen == pCache->uGeneration) )
     1558            || pDir->Obj.uCacheGen == pCache->auGenerations[pDir->Obj.fFlags & KFSOBJ_F_USE_CUSTOM_GEN]) )
    15471559        return K_TRUE;
    15481560    return kFsCachePopuplateOrRefreshDir(pCache, pDir, penmError ? penmError : &enmIgnored);
     
    15901602    {
    15911603        KFSCACHE_LOG(("Parent of missing not written to %s/%s\n", pMissing->pParent->Obj.pszName, pMissing->pszName));
    1592         pMissing->uCacheGen = pCache->uGenerationMissing;
     1604        pMissing->uCacheGen = pCache->auGenerationsMissing[pMissing->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    15931605    }
    15941606    else
     
    16121624             * Probably more likely that a missing node stays missing.
    16131625             */
    1614             pMissing->uCacheGen = pCache->uGenerationMissing;
     1626            pMissing->uCacheGen = pCache->auGenerationsMissing[pMissing->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    16151627            KFSCACHE_LOG(("Still missing %s/%s\n", pMissing->pParent->Obj.pszName, pMissing->pszName));
    16161628        }
     
    16291641                          pMissing->pParent->Obj.pszName, pMissing->pszName, bObjType, BasicInfo.FileAttributes));
    16301642            pMissing->bObjType  = bObjType;
    1631             pMissing->uCacheGen = pCache->uGenerationMissing;
     1643            pMissing->uCacheGen = pCache->auGenerations[pMissing->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    16321644/**
    16331645 * @todo refresh missing object names when it appears.
     
    17991811            if (MY_NT_SUCCESS(rcNt))
    18001812            {
    1801                 pObj->uCacheGen = pCache->uGeneration;
     1813                pObj->uCacheGen = pCache->auGenerations[pObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    18021814                fRc = K_TRUE;
    18031815            }
     
    18581870            if (MY_NT_SUCCESS(rcNt))
    18591871            {
    1860                 pObj->uCacheGen = pCache->uGeneration;
     1872                pObj->uCacheGen = pCache->auGenerations[pObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
    18611873                fRc = K_TRUE;
    18621874            }
     
    22762288 * @param   penmError           Where to return details as to why the lookup
    22772289 *                              failed.
     2290 * @param   ppLastAncestor      Where to return the last parent element found
     2291 *                              (referenced) in case of error an path/file not
     2292 *                              found problem.  Optional.
    22782293 */
    22792294PKFSOBJ kFsCacheLookupRelativeToDirA(PKFSCACHE pCache, PKFSDIR pParent, const char *pszPath, KU32 cchPath,
    2280                                      KFSLOOKUPERROR *penmError)
     2295                                     KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
    22812296{
    22822297    /*
     
    22842299     */
    22852300    KU32 off = 0;
     2301    if (ppLastAncestor)
     2302        *ppLastAncestor = NULL;
    22862303    for (;;)
    22872304    {
     
    23122329        if (   pParent->fPopulated
    23132330            && (   pParent->Obj.uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2314                 || pParent->Obj.uCacheGen == pCache->uGeneration) )
     2331                || pParent->Obj.uCacheGen == pCache->auGenerations[pParent->Obj.fFlags & KFSOBJ_F_USE_CUSTOM_GEN]) )
    23152332        { /* likely */ }
    23162333        else if (kFsCachePopuplateOrRefreshDir(pCache, pParent, penmError))
     
    23402357            else
    23412358                *penmError = KFSLOOKUPERROR_PATH_COMP_NOT_FOUND;
     2359            if (ppLastAncestor)
     2360                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    23422361            return NULL;
    23432362        }
     
    23502369            if (   pChild->bObjType != KFSOBJ_TYPE_MISSING
    23512370                || pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2352                 || pChild->uCacheGen == pCache->uGenerationMissing
     2371                || pChild->uCacheGen == pCache->auGenerationsMissing[pChild->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
    23532372                || kFsCacheRefreshMissing(pCache, pChild, penmError) )
    23542373            { /* likely */ }
     
    23672386        {
    23682387            *penmError = KFSLOOKUPERROR_PATH_COMP_NOT_DIR;
     2388            if (ppLastAncestor)
     2389                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    23692390            return NULL;
    23702391        }
    23712392        else if (   pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2372                  || pChild->uCacheGen == pCache->uGenerationMissing)
     2393                 || pChild->uCacheGen == pCache->auGenerationsMissing[pChild->fFlags & KFSOBJ_F_USE_CUSTOM_GEN])
    23732394        {
    23742395            *penmError = KFSLOOKUPERROR_PATH_COMP_NOT_FOUND;
     2396            if (ppLastAncestor)
     2397                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    23752398            return NULL;
    23762399        }
     
    23782401            pParent = (PKFSDIR)pChild;
    23792402        else
     2403        {
     2404            if (ppLastAncestor)
     2405                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    23802406            return NULL;
     2407        }
    23812408    }
    23822409
     
    24012428 * @param   penmError           Where to return details as to why the lookup
    24022429 *                              failed.
     2430 * @param   ppLastAncestor      Where to return the last parent element found
     2431 *                              (referenced) in case of error an path/file not
     2432 *                              found problem.  Optional.
    24032433 */
    24042434PKFSOBJ kFsCacheLookupRelativeToDirW(PKFSCACHE pCache, PKFSDIR pParent, const wchar_t *pwszPath, KU32 cwcPath,
    2405                                      KFSLOOKUPERROR *penmError)
     2435                                     KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
    24062436{
    24072437    /*
     
    24092439     */
    24102440    KU32 off = 0;
     2441    if (ppLastAncestor)
     2442        *ppLastAncestor = NULL;
    24112443    for (;;)
    24122444    {
     
    24372469        if (   pParent->fPopulated
    24382470            && (   pParent->Obj.uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2439                 || pParent->Obj.uCacheGen == pCache->uGeneration) )
     2471                || pParent->Obj.uCacheGen == pCache->auGenerations[pParent->Obj.fFlags & KFSOBJ_F_USE_CUSTOM_GEN]) )
    24402472        { /* likely */ }
    24412473        else if (kFsCachePopuplateOrRefreshDir(pCache, pParent, penmError))
     
    24652497            else
    24662498                *penmError = KFSLOOKUPERROR_PATH_COMP_NOT_FOUND;
     2499            if (ppLastAncestor)
     2500                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    24672501            return NULL;
    24682502        }
     
    24752509            if (   pChild->bObjType != KFSOBJ_TYPE_MISSING
    24762510                || pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2477                 || pChild->uCacheGen == pCache->uGenerationMissing
     2511                || pChild->uCacheGen == pCache->auGenerationsMissing[pChild->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
    24782512                || kFsCacheRefreshMissing(pCache, pChild, penmError) )
    24792513            { /* likely */ }
     
    24922526        {
    24932527            *penmError = KFSLOOKUPERROR_PATH_COMP_NOT_DIR;
     2528            if (ppLastAncestor)
     2529                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    24942530            return NULL;
    24952531        }
    24962532        else if (   pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2497                  || pChild->uCacheGen == pCache->uGenerationMissing)
     2533                 || pChild->uCacheGen == pCache->auGenerationsMissing[pChild->fFlags & KFSOBJ_F_USE_CUSTOM_GEN])
    24982534        {
    24992535            *penmError = KFSLOOKUPERROR_PATH_COMP_NOT_FOUND;
     2536            if (ppLastAncestor)
     2537                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    25002538            return NULL;
    25012539        }
     
    25032541            pParent = (PKFSDIR)pChild;
    25042542        else
     2543        {
     2544            if (ppLastAncestor)
     2545                *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
    25052546            return NULL;
     2547        }
    25062548    }
    25072549
     
    25252567 * @param   penmError           Where to return details as to why the lookup
    25262568 *                              failed.
    2527  */
    2528 static PKFSOBJ kFsCacheLookupAbsoluteA(PKFSCACHE pCache, const char *pszPath, KU32 cchPath, KFSLOOKUPERROR *penmError)
    2529 {
    2530     PKFSOBJ     pChild;
     2569 * @param   ppLastAncestor      Where to return the last parent element found
     2570 *                              (referenced) in case of error an path/file not
     2571 *                              found problem.  Optional.
     2572 */
     2573static PKFSOBJ kFsCacheLookupAbsoluteA(PKFSCACHE pCache, const char *pszPath, KU32 cchPath,
     2574                                       KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
     2575{
     2576    PKFSOBJ     pRoot;
    25312577    KU32        cchSlashes;
    25322578    KU32        offEnd;
     
    25452591        offEnd = 2;
    25462592        kHlpAssert(IS_SLASH(pszPath[2]));
    2547         pChild = kFswCacheLookupDrive(pCache, toupper(pszPath[0]), penmError);
     2593        pRoot = kFswCacheLookupDrive(pCache, toupper(pszPath[0]), penmError);
    25482594    }
    25492595    else if (   IS_SLASH(pszPath[0])
    25502596             && IS_SLASH(pszPath[1]) )
    2551         pChild = kFswCacheLookupUncShareA(pCache, pszPath, &offEnd, penmError);
     2597        pRoot = kFswCacheLookupUncShareA(pCache, pszPath, &offEnd, penmError);
    25522598    else
    25532599    {
     
    25552601        return NULL;
    25562602    }
    2557     if (pChild)
     2603    if (pRoot)
    25582604    { /* likely */ }
    25592605    else
     
    25722618    if (offEnd >= cchPath)
    25732619    {
    2574         if (   pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2575             || pChild->uCacheGen == (pChild->bObjType != KFSOBJ_TYPE_MISSING ? pCache->uGeneration : pCache->uGenerationMissing)
    2576             || kFsCacheRefreshObj(pCache, pChild, penmError))
    2577             return kFsCacheObjRetainInternal(pChild);
     2620        if (   pRoot->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
     2621            || pRoot->uCacheGen == (  pRoot->bObjType != KFSOBJ_TYPE_MISSING
     2622                                    ? pCache->auGenerations[       pRoot->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     2623                                    : pCache->auGenerationsMissing[pRoot->fFlags & KFSOBJ_F_USE_CUSTOM_GEN])
     2624            || kFsCacheRefreshObj(pCache, pRoot, penmError))
     2625            return kFsCacheObjRetainInternal(pRoot);
    25782626        return NULL;
    25792627    }
    25802628
    25812629    /* Check that we've got a valid result and not a cached negative one. */
    2582     if (pChild->bObjType == KFSOBJ_TYPE_DIR)
     2630    if (pRoot->bObjType == KFSOBJ_TYPE_DIR)
    25832631    { /* likely */ }
    25842632    else
    25852633    {
    2586         kHlpAssert(pChild->bObjType == KFSOBJ_TYPE_MISSING);
    2587         kHlpAssert(pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE || pChild->uCacheGen == pCache->uGenerationMissing);
    2588         return pChild;
     2634        kHlpAssert(pRoot->bObjType == KFSOBJ_TYPE_MISSING);
     2635        kHlpAssert(   pRoot->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
     2636                   || pRoot->uCacheGen == pCache->auGenerationsMissing[pRoot->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]);
     2637        return pRoot;
    25892638    }
    25902639
     
    25932642     * remainder of the path starting with it.
    25942643     */
    2595     return kFsCacheLookupRelativeToDirA(pCache, (PKFSDIR)pChild, &pszPath[offEnd + cchSlashes],
    2596                                         cchPath - offEnd - cchSlashes, penmError);
     2644    return kFsCacheLookupRelativeToDirA(pCache, (PKFSDIR)pRoot, &pszPath[offEnd + cchSlashes],
     2645                                        cchPath - offEnd - cchSlashes, penmError, ppLastAncestor);
    25972646}
    25982647
     
    26122661 * @param   penmError           Where to return details as to why the lookup
    26132662 *                              failed.
    2614  */
    2615 static PKFSOBJ kFsCacheLookupAbsoluteW(PKFSCACHE pCache, const wchar_t *pwszPath, KU32 cwcPath, KFSLOOKUPERROR *penmError)
     2663 * @param   ppLastAncestor      Where to return the last parent element found
     2664 *                              (referenced) in case of error an path/file not
     2665 *                              found problem.  Optional.
     2666 */
     2667static PKFSOBJ kFsCacheLookupAbsoluteW(PKFSCACHE pCache, const wchar_t *pwszPath, KU32 cwcPath,
     2668                                       KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
    26162669{
    26172670    PKFSDIR     pParent = &pCache->RootDir;
    2618     PKFSOBJ     pChild;
     2671    PKFSOBJ     pRoot;
    26192672    KU32        off;
    26202673    KU32        cwcSlashes;
     
    26352688        offEnd = 2;
    26362689        kHlpAssert(IS_SLASH(pwszPath[2]));
    2637         pChild = kFswCacheLookupDrive(pCache, toupper(pwszPath[0]), penmError);
     2690        pRoot = kFswCacheLookupDrive(pCache, toupper(pwszPath[0]), penmError);
    26382691    }
    26392692    else if (   IS_SLASH(pwszPath[0])
    26402693             && IS_SLASH(pwszPath[1]) )
    2641         pChild = kFswCacheLookupUncShareW(pCache, pwszPath, &offEnd, penmError);
     2694        pRoot = kFswCacheLookupUncShareW(pCache, pwszPath, &offEnd, penmError);
    26422695    else
    26432696    {
     
    26452698        return NULL;
    26462699    }
    2647     if (pChild)
     2700    if (pRoot)
    26482701    { /* likely */ }
    26492702    else
     
    26622715    if (offEnd >= cwcPath)
    26632716    {
    2664         if (   pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2665             || pChild->uCacheGen == (pChild->bObjType != KFSOBJ_TYPE_MISSING ? pCache->uGeneration : pCache->uGenerationMissing)
    2666             || kFsCacheRefreshObj(pCache, pChild, penmError))
    2667             return kFsCacheObjRetainInternal(pChild);
     2717        if (   pRoot->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
     2718            || pRoot->uCacheGen == (pRoot->bObjType != KFSOBJ_TYPE_MISSING
     2719                                    ? pCache->auGenerations[       pRoot->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     2720                                    : pCache->auGenerationsMissing[pRoot->fFlags & KFSOBJ_F_USE_CUSTOM_GEN])
     2721            || kFsCacheRefreshObj(pCache, pRoot, penmError))
     2722            return kFsCacheObjRetainInternal(pRoot);
    26682723        return NULL;
    26692724    }
    26702725
    26712726    /* Check that we've got a valid result and not a cached negative one. */
    2672     if (pChild->bObjType == KFSOBJ_TYPE_DIR)
     2727    if (pRoot->bObjType == KFSOBJ_TYPE_DIR)
    26732728    { /* likely */ }
    26742729    else
    26752730    {
    2676         kHlpAssert(pChild->bObjType == KFSOBJ_TYPE_MISSING);
    2677         kHlpAssert(pChild->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE || pChild->uCacheGen == pCache->uGenerationMissing);
    2678         return pChild;
     2731        kHlpAssert(pRoot->bObjType == KFSOBJ_TYPE_MISSING);
     2732        kHlpAssert(   pRoot->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
     2733                   || pRoot->uCacheGen == pCache->auGenerationsMissing[pRoot->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]);
     2734        return pRoot;
    26792735    }
    26802736
     
    26832739     * remainder of the path starting with it.
    26842740     */
    2685     return kFsCacheLookupRelativeToDirW(pCache, (PKFSDIR)pChild, &pwszPath[offEnd + cwcSlashes],
    2686                                         cwcPath - offEnd - cwcSlashes, penmError);
     2741    return kFsCacheLookupRelativeToDirW(pCache, (PKFSDIR)pRoot, &pwszPath[offEnd + cwcSlashes],
     2742                                        cwcPath - offEnd - cwcSlashes, penmError, ppLastAncestor);
    26872743}
    26882744
     
    27002756 * @param   penmError           Where to return details as to why the lookup
    27012757 *                              failed.
    2702  */
    2703 static PKFSOBJ kFsCacheLookupSlowA(PKFSCACHE pCache, const char *pszPath, KU32 cchPath, KFSLOOKUPERROR *penmError)
     2758 * @param   ppLastAncestor      Where to return the last parent element found
     2759 *                              (referenced) in case of error an path/file not
     2760 *                              found problem.  Optional.
     2761 */
     2762static PKFSOBJ kFsCacheLookupSlowA(PKFSCACHE pCache, const char *pszPath, KU32 cchPath,
     2763                                   KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
    27042764{
    27052765    /*
     
    27142774        PKFSOBJ pFsObj;
    27152775        KFSCACHE_LOG2(("kFsCacheLookupSlowA(%s)\n", pszPath));
    2716         pFsObj = kFsCacheLookupAbsoluteA(pCache, szFull, cchFull, penmError);
     2776        pFsObj = kFsCacheLookupAbsoluteA(pCache, szFull, cchFull, penmError, ppLastAncestor);
    27172777
    27182778#if 0 /* No need to do this until it's actually queried. */
     
    27492809 * @param   penmError           Where to return details as to why the lookup
    27502810 *                              failed.
    2751  */
    2752 static PKFSOBJ kFsCacheLookupSlowW(PKFSCACHE pCache, const wchar_t *pwszPath, KU32 wcwPath, KFSLOOKUPERROR *penmError)
     2811 * @param   ppLastAncestor      Where to return the last parent element found
     2812 *                              (referenced) in case of error an path/file not
     2813 *                              found problem.  Optional.
     2814 */
     2815static PKFSOBJ kFsCacheLookupSlowW(PKFSCACHE pCache, const wchar_t *pwszPath, KU32 wcwPath,
     2816                                   KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
    27532817{
    27542818    /*
     
    27632827        PKFSOBJ pFsObj;
    27642828        KFSCACHE_LOG2(("kFsCacheLookupSlowA(%ls)\n", pwszPath));
    2765         pFsObj = kFsCacheLookupAbsoluteW(pCache, wszFull, cwcFull, penmError);
     2829        pFsObj = kFsCacheLookupAbsoluteW(pCache, wszFull, cwcFull, penmError, ppLastAncestor);
    27662830
    27672831#if 0 /* No need to do this until it's actually queried. */
     
    27962860static PKFSHASHA kFsCacheRefreshPathA(PKFSCACHE pCache, PKFSHASHA pHashEntry, KU32 idxHashTab)
    27972861{
     2862    PKFSOBJ pLastAncestor = NULL;
    27982863    if (!pHashEntry->pFsObj)
    27992864    {
    28002865        if (pHashEntry->fAbsolute)
    2801             pHashEntry->pFsObj = kFsCacheLookupAbsoluteA(pCache, pHashEntry->pszPath, pHashEntry->cchPath, &pHashEntry->enmError);
     2866            pHashEntry->pFsObj = kFsCacheLookupAbsoluteA(pCache, pHashEntry->pszPath, pHashEntry->cchPath,
     2867                                                         &pHashEntry->enmError, &pLastAncestor);
    28022868        else
    2803             pHashEntry->pFsObj = kFsCacheLookupSlowA(pCache, pHashEntry->pszPath, pHashEntry->cchPath, &pHashEntry->enmError);
     2869            pHashEntry->pFsObj = kFsCacheLookupSlowA(pCache, pHashEntry->pszPath, pHashEntry->cchPath,
     2870                                                     &pHashEntry->enmError, &pLastAncestor);
    28042871    }
    28052872    else
     
    28162883                if (pHashEntry->fAbsolute)
    28172884                    pHashEntry->pFsObj = kFsCacheLookupAbsoluteA(pCache, pHashEntry->pszPath, pHashEntry->cchPath,
    2818                                                                  &pHashEntry->enmError);
     2885                                                                 &pHashEntry->enmError, &pLastAncestor);
    28192886                else
    28202887                    pHashEntry->pFsObj = kFsCacheLookupSlowA(pCache, pHashEntry->pszPath, pHashEntry->cchPath,
    2821                                                              &pHashEntry->enmError);
     2888                                                             &pHashEntry->enmError, &pLastAncestor);
    28222889            }
    28232890        }
     
    28302897        }
    28312898    }
    2832     pHashEntry->uCacheGen = pCache->uGenerationMissing;
     2899
     2900    if (pLastAncestor && !pHashEntry->pFsObj)
     2901        pHashEntry->idxMissingGen = pLastAncestor->fFlags & KFSOBJ_F_USE_CUSTOM_GEN;
     2902    pHashEntry->uCacheGen = !pHashEntry->pFsObj
     2903                          ? pCache->auGenerationsMissing[pHashEntry->idxMissingGen]
     2904                          : pHashEntry->pFsObj->bObjType == KFSOBJ_TYPE_MISSING
     2905                          ? pCache->auGenerationsMissing[pHashEntry->pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     2906                          : pCache->auGenerations[       pHashEntry->pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
     2907    if (pLastAncestor)
     2908        kFsCacheObjRelease(pCache, pLastAncestor);
    28332909    return pHashEntry;
    28342910}
     
    28452921static PKFSHASHW kFsCacheRefreshPathW(PKFSCACHE pCache, PKFSHASHW pHashEntry, KU32 idxHashTab)
    28462922{
     2923    PKFSOBJ pLastAncestor = NULL;
    28472924    if (!pHashEntry->pFsObj)
    28482925    {
    28492926        if (pHashEntry->fAbsolute)
    2850             pHashEntry->pFsObj = kFsCacheLookupAbsoluteW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath, &pHashEntry->enmError);
     2927            pHashEntry->pFsObj = kFsCacheLookupAbsoluteW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath,
     2928                                                         &pHashEntry->enmError, &pLastAncestor);
    28512929        else
    2852             pHashEntry->pFsObj = kFsCacheLookupSlowW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath, &pHashEntry->enmError);
     2930            pHashEntry->pFsObj = kFsCacheLookupSlowW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath,
     2931                                                     &pHashEntry->enmError, &pLastAncestor);
    28532932    }
    28542933    else
     
    28652944                if (pHashEntry->fAbsolute)
    28662945                    pHashEntry->pFsObj = kFsCacheLookupAbsoluteW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath,
    2867                                                                  &pHashEntry->enmError);
     2946                                                                 &pHashEntry->enmError, &pLastAncestor);
    28682947                else
    28692948                    pHashEntry->pFsObj = kFsCacheLookupSlowW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath,
    2870                                                              &pHashEntry->enmError);
     2949                                                             &pHashEntry->enmError, &pLastAncestor);
    28712950            }
    28722951        }
     
    28792958        }
    28802959    }
    2881     pHashEntry->uCacheGen = pCache->uGenerationMissing;
     2960    if (pLastAncestor && !pHashEntry->pFsObj)
     2961        pHashEntry->idxMissingGen = pLastAncestor->fFlags & KFSOBJ_F_USE_CUSTOM_GEN;
     2962    pHashEntry->uCacheGen = !pHashEntry->pFsObj
     2963                          ? pCache->auGenerationsMissing[pHashEntry->idxMissingGen]
     2964                          : pHashEntry->pFsObj->bObjType == KFSOBJ_TYPE_MISSING
     2965                          ? pCache->auGenerationsMissing[pHashEntry->pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     2966                          : pCache->auGenerations[       pHashEntry->pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN];
     2967    if (pLastAncestor)
     2968        kFsCacheObjRelease(pCache, pLastAncestor);
    28822969    return pHashEntry;
    28832970}
     
    29223009                && kHlpMemComp(pHashEntry->pszPath, pchPath, cchPath) == 0)
    29233010            {
     3011                PKFSOBJ pFsObj;
    29243012                if (   pHashEntry->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    2925                     || pHashEntry->uCacheGen == (pHashEntry->pFsObj ? pCache->uGeneration : pCache->uGenerationMissing)
     3013                    || pHashEntry->uCacheGen == (  (pFsObj = pHashEntry->pFsObj) != NULL
     3014                                                 ? pFsObj->bObjType != KFSOBJ_TYPE_MISSING
     3015                                                   ? pCache->auGenerations[       pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     3016                                                   : pCache->auGenerationsMissing[pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     3017                                                 : pCache->auGenerationsMissing[pHashEntry->idxMissingGen])
    29263018                    || (pHashEntry = kFsCacheRefreshPathA(pCache, pHashEntry, idxHashTab)) )
    29273019                {
     
    29483040        PKFSOBJ pFsObj;
    29493041        KBOOL   fAbsolute;
     3042        PKFSOBJ pLastAncestor = NULL;
    29503043
    29513044        /* Is absolute without any '..' bits? */
     
    29583051            && !kFsCacheHasDotDotA(pchPath, cchPath) )
    29593052        {
    2960             pFsObj = kFsCacheLookupAbsoluteA(pCache, pchPath, cchPath, penmError);
     3053            pFsObj = kFsCacheLookupAbsoluteA(pCache, pchPath, cchPath, penmError, &pLastAncestor);
    29613054            fAbsolute = K_TRUE;
    29623055        }
    29633056        else
    29643057        {
    2965             pFsObj = kFsCacheLookupSlowA(pCache, pchPath, cchPath, penmError);
     3058            pFsObj = kFsCacheLookupSlowA(pCache, pchPath, cchPath, penmError, &pLastAncestor);
    29663059            fAbsolute = K_FALSE;
    29673060        }
     
    29703063                && *penmError != KFSLOOKUPERROR_PATH_TOO_LONG)
    29713064            || *penmError == KFSLOOKUPERROR_UNSUPPORTED )
    2972             kFsCacheCreatePathHashTabEntryA(pCache, pFsObj, pchPath, cchPath, uHashPath, idxHashTab, fAbsolute, *penmError);
     3065            kFsCacheCreatePathHashTabEntryA(pCache, pFsObj, pchPath, cchPath, uHashPath, idxHashTab, fAbsolute,
     3066                                            pLastAncestor ? pLastAncestor->bObjType & KFSOBJ_F_USE_CUSTOM_GEN : 0, *penmError);
     3067        if (pLastAncestor)
     3068            kFsCacheObjRelease(pCache, pLastAncestor);
    29733069
    29743070        pCache->cLookups++;
     
    30213117                && kHlpMemComp(pHashEntry->pwszPath, pwcPath, cwcPath) == 0)
    30223118            {
     3119                PKFSOBJ pFsObj;
    30233120                if (   pHashEntry->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
    3024                     || pHashEntry->uCacheGen == (pHashEntry->pFsObj ? pCache->uGeneration : pCache->uGenerationMissing)
     3121                    || pHashEntry->uCacheGen == ((pFsObj = pHashEntry->pFsObj) != NULL
     3122                                                 ? pFsObj->bObjType != KFSOBJ_TYPE_MISSING
     3123                                                   ? pCache->auGenerations[       pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     3124                                                   : pCache->auGenerationsMissing[pFsObj->fFlags & KFSOBJ_F_USE_CUSTOM_GEN]
     3125                                                 : pCache->auGenerationsMissing[pHashEntry->idxMissingGen])
    30253126                    || (pHashEntry = kFsCacheRefreshPathW(pCache, pHashEntry, idxHashTab)) )
    30263127                {
     
    30473148        PKFSOBJ pFsObj;
    30483149        KBOOL   fAbsolute;
     3150        PKFSOBJ pLastAncestor = NULL;
    30493151
    30503152        /* Is absolute without any '..' bits? */
     
    30573159            && !kFsCacheHasDotDotW(pwcPath, cwcPath) )
    30583160        {
    3059             pFsObj = kFsCacheLookupAbsoluteW(pCache, pwcPath, cwcPath, penmError);
     3161            pFsObj = kFsCacheLookupAbsoluteW(pCache, pwcPath, cwcPath, penmError, &pLastAncestor);
    30603162            fAbsolute = K_TRUE;
    30613163        }
    30623164        else
    30633165        {
    3064             pFsObj = kFsCacheLookupSlowW(pCache, pwcPath, cwcPath, penmError);
     3166            pFsObj = kFsCacheLookupSlowW(pCache, pwcPath, cwcPath, penmError, &pLastAncestor);
    30653167            fAbsolute = K_FALSE;
    30663168        }
     
    30693171                && *penmError != KFSLOOKUPERROR_PATH_TOO_LONG)
    30703172            || *penmError == KFSLOOKUPERROR_UNSUPPORTED )
    3071             kFsCacheCreatePathHashTabEntryW(pCache, pFsObj, pwcPath, cwcPath, uHashPath, idxHashTab, fAbsolute, *penmError);
     3173            kFsCacheCreatePathHashTabEntryW(pCache, pFsObj, pwcPath, cwcPath, uHashPath, idxHashTab, fAbsolute,
     3174                                            pLastAncestor ? pLastAncestor->bObjType & KFSOBJ_F_USE_CUSTOM_GEN : 0, *penmError);
     3175        if (pLastAncestor)
     3176            kFsCacheObjRelease(pCache, pLastAncestor);
    30723177
    30733178        pCache->cLookups++;
     
    37393844{
    37403845    kHlpAssert(pCache->u32Magic == KFSOBJ_MAGIC);
    3741     pCache->uGenerationMissing++;
     3846    pCache->auGenerationsMissing[0]++;
    37423847    kHlpAssert(pCache->uGenerationMissing < KU32_MAX);
    3743     KFSCACHE_LOG(("Invalidate missing %#x\n", pCache->uGenerationMissing));
    3744 }
    3745 
    3746 
    3747 /**
    3748  * Invalidate all cache entries of missing files.
     3848    KFSCACHE_LOG(("Invalidate missing %#x\n", pCache->auGenerationsMissing[0]));
     3849}
     3850
     3851
     3852/**
     3853 * Invalidate all cache entries (regular, custom & missing).
    37493854 *
    37503855 * @param   pCache      The cache.
     
    37533858{
    37543859    kHlpAssert(pCache->u32Magic == KFSOBJ_MAGIC);
    3755     pCache->uGenerationMissing++;
    3756     kHlpAssert(pCache->uGenerationMissing < KU32_MAX);
    3757     pCache->uGeneration++;
    3758     kHlpAssert(pCache->uGeneration < KU32_MAX);
    3759     KFSCACHE_LOG(("Invalidate all %#x/%#x\n", pCache->uGenerationMissing, pCache->uGeneration));
    3760 
    3761 }
    3762 
     3860
     3861    pCache->auGenerationsMissing[0]++;
     3862    kHlpAssert(pCache->auGenerationsMissing[0] < KU32_MAX);
     3863    pCache->auGenerationsMissing[1]++;
     3864    kHlpAssert(pCache->auGenerationsMissing[1] < KU32_MAX);
     3865
     3866    pCache->auGenerations[0]++;
     3867    kHlpAssert(pCache->auGenerations[0] < KU32_MAX);
     3868    pCache->auGenerations[1]++;
     3869    kHlpAssert(pCache->auGenerations[1] < KU32_MAX);
     3870
     3871    KFSCACHE_LOG(("Invalidate all - default: %#x/%#x,  custom: %#x/%#x\n",
     3872                  pCache->auGenerationsMissing[0], pCache->auGenerations[0],
     3873                  pCache->auGenerationsMissing[1], pCache->auGenerations[1]));
     3874}
     3875
     3876
     3877/**
     3878 * Invalidate all cache entries with custom generation handling set.
     3879 *
     3880 * @see     kFsCacheSetupCustomRevisionForTree, KFSOBJ_F_USE_CUSTOM_GEN
     3881 * @param   pCache      The cache.
     3882 */
     3883void kFsCacheInvalidateCustomMissing(PKFSCACHE pCache)
     3884{
     3885    kHlpAssert(pCache->u32Magic == KFSOBJ_MAGIC);
     3886    pCache->auGenerationsMissing[1]++;
     3887    kHlpAssert(pCache->auGenerationsMissing[1] < KU32_MAX);
     3888    KFSCACHE_LOG(("Invalidate missing custom %#x\n", pCache->auGenerationsMissing[1]));
     3889}
     3890
     3891
     3892/**
     3893 * Invalidate all cache entries with custom generation handling set, both
     3894 * missing and regular present entries.
     3895 *
     3896 * @see     kFsCacheSetupCustomRevisionForTree, KFSOBJ_F_USE_CUSTOM_GEN
     3897 * @param   pCache      The cache.
     3898 */
     3899void kFsCacheInvalidateCustomBoth(PKFSCACHE pCache)
     3900{
     3901    kHlpAssert(pCache->u32Magic == KFSOBJ_MAGIC);
     3902    pCache->auGenerations[1]++;
     3903    kHlpAssert(pCache->auGenerations[1] < KU32_MAX);
     3904    pCache->auGenerationsMissing[1]++;
     3905    kHlpAssert(pCache->auGenerationsMissing[1] < KU32_MAX);
     3906    KFSCACHE_LOG(("Invalidate both custom %#x/%#x\n", pCache->auGenerationsMissing[1], pCache->auGenerations[1]));
     3907}
     3908
     3909
     3910
     3911/**
     3912 * Applies the given flags to all the objects in a tree.
     3913 *
     3914 * @param   pRoot               Where to start applying the flag changes.
     3915 * @param   fAndMask            The AND mask.
     3916 * @param   fOrMask             The OR mask.
     3917 */
     3918static void kFsCacheApplyFlagsToTree(PKFSDIR pRoot, KU32 fAndMask, KU32 fOrMask)
     3919{
     3920    PKFSOBJ    *ppCur = ((PKFSDIR)pRoot)->papChildren;
     3921    KU32        cLeft = ((PKFSDIR)pRoot)->cChildren;
     3922    while (cLeft-- > 0)
     3923    {
     3924        PKFSOBJ pCur = *ppCur++;
     3925        if (pCur->bObjType != KFSOBJ_TYPE_DIR)
     3926            pCur->fFlags = (fAndMask & pCur->fFlags) | fOrMask;
     3927        else
     3928            kFsCacheApplyFlagsToTree((PKFSDIR)pCur, fAndMask, fOrMask);
     3929    }
     3930
     3931    pRoot->Obj.fFlags = (fAndMask & pRoot->Obj.fFlags) | fOrMask;
     3932}
     3933
     3934
     3935/**
     3936 * Sets up using custom revisioning for the specified directory tree or file.
     3937 *
     3938 * There are some restrictions of the current implementation:
     3939 *      - If the root of the sub-tree is ever deleted from the cache (i.e.
     3940 *        deleted in real life and reflected in the cache), the setting is lost.
     3941 *      - It is not automatically applied to the lookup paths caches.
     3942 *
     3943 * @returns K_TRUE on success, K_FALSE on failure.
     3944 * @param   pCache              The cache.
     3945 * @param   pRoot               The root of the subtree.  A non-directory is
     3946 *                              fine, like a missing node.
     3947 */
     3948KBOOL kFsCacheSetupCustomRevisionForTree(PKFSCACHE pCache, PKFSOBJ pRoot)
     3949{
     3950    if (pRoot)
     3951    {
     3952        if (pRoot->bObjType == KFSOBJ_TYPE_DIR)
     3953            kFsCacheApplyFlagsToTree((PKFSDIR)pRoot, KU32_MAX, KFSOBJ_F_USE_CUSTOM_GEN);
     3954        else
     3955            pRoot->fFlags |= KFSOBJ_F_USE_CUSTOM_GEN;
     3956        return K_TRUE;
     3957    }
     3958    return K_FALSE;
     3959}
    37633960
    37643961
     
    38094006            pCache->u32Magic        = KFSCACHE_MAGIC;
    38104007            pCache->fFlags          = fFlags;
    3811             pCache->uGeneration     = KU32_MAX / 2;
    3812             pCache->uGenerationMissing = 1;
     4008            pCache->auGenerations[0]        = KU32_MAX / 4;
     4009            pCache->auGenerations[1]        = KU32_MAX / 32;
     4010            pCache->auGenerationsMissing[0] = KU32_MAX / 256;
     4011            pCache->auGenerationsMissing[1] = 1;
    38134012            pCache->cObjects        = 1;
    38144013            pCache->cbObjects       = sizeof(pCache->RootDir) + pCache->RootDir.cHashTab * sizeof(pCache->RootDir.paHashTab[0]);
  • trunk/src/lib/nt/kFsCache.h

    r2863 r2868  
    8080/** @name KFSOBJ_F_XXX - KFSOBJ::fFlags
    8181 * @{ */
     82 /** Use custom generation.
     83  * @remarks This is given the value 1, as we use it as an index into
     84  *          KFSCACHE::auGenerations, 0 being the default. */
     85#define KFSOBJ_F_USE_CUSTOM_GEN         KU32_C(0x00000001)
     86
    8287/** Whether the file system update the modified timestamp of directories
    8388 * when something is removed from it or added to it.
    8489 * @remarks They say NTFS is the only windows filesystem doing this.  */
    85 #define KFSOBJ_F_WORKING_DIR_MTIME      KU32_C(0x00000001)
     90#define KFSOBJ_F_WORKING_DIR_MTIME      KU32_C(0x00000002)
    8691/** NTFS file system volume. */
    8792#define KFSOBJ_F_NTFS                   KU32_C(0x80000000)
     93/** Flags that are automatically inherited. */
     94#define KFSOBJ_F_INHERITED_MASK         KU32_C(0xffffffff)
    8895/** @} */
    8996
     
    304311    /** Set if aboslute path.   */
    305312    KBOOL               fAbsolute;
     313    /** Index into KFSCACHE:auGenerationsMissing when pFsObj is NULL. */
     314    KU8                 idxMissingGen;
    306315    /** The cache generation ID. */
    307316    KU32                uCacheGen;
     
    333342    /** Set if aboslute path.   */
    334343    KBOOL               fAbsolute;
     344    /** Index into KFSCACHE:auGenerationsMissing when pFsObj is NULL. */
     345    KU8                 idxMissingGen;
    335346    /** The cache generation ID. */
    336347    KU32                uCacheGen;
     
    365376    KU32                fFlags;
    366377
    367     /** The current cache generation for objects that already exists. */
    368     KU32                uGeneration;
    369     /** The current cache generation for missing objects, negative results, ++. */
    370     KU32                uGenerationMissing;
     378    /** The default and custom cache generations for stuff that exists, indexed by
     379     *  KFSOBJ_F_USE_CUSTOM_GEN.
     380     *
     381     * The custom generation can be used to invalidate parts of the file system that
     382     * are known to be volatile without triggering refreshing of the more static
     383     * parts.  Like the 'out' directory in a kBuild setup or a 'TEMP' directory are
     384     * expected to change and you need to invalidate the caching of these frequently
     385     * to stay on top of things.  Whereas the sources, headers, compilers, sdk,
     386     * ddks, windows directory and such generally doesn't change all that often.
     387     */
     388    KU32                auGenerations[2];
     389    /** The current cache generation for missing objects, negative results, ++.
     390     * This comes with a custom variant too.  Indexed by KFSOBJ_F_USE_CUSTOM_GEN. */
     391    KU32                auGenerationsMissing[2];
    371392
    372393    /** Number of cache objects. */
     
    437458PKFSOBJ     kFsCacheLookupW(PKFSCACHE pCache, const wchar_t *pwszPath, KFSLOOKUPERROR *penmError);
    438459PKFSOBJ     kFsCacheLookupRelativeToDirA(PKFSCACHE pCache, PKFSDIR pParent, const char *pszPath, KU32 cchPath,
    439                                          KFSLOOKUPERROR *penmError);
     460                                         KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor);
    440461PKFSOBJ     kFsCacheLookupRelativeToDirW(PKFSCACHE pCache, PKFSDIR pParent, const wchar_t *pwszPath, KU32 cwcPath,
    441                                          KFSLOOKUPERROR *penmError);
     462                                         KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor);
    442463PKFSOBJ     kFsCacheLookupWithLengthA(PKFSCACHE pCache, const char *pchPath, KSIZE cchPath, KFSLOOKUPERROR *penmError);
    443464PKFSOBJ     kFsCacheLookupWithLengthW(PKFSCACHE pCache, const wchar_t *pwcPath, KSIZE cwcPath, KFSLOOKUPERROR *penmError);
     
    459480PKFSCACHE   kFsCacheCreate(KU32 fFlags);
    460481void        kFsCacheDestroy(PKFSCACHE);
    461 void        kFsCacheInvalidateMissing(PKFSCACHE pFsCache);
    462 void        kFsCacheInvalidateAll(PKFSCACHE pFsCache);
    463 
    464 #endif
     482void        kFsCacheInvalidateMissing(PKFSCACHE pCache);
     483void        kFsCacheInvalidateAll(PKFSCACHE pCache);
     484void        kFsCacheInvalidateCustomMissing(PKFSCACHE pCache);
     485void        kFsCacheInvalidateCustomBoth(PKFSCACHE pCache);
     486KBOOL       kFsCacheSetupCustomRevisionForTree(PKFSCACHE pCache, PKFSOBJ pRoot);
     487
     488#endif
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette