Changeset 2862


Ignore:
Timestamp:
Sep 2, 2016, 4:39:56 AM (9 years ago)
Author:
bird
Message:

updates

Location:
trunk/src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/dir-nt-bird.c

    r2861 r2862  
    504504void dir_cache_invalid_missing(void)
    505505{
    506     kFsCacheInvalidateMissing(g_pFsCache);
    507 }
    508 
     506    kFsCacheInvalidateAll(g_pFsCache);
     507}
     508
  • trunk/src/kmk/job.c

    r2861 r2862  
    686686              if (job_counter)
    687687                --job_counter;
    688 
    689 # if defined(KMK) && defined(KBUILD_OS_WINDOWS)
    690               /* Invalidate negative directory cache entries now that a
    691                  job has completed and possibly created new files that
    692                  was missing earlier. */
    693               extern void dir_cache_invalid_missing(void);
    694               dir_cache_invalid_missing ();
    695 # endif
    696688            }
    697689          else
  • trunk/src/kmk/w32/subproc/sub_proc.c

    r2846 r2862  
    269269                 */
    270270#ifdef KMK
     271                /* Invalidate negative directory cache entries now that a
     272                   job has completed and possibly created new files that
     273                   was missing earlier. */
     274                extern void dir_cache_invalid_missing(void);
     275                dir_cache_invalid_missing();
     276
    271277                if (pproc->enmType == kRegular) {
    272278                    (void)process_file_io_private(pproc, FALSE);
  • trunk/src/lib/nt/kFsCache.c

    r2861 r2862  
    5151#include "kFsCache.h"
    5252
     53
     54/*********************************************************************************************************************************
     55*   Defined Constants And Macros                                                                                                 *
     56*********************************************************************************************************************************/
     57/** @def KFSCACHE_LOG2
     58 * More logging. */
     59#if 0
     60# define KFSCACHE_LOG2(a) KFSCACHE_LOG(a)
     61#else
     62# define KFSCACHE_LOG2(a) do { } while (0)
     63#endif
    5364
    5465
     
    218229}
    219230
    220 #if 0
    221 
    222 /**
    223  * Converts the given string to unicode.
    224  *
    225  * @returns Length of the resulting string in wchar_t's.
    226  * @param   pszSrc              The source string.
    227  * @param   pwszDst             The destination buffer.
    228  * @param   cwcDst              The size of the destination buffer in wchar_t's.
    229  */
    230 static KSIZE kwStrToUtf16(const char *pszSrc, wchar_t *pwszDst, KSIZE cwcDst)
    231 {
    232     /* Just to the quick ASCII stuff for now. correct ansi code page stuff later some time.  */
    233     KSIZE offDst = 0;
    234     while (offDst < cwcDst)
    235     {
    236         char ch = *pszSrc++;
    237         pwszDst[offDst++] = ch;
    238         if (!ch)
    239             return offDst - 1;
    240         kHlpAssert((unsigned)ch < 127);
    241     }
    242 
    243     pwszDst[offDst - 1] = '\0';
    244     return offDst;
    245 }
    246 
    247 
    248 /**
    249  * Converts the given UTF-16 to a normal string.
    250  *
    251  * @returns Length of the resulting string.
    252  * @param   pwszSrc             The source UTF-16 string.
    253  * @param   pszDst              The destination buffer.
    254  * @param   cbDst               The size of the destination buffer in bytes.
    255  */
    256 static KSIZE kwUtf16ToStr(const wchar_t *pwszSrc, char *pszDst, KSIZE cbDst)
    257 {
    258     /* Just to the quick ASCII stuff for now. correct ansi code page stuff later some time.  */
    259     KSIZE offDst = 0;
    260     while (offDst < cbDst)
    261     {
    262         wchar_t wc = *pwszSrc++;
    263         pszDst[offDst++] = (char)wc;
    264         if (!wc)
    265             return offDst - 1;
    266         kHlpAssert((unsigned)wc < 127);
    267     }
    268 
    269     pszDst[offDst - 1] = '\0';
    270     return offDst;
    271 }
    272 
    273 
    274 
    275 /** UTF-16 string length.  */
    276 static KSIZE kwUtf16Len(wchar_t const *pwsz)
    277 {
    278     KSIZE cwc = 0;
    279     while (*pwsz != '\0')
    280         cwc++, pwsz++;
    281     return cwc;
    282 }
    283 
    284 /**
    285  * Copy out the UTF-16 string following the convension of GetModuleFileName
    286  */
    287 static DWORD kwUtf16CopyStyle1(wchar_t const *pwszSrc, wchar_t *pwszDst, KSIZE cwcDst)
    288 {
    289     KSIZE cwcSrc = kwUtf16Len(pwszSrc);
    290     if (cwcSrc + 1 <= cwcDst)
    291     {
    292         kHlpMemCopy(pwszDst, pwszSrc, (cwcSrc + 1) * sizeof(wchar_t));
    293         return (DWORD)cwcSrc;
    294     }
    295     if (cwcDst > 0)
    296     {
    297         KSIZE cwcDstTmp = cwcDst - 1;
    298         pwszDst[cwcDstTmp] = '\0';
    299         if (cwcDstTmp > 0)
    300             kHlpMemCopy(pwszDst, pwszSrc, cwcDstTmp);
    301     }
    302     SetLastError(ERROR_INSUFFICIENT_BUFFER);
    303     return (DWORD)cwcDst;
    304 }
    305 
    306 
    307 /**
    308  * Copy out the ANSI string following the convension of GetModuleFileName
    309  */
    310 static DWORD kwStrCopyStyle1(char const *pszSrc, char *pszDst, KSIZE cbDst)
    311 {
    312     KSIZE cchSrc = kHlpStrLen(pszSrc);
    313     if (cchSrc + 1 <= cbDst)
    314     {
    315         kHlpMemCopy(pszDst, pszSrc, cchSrc + 1);
    316         return (DWORD)cchSrc;
    317     }
    318     if (cbDst > 0)
    319     {
    320         KSIZE cbDstTmp = cbDst - 1;
    321         pszDst[cbDstTmp] = '\0';
    322         if (cbDstTmp > 0)
    323             kHlpMemCopy(pszDst, pszSrc, cbDstTmp);
    324     }
    325     SetLastError(ERROR_INSUFFICIENT_BUFFER);
    326     return (DWORD)cbDst;
    327 }
    328 
    329 
    330 /**
    331  * Normalizes the path so we get a consistent hash.
    332  *
    333  * @returns status code.
    334  * @param   pszPath             The path.
    335  * @param   pszNormPath         The output buffer.
    336  * @param   cbNormPath          The size of the output buffer.
    337  */
    338 static int kwPathNormalize(const char *pszPath, char *pszNormPath, KSIZE cbNormPath)
    339 {
    340     char           *pchSlash;
    341     KSIZE           cchNormPath;
    342 
    343     /*
    344      * We hash these to speed stuff up (nt_fullpath isn't cheap and we're
    345      * gonna have many repeat queries and assume nobody do case changes to
    346      * anything essential while kmk is running).
    347      */
    348     KU32            uHashPath;
    349     KU32            cchPath    = (KU32)kFsCacheStrHashEx(pszPath, &uHashPath);
    350     KU32 const      idxHashTab = uHashPath % K_ELEMENTS(g_apFsNormalizedPathsA);
    351     PKFSNORMHASHA  pHashEntry = g_apFsNormalizedPathsA[idxHashTab];
    352     if (pHashEntry)
    353     {
    354         do
    355         {
    356             if (   pHashEntry->uHashPath == uHashPath
    357                 && pHashEntry->cchPath   == cchPath
    358                 && kHlpMemComp(pHashEntry->pszPath, pszPath, cchPath) == 0)
    359             {
    360                 if (cbNormPath > pHashEntry->cchNormPath)
    361                 {
    362                     KFSCACHE_LOG(("kwPathNormalize(%s) - hit\n", pszPath));
    363                     kHlpMemCopy(pszNormPath, pHashEntry->szNormPath, pHashEntry->cchNormPath + 1);
    364                     return 0;
    365                 }
    366                 return KERR_BUFFER_OVERFLOW;
    367             }
    368             pHashEntry = pHashEntry->pNext;
    369         } while (pHashEntry);
    370     }
    371 
    372     /*
    373      * Do it the slow way.
    374      */
    375     nt_fullpath(pszPath, pszNormPath, cbNormPath);
    376     /** @todo nt_fullpath overflow handling?!?!?   */
    377 
    378     pchSlash = kHlpStrChr(pszNormPath, '/');
    379     while (pchSlash)
    380     {
    381         *pchSlash = '\\';
    382         pchSlash = kHlpStrChr(pchSlash + 1, '/');
    383     }
    384 
    385     /*
    386      * Create a new hash table entry (ignore failures).
    387      */
    388     cchNormPath = kHlpStrLen(pszNormPath);
    389     if (cchNormPath < KU16_MAX && cchPath < KU16_MAX)
    390     {
    391         pHashEntry = (PKFSNORMHASHA)kHlpAlloc(sizeof(*pHashEntry) + cchNormPath + 1 + cchPath + 1);
    392         if (pHashEntry)
    393         {
    394             pHashEntry->cchNormPath = (KU16)cchNormPath;
    395             pHashEntry->cchPath     = (KU16)cchPath;
    396             pHashEntry->uHashPath   = uHashPath;
    397             pHashEntry->pszPath     = (char *)kHlpMemCopy(&pHashEntry->szNormPath[cchNormPath + 1], pszPath, cchPath + 1);
    398             kHlpMemCopy(pHashEntry->szNormPath, pszNormPath, cchNormPath + 1);
    399 
    400             pHashEntry->pNext = g_apFsNormalizedPathsA[idxHashTab];
    401             g_apFsNormalizedPathsA[idxHashTab] = pHashEntry;
    402         }
    403     }
    404 
    405     return 0;
    406 }
    407 
    408 
    409 /**
    410  * Get the pointer to the filename part of the path.
    411  *
    412  * @returns Pointer to where the filename starts within the string pointed to by pszFilename.
    413  * @returns Pointer to the terminator char if no filename.
    414  * @param   pszPath     The path to parse.
    415  */
    416 static wchar_t *kwPathGetFilenameW(const wchar_t *pwszPath)
    417 {
    418     const wchar_t *pwszLast = NULL;
    419     for (;;)
    420     {
    421         wchar_t wc = *pwszPath;
    422 #if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS
    423         if (wc == '/' || wc == '\\' || wc == ':')
    424         {
    425             while ((wc = *++pwszPath) == '/' || wc == '\\' || wc == ':')
    426                 /* nothing */;
    427             pwszLast = pwszPath;
    428         }
    429 #else
    430         if (wc == '/')
    431         {
    432             while ((wc = *++pszFilename) == '/')
    433                 /* betsuni */;
    434             pwszLast = pwszPath;
    435         }
    436 #endif
    437         if (!wc)
    438             return (wchar_t *)(pwszLast ? pwszLast : pwszPath);
    439         pwszPath++;
    440     }
    441 }
    442 
    443 
    444 /**
    445  * Check if the path leads to a regular file (that exists).
    446  *
    447  * @returns K_TRUE / K_FALSE
    448  * @param   pszPath             Path to the file to check out.
    449  */
    450 static KBOOL kwLdrModuleIsRegularFile(const char *pszPath)
    451 {
    452     /* For stuff with .DLL extensions, we can use the GetFileAttribute cache to speed this up! */
    453     KSIZE cchPath = kHlpStrLen(pszPath);
    454     if (   cchPath > 3
    455         && pszPath[cchPath - 4] == '.'
    456         && (pszPath[cchPath - 3] == 'd' || pszPath[cchPath - 3] == 'D')
    457         && (pszPath[cchPath - 2] == 'l' || pszPath[cchPath - 2] == 'L')
    458         && (pszPath[cchPath - 1] == 'l' || pszPath[cchPath - 1] == 'L') )
    459     {
    460         PKFSOBJ pFsObj = kFsCacheLookupA(pszPath);
    461         if (pFsObj)
    462         {
    463             if (!(pFsObj->fAttribs & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE))) /* also checks invalid */
    464                 return K_TRUE;
    465         }
    466     }
    467     else
    468     {
    469         BirdStat_T Stat;
    470         int rc = birdStatFollowLink(pszPath, &Stat);
    471         if (rc == 0)
    472         {
    473             if (S_ISREG(Stat.st_mode))
    474                 return K_TRUE;
    475         }
    476     }
    477     return K_FALSE;
    478 }
    479 
    480 
    481 
    482 
    483 
    484 
    485 /**
    486  * Helper for getting the extension of a UTF-16 path.
    487  *
    488  * @returns Pointer to the extension or the terminator.
    489  * @param   pwszPath        The path.
    490  * @param   pcwcExt         Where to return the length of the extension.
    491  */
    492 static wchar_t const *kwFsPathGetExtW(wchar_t const *pwszPath, KSIZE *pcwcExt)
    493 {
    494     wchar_t const *pwszName = pwszPath;
    495     wchar_t const *pwszExt  = NULL;
    496     for (;;)
    497     {
    498         wchar_t const wc = *pwszPath++;
    499         if (wc == '.')
    500             pwszExt = pwszPath;
    501         else if (wc == '/' || wc == '\\' || wc == ':')
    502         {
    503             pwszName = pwszPath;
    504             pwszExt = NULL;
    505         }
    506         else if (wc == '\0')
    507         {
    508             if (pwszExt)
    509             {
    510                 *pcwcExt = pwszPath - pwszExt - 1;
    511                 return pwszExt;
    512             }
    513             *pcwcExt = 0;
    514             return pwszPath - 1;
    515         }
    516     }
    517 }
    518 #endif
    519 
    520231
    521232/**
     
    1058769        fRefreshing = K_TRUE;
    1059770    }
    1060 
     771    if (!fRefreshing)
     772        KFSCACHE_LOG(("Populating %s...\n", pDir->Obj.pszName));
     773    else
     774        KFSCACHE_LOG(("Refreshing %s...\n", pDir->Obj.pszName));
    1061775
    1062776    /*
     
    1280994            return BasicInfo.LastWriteTime.QuadPart != pDir->iLastWrite;
    1281995    }
     996    /* The cache root never changes. */
     997    else if (!pDir->Obj.pParent)
     998        return K_FALSE;
    1282999
    12831000    return K_TRUE;
     
    12931010     */
    12941011    if (!kFsCacheDirIsModified(pMissing->pParent))
     1012    {
     1013        KFSCACHE_LOG(("Parent of missing not written to %s/%s\n", pMissing->pParent->Obj.pszName, pMissing->pszName));
    12951014        pMissing->uCacheGen = pCache->uGenerationMissing;
     1015    }
    12961016    else
    12971017    {
     
    13151035             */
    13161036            pMissing->uCacheGen = pCache->uGenerationMissing;
     1037            KFSCACHE_LOG(("Still missing %s/%s\n", pMissing->pParent->Obj.pszName, pMissing->pszName));
    13171038        }
    13181039        else
     
    13231044             * just as well update the parent directory...
    13241045             */
     1046            KFSCACHE_LOG(("Birth of %s/%s with attribs %#x...\n",
     1047                          pMissing->pParent->Obj.pszName, pMissing->pszName, BasicInfo.FileAttributes));
    13251048            /** @todo   */
    13261049            __debugbreak();
     
    13481071static KBOOL kFsCacheRefreshObj(PKFSCACHE pCache, PKFSOBJ pObj, KFSLOOKUPERROR *penmError)
    13491072{
     1073    KBOOL fRc;
     1074
     1075    /*
     1076     * Since we generally assume nothing goes away in this cache, we only really
     1077     * have a hard time with negative entries.  So, missing stuff goes to
     1078     * complicated land.
     1079     */
    13501080    if (pObj->bObjType == KFSOBJ_TYPE_MISSING)
    1351         return kFsCacheRefreshMissing(pCache, pObj, penmError);
    1352 
    1353     __debugbreak();
    1354     return K_FALSE;
     1081        fRc = kFsCacheRefreshMissing(pCache, pObj, penmError);
     1082    else
     1083    {
     1084        /*
     1085         * This object is supposed to exist, so all we need to do is query essential
     1086         * stats again.  Since we've already got handles on directories, there are
     1087         * two ways to go about this.
     1088         */
     1089        union
     1090        {
     1091            MY_FILE_NETWORK_OPEN_INFORMATION    FullInfo;
     1092            MY_FILE_STANDARD_INFORMATION        StdInfo;
     1093#ifdef KFSCACHE_CFG_SHORT_NAMES
     1094            MY_FILE_ID_BOTH_DIR_INFORMATION     WithId;
     1095            //MY_FILE_BOTH_DIR_INFORMATION        NoId;
     1096#else
     1097            MY_FILE_ID_FULL_DIR_INFORMATION     WithId;
     1098            //MY_FILE_FULL_DIR_INFORMATION        NoId;
     1099#endif
     1100            KU8                                 abPadding[  sizeof(wchar_t) * KFSCACHE_CFG_MAX_UTF16_NAME
     1101                                                          + sizeof(MY_FILE_ID_BOTH_DIR_INFORMATION)];
     1102        } uBuf;
     1103        MY_IO_STATUS_BLOCK                      Ios;
     1104        MY_NTSTATUS                             rcNt;
     1105        if (   pObj->bObjType != KFSOBJ_TYPE_DIR
     1106            || ((PKFSDIR)pObj)->hDir == INVALID_HANDLE_VALUE)
     1107        {
     1108#if 0 /** @todo performance check these two alternatives. */
     1109            MY_UNICODE_STRING    UniStr;
     1110            MY_OBJECT_ATTRIBUTES ObjAttr;
     1111
     1112            UniStr.Buffer        = (wchar_t *)pObj->pwszName;
     1113            UniStr.Length        = (USHORT)(pObj->cwcName * sizeof(wchar_t));
     1114            UniStr.MaximumLength = UniStr.Length + sizeof(wchar_t);
     1115
     1116            kHlpAssert(pObj->pParent->hDir != INVALID_HANDLE_VALUE);
     1117            MyInitializeObjectAttributes(&ObjAttr, &UniStr, OBJ_CASE_INSENSITIVE, pObj->pParent->hDir, NULL /*pSecAttr*/);
     1118
     1119            rcNt = g_pfnNtQueryFullAttributesFile(&ObjAttr, &uBuf.FullInfo);
     1120            if (MY_NT_SUCCESS(rcNt))
     1121            {
     1122                pObj->Stats.st_size          = uBuf.FullInfo.EndOfFile.QuadPart;
     1123                birdNtTimeToTimeSpec(uBuf.FullInfo.CreationTime.QuadPart,   &pObj->Stats.st_birthtim);
     1124                birdNtTimeToTimeSpec(uBuf.FullInfo.ChangeTime.QuadPart,     &pObj->Stats.st_ctim);
     1125                birdNtTimeToTimeSpec(uBuf.FullInfo.LastWriteTime.QuadPart,  &pObj->Stats.st_mtim);
     1126                birdNtTimeToTimeSpec(uBuf.FullInfo.LastAccessTime.QuadPart, &pObj->Stats.st_atim);
     1127                pObj->Stats.st_attribs       = uBuf.FullInfo.FileAttributes;
     1128                pObj->Stats.st_blksize       = 65536;
     1129                pObj->Stats.st_blocks        = (uBuf.FullInfo.AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1)
     1130                                             / BIRD_STAT_BLOCK_SIZE;
     1131            }
     1132#else
     1133            /* This alternative lets us keep the inode number up to date. */
     1134            MY_UNICODE_STRING    UniStr;
     1135# ifdef KFSCACHE_CFG_SHORT_NAMES
     1136            MY_FILE_INFORMATION_CLASS enmInfoClass = MyFileIdBothDirectoryInformation;
     1137# else
     1138            MY_FILE_INFORMATION_CLASS enmInfoClass = MyFileIdFullDirectoryInformation;
     1139# endif
     1140
     1141            UniStr.Buffer        = (wchar_t *)pObj->pwszName;
     1142            UniStr.Length        = (USHORT)(pObj->cwcName * sizeof(wchar_t));
     1143            UniStr.MaximumLength = UniStr.Length + sizeof(wchar_t);
     1144
     1145            kHlpAssert(pObj->pParent->hDir != INVALID_HANDLE_VALUE);
     1146
     1147            Ios.Information = -1;
     1148            Ios.u.Status    = -1;
     1149            rcNt = g_pfnNtQueryDirectoryFile(pObj->pParent->hDir,
     1150                                             NULL,      /* hEvent */
     1151                                             NULL,      /* pfnApcComplete */
     1152                                             NULL,      /* pvApcCompleteCtx */
     1153                                             &Ios,
     1154                                             &uBuf,
     1155                                             sizeof(uBuf),
     1156                                             enmInfoClass,
     1157                                             TRUE,      /* fReturnSingleEntry */
     1158                                             &UniStr,   /* Filter / restart pos. */
     1159                                             TRUE);     /* fRestartScan */
     1160
     1161            if (MY_NT_SUCCESS(rcNt))
     1162            {
     1163                if (pObj->Stats.st_ino == uBuf.WithId.FileId.QuadPart)
     1164                    KFSCACHE_LOG(("Refreshing %s/%s, no ID change...\n", pObj->pParent->Obj.pszName, pObj->pszName));
     1165                else if (   pObj->cwcName == uBuf.WithId.FileNameLength / sizeof(wchar_t)
     1166# ifdef KFSCACHE_CFG_SHORT_NAMES
     1167                         && (  uBuf.WithId.ShortNameLength == 0
     1168                             ?    pObj->pwszName == pObj->pwszShortName
     1169                               || (   pObj->cwcName == pObj->cwcShortName
     1170                                   && memcmp(pObj->pwszName, pObj->pwszShortName, pObj->cwcName * sizeof(wchar_t)) == 0)
     1171                             : pObj->cwcShortName == uBuf.WithId.ShortNameLength / sizeof(wchar_t)
     1172                               && memcmp(pObj->pwszShortName, uBuf.WithId.ShortName, uBuf.WithId.ShortNameLength) == 0
     1173                            )
     1174# endif
     1175                         && memcmp(pObj->pwszName, uBuf.WithId.FileName, uBuf.WithId.FileNameLength) == 0
     1176                         )
     1177                {
     1178                    KFSCACHE_LOG(("Refreshing %s/%s, ID changed %#llx -> %#llx...\n",
     1179                                  pObj->pParent->Obj.pszName, pObj->pszName, pObj->Stats.st_ino, uBuf.WithId.FileId.QuadPart));
     1180                    pObj->Stats.st_ino = uBuf.WithId.FileId.QuadPart;
     1181                }
     1182                else
     1183                {
     1184                    KFSCACHE_LOG(("Refreshing %s/%s, ID changed %#llx -> %#llx and names too...\n",
     1185                                  pObj->pParent->Obj.pszName, pObj->pszName, pObj->Stats.st_ino, uBuf.WithId.FileId.QuadPart));
     1186                    __debugbreak();
     1187                    pObj->Stats.st_ino = uBuf.WithId.FileId.QuadPart;
     1188                    /** @todo implement as needed.   */
     1189                }
     1190
     1191                pObj->Stats.st_size          = uBuf.WithId.EndOfFile.QuadPart;
     1192                birdNtTimeToTimeSpec(uBuf.WithId.CreationTime.QuadPart,   &pObj->Stats.st_birthtim);
     1193                birdNtTimeToTimeSpec(uBuf.WithId.ChangeTime.QuadPart,     &pObj->Stats.st_ctim);
     1194                birdNtTimeToTimeSpec(uBuf.WithId.LastWriteTime.QuadPart,  &pObj->Stats.st_mtim);
     1195                birdNtTimeToTimeSpec(uBuf.WithId.LastAccessTime.QuadPart, &pObj->Stats.st_atim);
     1196                pObj->Stats.st_attribs       = uBuf.WithId.FileAttributes;
     1197                pObj->Stats.st_blksize       = 65536;
     1198                pObj->Stats.st_blocks        = (uBuf.WithId.AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1)
     1199                                             / BIRD_STAT_BLOCK_SIZE;
     1200            }
     1201#endif
     1202        }
     1203        else
     1204        {
     1205            /*
     1206             * An open directory.  Query information via the handle, the
     1207             * file ID shouldn't have been able to change, so we can use
     1208             * NtQueryInformationFile.  Right...
     1209             */
     1210            PKFSDIR pDir = (PKFSDIR)pObj;
     1211            Ios.Information = -1;
     1212            Ios.u.Status    = -1;
     1213            rcNt = g_pfnNtQueryInformationFile(pDir->hDir, &Ios, &uBuf.FullInfo, sizeof(uBuf.FullInfo),
     1214                                               MyFileNetworkOpenInformation);
     1215            if (MY_NT_SUCCESS(rcNt))
     1216                rcNt = Ios.u.Status;
     1217            if (MY_NT_SUCCESS(rcNt))
     1218            {
     1219                pObj->Stats.st_size          = uBuf.FullInfo.EndOfFile.QuadPart;
     1220                birdNtTimeToTimeSpec(uBuf.FullInfo.CreationTime.QuadPart,   &pObj->Stats.st_birthtim);
     1221                birdNtTimeToTimeSpec(uBuf.FullInfo.ChangeTime.QuadPart,     &pObj->Stats.st_ctim);
     1222                birdNtTimeToTimeSpec(uBuf.FullInfo.LastWriteTime.QuadPart,  &pObj->Stats.st_mtim);
     1223                birdNtTimeToTimeSpec(uBuf.FullInfo.LastAccessTime.QuadPart, &pObj->Stats.st_atim);
     1224                pObj->Stats.st_attribs       = uBuf.FullInfo.FileAttributes;
     1225                pObj->Stats.st_blksize       = 65536;
     1226                pObj->Stats.st_blocks        = (uBuf.FullInfo.AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1)
     1227                                             / BIRD_STAT_BLOCK_SIZE;
     1228
     1229                if (   pDir->iLastWrite -= uBuf.FullInfo.LastWriteTime.QuadPart
     1230                    && (pObj->fFlags & KFSOBJ_F_WORKING_DIR_MTIME) )
     1231                    KFSCACHE_LOG(("Refreshing %s/%s/ - no re-populating necessary.\n",
     1232                                  pObj->pParent->Obj.pszName, pObj->pszName));
     1233                else
     1234                {
     1235                    KFSCACHE_LOG(("Refreshing %s/%s/ - needs re-populating...\n",
     1236                                  pObj->pParent->Obj.pszName, pObj->pszName));
     1237                    pDir->fNeedRePopulating = K_TRUE;
     1238#if 0
     1239                    /* Refresh the link count. */
     1240                    rcNt = g_pfnNtQueryInformationFile(pDir->hDir, &Ios, &StdInfo, sizeof(StdInfo), FileStandardInformation);
     1241                    if (MY_NT_SUCCESS(rcNt))
     1242                        rcNt = Ios.s.Status;
     1243                    if (MY_NT_SUCCESS(rcNt))
     1244                        pObj->Stats.st_nlink = StdInfo.NumberOfLinks;
     1245#endif
     1246                }
     1247            }
     1248
     1249        }
     1250        if (MY_NT_SUCCESS(rcNt))
     1251        {
     1252            pObj->uCacheGen = pCache->uGeneration;
     1253            fRc = K_TRUE;
     1254        }
     1255        else
     1256        {
     1257            /* ouch! */
     1258            kHlpAssertMsgFailed(("%#x\n", rcNt));
     1259            __debugbreak();
     1260            fRc = K_FALSE;
     1261        }
     1262    }
     1263
     1264    return fRc;
    13551265}
    13561266
     
    20711981    KU32        offEnd;
    20721982
    2073     KFSCACHE_LOG(("kFsCacheLookupAbsoluteA(%s)\n", pszPath));
     1983    KFSCACHE_LOG2(("kFsCacheLookupAbsoluteA(%s)\n", pszPath));
    20741984
    20751985    /*
     
    21602070    KU32        offEnd;
    21612071
    2162     KFSCACHE_LOG(("kFsCacheLookupAbsoluteW(%ls)\n", pwszPath));
     2072    KFSCACHE_LOG2(("kFsCacheLookupAbsoluteW(%ls)\n", pwszPath));
    21632073
    21642074    /*
     
    22522162    {
    22532163        PKFSOBJ pFsObj;
    2254         KFSCACHE_LOG(("kFsCacheLookupSlowA(%s)\n", pszPath));
     2164        KFSCACHE_LOG2(("kFsCacheLookupSlowA(%s)\n", pszPath));
    22552165        pFsObj = kFsCacheLookupAbsoluteA(pCache, szFull, cchFull, penmError);
    22562166
     
    23012211    {
    23022212        PKFSOBJ pFsObj;
    2303         KFSCACHE_LOG(("kFsCacheLookupSlowA(%ls)\n", pwszPath));
     2213        KFSCACHE_LOG2(("kFsCacheLookupSlowA(%ls)\n", pwszPath));
    23042214        pFsObj = kFsCacheLookupAbsoluteW(pCache, wszFull, cwcFull, penmError);
    23052215
     
    23442254    else
    23452255    {
    2346         KFSLOOKUPERROR enmError;
     2256        KU8             bOldType = pHashEntry->pFsObj->bObjType;
     2257        KFSLOOKUPERROR  enmError;
    23472258        if (kFsCacheRefreshObj(pCache, pHashEntry->pFsObj, &enmError))
    23482259        {
    2349         }
    2350         __debugbreak();  /** @todo implement once we've start inserting uCacheGen nodes. */
    2351         K_NOREF(pCache);
    2352         K_NOREF(idxHashTab);
     2260            if (pHashEntry->pFsObj->bObjType == bOldType)
     2261            { }
     2262            else
     2263            {
     2264                kFsCacheObjRelease(pCache, pHashEntry->pFsObj);
     2265                if (pHashEntry->fAbsolute)
     2266                    pHashEntry->pFsObj = kFsCacheLookupAbsoluteA(pCache, pHashEntry->pszPath, pHashEntry->cchPath,
     2267                                                                 &pHashEntry->enmError);
     2268                else
     2269                    pHashEntry->pFsObj = kFsCacheLookupSlowA(pCache, pHashEntry->pszPath, pHashEntry->cchPath,
     2270                                                             &pHashEntry->enmError);
     2271            }
     2272        }
     2273        else
     2274        {
     2275            __debugbreak();
     2276            /** @todo just remove this entry.   */
     2277            return NULL;
     2278        }
    23532279    }
    23542280    pHashEntry->uCacheGen = pCache->uGenerationMissing;
     
    23762302    else
    23772303    {
    2378         KFSLOOKUPERROR enmError;
     2304        KU8             bOldType = pHashEntry->pFsObj->bObjType;
     2305        KFSLOOKUPERROR  enmError;
    23792306        if (kFsCacheRefreshObj(pCache, pHashEntry->pFsObj, &enmError))
    23802307        {
    2381         }
    2382         __debugbreak();  /** @todo implement once we've start inserting uCacheGen nodes. */
    2383         K_NOREF(pCache);
    2384         K_NOREF(idxHashTab);
    2385     }
     2308            if (pHashEntry->pFsObj->bObjType == bOldType)
     2309            { }
     2310            else
     2311            {
     2312                kFsCacheObjRelease(pCache, pHashEntry->pFsObj);
     2313                if (pHashEntry->fAbsolute)
     2314                    pHashEntry->pFsObj = kFsCacheLookupAbsoluteW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath,
     2315                                                                 &pHashEntry->enmError);
     2316                else
     2317                    pHashEntry->pFsObj = kFsCacheLookupSlowW(pCache, pHashEntry->pwszPath, pHashEntry->cwcPath,
     2318                                                             &pHashEntry->enmError);
     2319            }
     2320        }
     2321        else
     2322        {
     2323            __debugbreak();
     2324            /** @todo just remove this entry.   */
     2325            return NULL;
     2326        }
     2327    }
     2328    pHashEntry->uCacheGen = pCache->uGenerationMissing;
    23862329    return pHashEntry;
    23872330}
     
    24322375                    pCache->cLookups++;
    24332376                    pCache->cPathHashHits++;
    2434                     KFSCACHE_LOG(("kFsCacheLookupA(%*.*s) - hit %p\n", cchPath, cchPath, pchPath, pHashEntry->pFsObj));
     2377                    KFSCACHE_LOG2(("kFsCacheLookupA(%*.*s) - hit %p\n", cchPath, cchPath, pchPath, pHashEntry->pFsObj));
    24352378                    *penmError = pHashEntry->enmError;
    24362379                    if (pHashEntry->pFsObj)
     
    25312474                    pCache->cLookups++;
    25322475                    pCache->cPathHashHits++;
    2533                     KFSCACHE_LOG(("kFsCacheLookupW(%*.*ls) - hit %p\n", cwcPath, cwcPath, pwcPath, pHashEntry->pFsObj));
     2476                    KFSCACHE_LOG2(("kFsCacheLookupW(%*.*ls) - hit %p\n", cwcPath, cwcPath, pwcPath, pHashEntry->pFsObj));
    25342477                    *penmError = pHashEntry->enmError;
    25352478                    if (pHashEntry->pFsObj)
     
    32433186    pCache->uGenerationMissing++;
    32443187    kHlpAssert(pCache->uGenerationMissing < KU32_MAX);
     3188    KFSCACHE_LOG(("Invalidate missing %#x\n", pCache->uGenerationMissing));
    32453189}
    32463190
     
    32583202    pCache->uGeneration++;
    32593203    kHlpAssert(pCache->uGeneration < KU32_MAX);
     3204    KFSCACHE_LOG(("Invalidate all %#x/%#x\n", pCache->uGenerationMissing, pCache->uGeneration));
     3205
    32603206}
    32613207
  • trunk/src/lib/nt/kFsCache.h

    r2861 r2862  
    246246    /** Set if populated. */
    247247    KBOOL               fPopulated;
     248    /** Set if it needs re-populated. */
     249    KBOOL               fNeedRePopulating;
    248250} KFSDIR;
    249251
  • trunk/src/lib/nt/nthlp.h

    r2713 r2862  
    3333
    3434#include "ntstuff.h"
     35#include "nttypes.h"
    3536
    3637
     
    6768
    6869
     70static __inline void birdNtTimeToTimeSpec(__int64 iNtTime, BirdTimeSpec_T *pTimeSpec)
     71{
     72    iNtTime -= BIRD_NT_EPOCH_OFFSET_UNIX_100NS;
     73    pTimeSpec->tv_sec  = iNtTime / 10000000;
     74    pTimeSpec->tv_nsec = (iNtTime % 10000000) * 100;
     75}
     76
     77
    6978#endif
    7079
  • trunk/src/lib/nt/nthlpcore.c

    r2861 r2862  
    5555                                                MY_UNICODE_STRING *, BOOLEAN);
    5656MY_NTSTATUS (WINAPI *g_pfnNtQueryAttributesFile)(MY_OBJECT_ATTRIBUTES *, MY_FILE_BASIC_INFORMATION *);
     57MY_NTSTATUS (WINAPI *g_pfnNtQueryFullAttributesFile)(MY_OBJECT_ATTRIBUTES *, MY_FILE_NETWORK_OPEN_INFORMATION *);
    5758MY_NTSTATUS (WINAPI *g_pfnNtSetInformationFile)(HANDLE, MY_IO_STATUS_BLOCK *, PVOID, LONG, MY_FILE_INFORMATION_CLASS);
    5859BOOLEAN     (WINAPI *g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *);
     
    7778    { (FARPROC *)&g_pfnNtQueryDirectoryFile,            "NtQueryDirectoryFile" },
    7879    { (FARPROC *)&g_pfnNtQueryAttributesFile,           "NtQueryAttributesFile" },
     80    { (FARPROC *)&g_pfnNtQueryFullAttributesFile,       "NtQueryFullAttributesFile" },
    7981    { (FARPROC *)&g_pfnNtSetInformationFile,            "NtSetInformationFile" },
    8082    { (FARPROC *)&g_pfnRtlDosPathNameToNtPathName_U,    "RtlDosPathNameToNtPathName_U" },
  • trunk/src/lib/nt/ntstat.c

    r2858 r2862  
    173173
    174174    return fMode;
    175 }
    176 
    177 
    178 static void birdNtTimeToTimeSpec(__int64 iNtTime, BirdTimeSpec_T *pTimeSpec)
    179 {
    180     iNtTime -= BIRD_NT_EPOCH_OFFSET_UNIX_100NS;
    181     pTimeSpec->tv_sec  = iNtTime / 10000000;
    182     pTimeSpec->tv_nsec = (iNtTime % 10000000) * 100;
    183175}
    184176
  • trunk/src/lib/nt/ntstuff.h

    r2861 r2862  
    114114    BOOLEAN         Directory;
    115115} MY_FILE_STANDARD_INFORMATION;
     116
     117typedef struct MY_FILE_NETWORK_OPEN_INFORMATION
     118{
     119    LARGE_INTEGER   CreationTime;
     120    LARGE_INTEGER   LastAccessTime;
     121    LARGE_INTEGER   LastWriteTime;
     122    LARGE_INTEGER   ChangeTime;
     123    LARGE_INTEGER   AllocationSize;
     124    LARGE_INTEGER   EndOfFile;
     125    ULONG           FileAttributes;
     126} MY_FILE_NETWORK_OPEN_INFORMATION;
    116127
    117128typedef struct MY_FILE_INTERNAL_INFORMATION
     
    435446                                                        MY_UNICODE_STRING *, BOOLEAN);
    436447extern MY_NTSTATUS (WINAPI * g_pfnNtQueryAttributesFile)(MY_OBJECT_ATTRIBUTES *, MY_FILE_BASIC_INFORMATION *);
     448extern MY_NTSTATUS (WINAPI * g_pfnNtQueryFullAttributesFile)(MY_OBJECT_ATTRIBUTES *, MY_FILE_NETWORK_OPEN_INFORMATION *);
    437449extern MY_NTSTATUS (WINAPI * g_pfnNtSetInformationFile)(HANDLE, MY_IO_STATUS_BLOCK *, PVOID, LONG, MY_FILE_INFORMATION_CLASS);
    438450extern BOOLEAN     (WINAPI * g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *);
Note: See TracChangeset for help on using the changeset viewer.