Ignore:
Timestamp:
Aug 19, 2016, 2:20:38 PM (9 years ago)
Author:
Yuri Dario
Message:

Updates to dircache code to be more independent from samba. ticket#274.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/client/src/dircache.c

    r960 r965  
     1/*
     2   Directory caching code for Netdrive plugins.
     3   Copyright (C) netlabs.org 2010-2016
     4*/
     5
    16#include <stdio.h>
    27#include <stdlib.h>
     
    510#include <time.h>
    611
    7 #define NDPL_LARGEFILES
    8 #define INCL_LONGLONG
    9 #include <ndextpl2.h>
    10 
    11 #include "smbwrp.h"
     12#include "dircache.h"
    1213
    1314extern PLUGINHELPERTABLE2L *ph;
     
    6869}
    6970
    70 
    71 
    72 /*
    73  * An entry in the directory cache contains one directory listing.
    74  */
    75 typedef struct DirectoryCacheEntry
    76 {
    77     struct DirectoryCacheEntry *pNext;
    78     struct DirectoryCacheEntry *pPrev;
    79 
    80     struct DirectoryCache *pdc;
    81    
    82     smbwrp_fileinfo *aInfos;
    83     int cInfos;
    84     int cInfosAllocated;
    85 
    86     char *pszPath;
    87     ULONG ulHash;
    88     ULONG ulLastUpdateTime;
    89     int fInvalid;
    90 } DirectoryCacheEntry;
    91 
    92 typedef struct DirectoryCache
    93 {
    94     NDMUTEX mutex;
    95 
    96     DirectoryCacheEntry *pEntriesHead;
    97     DirectoryCacheEntry *pEntriesTail;
    98     int cEntries;
    99 
    100     int fEnabled;
    101     unsigned long ulExpirationTime;
    102     int cMaxEntries;
    103 } DirectoryCache;
    104 
    105 enum {
    106     CacheFault = 0,
    107     CacheOk = 1
    108 };
    109        
    110 
    111 static int dceCreate (DirectoryCacheEntry **ppdce, Resource *pRes, const char *path, int cFiles)
     71static int dceCreate (DirectoryCacheEntry **ppdce, DirectoryCache* pdc, const char *path, int cFiles)
    11272{
    11373    DirectoryCacheEntry *pdce = (DirectoryCacheEntry *)malloc(sizeof(DirectoryCacheEntry));
     
    12888    pdce->ulHash = computehash (path);
    12989    pdce->ulLastUpdateTime = 0;
    130     pdce->pdc = pRes->pdc;
     90    pdce->pdc = pdc;
    13191    pdce->fInvalid = 0;
    13292
     
    155115}
    156116
    157 static void dceWriteEntry (Resource *pRes, DirectoryCacheEntry *pdce, const smbwrp_fileinfo *finfo)
     117static void dceWriteEntry (DirectoryCache *pdc, DirectoryCacheEntry *pdce, const smbwrp_fileinfo *finfo)
    158118{
    159119    if (pdce->cInfos >= pdce->cInfosAllocated)
     
    165125                                                                cNewAllocated * sizeof (smbwrp_fileinfo));
    166126
    167         debuglocal(pRes, 9, "dceWriteEntry: [%s] realloc %d -> %d\n", pdce->pszPath, pdce->cInfosAllocated, cNewAllocated);
     127        debuglocal(pdc->resource, 9, "dceWriteEntry: [%s] realloc %d -> %d\n", pdce->pszPath, pdce->cInfosAllocated, cNewAllocated);
    168128        if (pNewInfos)
    169129        {
     
    183143}
    184144
    185 static void dceAdjust (Resource *pRes, DirectoryCacheEntry *pdce)
     145static void dceAdjust (DirectoryCache *pdc, DirectoryCacheEntry *pdce)
    186146{
    187147    /* If the entry has too many preallocated info structures, adjust the memory allocation */
     
    196156                                                                cNewAllocated * sizeof (smbwrp_fileinfo));
    197157
    198         debuglocal(pRes, 9, "dceAdjust: [%s] realloc %d -> %d\n", pdce->pszPath, pdce->cInfosAllocated, cNewAllocated);
     158        debuglocal(pdc->resource, 9, "dceAdjust: [%s] realloc %d -> %d\n", pdce->pszPath, pdce->cInfosAllocated, cNewAllocated);
    199159        if (pNewInfos)
    200160        {
     
    209169}
    210170
    211 static int dcePathEqualsTo (Resource *pRes, DirectoryCacheEntry *pdce, const char *path)
    212 {
    213     debuglocal(pRes, 9, "dcePathEqualTo: [%s] [%s]\n", path, pdce->pszPath);
     171static int dcePathEqualsTo (DirectoryCache *pdc, DirectoryCacheEntry *pdce, const char *path)
     172{
     173    debuglocal(pdc->resource, 9, "dcePathEqualTo: [%s] [%s]\n", path, pdce->pszPath);
    214174    return ph->fsphStrICmp (path, pdce->pszPath) == 0;
    215175}
     
    225185}
    226186               
    227 static struct DirectoryCacheEntry *dcFindDirCache (Resource *pRes, const char *path, int fPrefix)
     187static struct DirectoryCacheEntry *dcFindDirCache (DirectoryCache *pdc, const char *path, int fPrefix)
    228188{
    229189    unsigned long hash = computehash (path);
    230190
    231     DirectoryCacheEntry *iter = pRes->pdc->pEntriesHead;
    232 
    233     debuglocal(pRes, 9, "findDirCache: [%s]\n", path);
     191    DirectoryCacheEntry *iter = pdc->pEntriesHead;
     192
     193    debuglocal(pdc->resource, 9, "findDirCache: [%s]\n", path);
    234194
    235195    while (iter != NULL)
    236196    {
    237         debuglocal(pRes, 9, "findDirCache: entry [%s]\n", iter->pszPath);
     197        debuglocal(pdc->resource, 9, "findDirCache: entry [%s]\n", iter->pszPath);
    238198        if (fPrefix)
    239199        {
     
    246206        {
    247207            if (    iter->ulHash == hash
    248                  && dcePathEqualsTo (pRes, iter, path)
     208                 && dcePathEqualsTo (pdc, iter, path)
    249209               )
    250210            {
     
    255215    }
    256216
    257     debuglocal(pRes, 9, "findDirCache: %p\n", iter);
     217    debuglocal(pdc->resource, 9, "findDirCache: %p\n", iter);
    258218
    259219    return iter;
    260220}
    261221
    262 static int dcCreate (struct DirectoryCache **ppdc)
     222static int dcCreate (struct DirectoryCache **ppdc, void* pRes)
    263223{
    264224    int rc;
    265225
    266226    DirectoryCache *pdc = (DirectoryCache *)malloc(sizeof (DirectoryCache));
    267    
    268227    if (!pdc)
    269228    {
     
    272231
    273232    rc = lockCreate (&pdc->mutex);
    274 
    275233    if (rc != NO_ERROR)
    276234    {
     
    285243    pdc->fEnabled = 0;
    286244    pdc->ulExpirationTime = -1;
     245    pdc->resource = pRes;
    287246   
    288247    *ppdc = pdc;
     
    363322};
    364323
    365 static int dcExistsInCache (Resource *pRes, const char *path)
     324static int dcExistsInCache (DirectoryCache *pdc, const char *path)
    366325{
    367326    int rc = CacheFault;
    368327       
    369     if (pRes->pdc->fEnabled)
    370     {
    371         if (dcFindDirCache (pRes, path, 0) != NULL)
     328    if (pdc->fEnabled)
     329    {
     330        if (dcFindDirCache (pdc, path, 0) != NULL)
    372331        {
    373332            rc = CacheOk;
    374333        }
    375334       
    376         debuglocal(pRes, 9, "ExistsInCache: [%s], %d\n", path, rc);
     335        debuglocal(pdc->resource, 9, "ExistsInCache: [%s], %d\n", path, rc);
    377336    }
    378337   
     
    380339}
    381340       
    382 static int dcRead (Resource *pRes, const char *path,
     341static int dcRead (DirectoryCache *pdc, const char *path,
    383342                   PFNADDDIRENTRY fn,
    384                    filelist_state *state,
     343                   void* plist,
    385344                   int *ptotal_received, int fForceCache)
    386345{
    387346    int i;
    388    
    389     DirectoryCache *pdc = pRes->pdc;
    390347    int rc = CacheFault;
    391        
     348
    392349    if (pdc->fEnabled)
    393350    {
    394351        DirectoryCacheEntry *pdce;
    395352
    396         pdce = dcFindDirCache (pRes, path, 0);
     353        pdce = dcFindDirCache (pdc, path, 0);
    397354       
    398355        if (pdce)
    399356        {
    400             debuglocal(pRes, 9, "CacheRead: entry %p found for [%s]\n", pdce, path);
     357            debuglocal(pdc->resource, 9, "dcRead: entry %p found for [%s]\n", pdce, path);
    401358           
    402359            if (fForceCache)
     
    404361                for (i = 0; i < pdce->cInfos; i++)
    405362                {
    406                     fn ("", &pdce->aInfos[i], path, state);
     363                    fn ("", &pdce->aInfos[i], path, plist);
    407364                }
    408365
     
    413370                if (dceExpired (pdce, pdc->ulExpirationTime))
    414371                {
    415                     debuglocal(pRes, 9, "CacheRead: expired\n");
     372                    debuglocal(pdc->resource, 9, "dcRead: expired\n");
    416373                    dcRemoveEntry (pdce);
    417374                    dceDelete (pdce);
     
    421378                    for (i = 0; i < pdce->cInfos; i++)
    422379                    {
    423                         fn ("", &pdce->aInfos[i], path, state);
     380                        fn ("", &pdce->aInfos[i], path, plist);
    424381                    }
    425382
     
    434391        }
    435392       
    436         debuglocal(pRes, 9, "CacheRead: [%s], %d\n", path, rc);
     393        debuglocal(pdc->resource, 9, "dcRead: [%s], %d\n", path, rc);
    437394    }
    438395   
     
    440397}
    441398
    442 static DirectoryCacheEntry *dcWriteBegin (Resource *pRes, const char *path, int cFiles)
     399static DirectoryCacheEntry *dcWriteBegin (DirectoryCache *pdc, const char *path, int cFiles)
    443400{
    444401    DirectoryCacheEntry *pdce = NULL;
    445402
    446     if (pRes->pdc->fEnabled)
    447     {
    448         pdce = dcFindDirCache (pRes, path, 0);
     403    if (pdc->fEnabled)
     404    {
     405        pdce = dcFindDirCache (pdc, path, 0);
    449406       
    450407        if (!pdce)
    451408        {
    452409            /* Does not exist in the cache yet. */
    453             dceCreate (&pdce, pRes, path, cFiles);
     410            dceCreate (&pdce, pdc, path, cFiles);
    454411        }
    455412        else
     
    466423        }
    467424       
    468         debuglocal(pRes, 9, "CacheWriteBegin: %s\n", path);
     425        debuglocal(pdc->resource, 9, "CacheWriteBegin: %s\n", path);
    469426    }
    470427   
     
    473430
    474431
    475 static void dcInvalidate (Resource *pRes, const char *path, int fPrefix)
     432static void dcInvalidate (DirectoryCache *pdc, const char *path, int fPrefix)
    476433{
    477434    DirectoryCacheEntry *pdce;
    478435   
    479     debuglocal(pRes, 9, "CacheInvalidate: [%s]\n", path);
    480 
    481     pdce = dcFindDirCache (pRes, path, fPrefix);
     436    debuglocal(pdc->resource, 9, "CacheInvalidate: [%s]\n", path);
     437
     438    pdce = dcFindDirCache (pdc, path, fPrefix);
    482439
    483440    while (pdce)
     
    486443        dceDelete (pdce);
    487444       
    488         pdce = dcFindDirCache (pRes, path, fPrefix);
    489     }
    490 }
    491 
    492 static int dcFindPath (Resource *pRes, DirectoryCache *pdc,
     445        pdce = dcFindDirCache (pdc, path, fPrefix);
     446    }
     447}
     448
     449static int dcFindPath (DirectoryCache *pdc,
    493450                       const char *path,
    494451                       const char *parent,
     
    501458    unsigned long hash = computehash (parent);
    502459
    503     debuglocal(pRes, 9, "dcFindPath: [%s][%s]\n", parent, name);
     460    debuglocal(pdc->resource, 9, "dcFindPath: [%s][%s]\n", parent, name);
    504461
    505462    while (pdce != NULL)
    506463    {
    507         debuglocal(pRes, 9, "dcFindPath: entry [%s]\n", pdce->pszPath);
     464        debuglocal(pdc->resource, 9, "dcFindPath: entry [%s]\n", pdce->pszPath);
    508465
    509466        if (   pdce->ulHash == hash
    510             && dcePathEqualsTo (pRes, pdce, parent))
     467            && dcePathEqualsTo (pdc, pdce, parent))
    511468        {
    512469            /* This entry should contain the path. */
     
    518475                    *finfo = pdce->aInfos[i];
    519476                    *pulAge = timesec () - pdce->ulLastUpdateTime;
    520                     debuglocal(pRes, 9, "dircache: FindPath %s found, age %d\n", path, *pulAge);
     477                    debuglocal(pdc->resource, 9, "dircache: FindPath %s found, age %d\n", path, *pulAge);
    521478                    return 1;
    522479                }
     
    527484    }
    528485
    529     debuglocal(pRes, 9, "dircache: FindPath %s not found\n", path);
     486    debuglocal(pdc->resource, 9, "dircache: FindPath %s not found\n", path);
    530487    return 0;
    531488}
    532489
    533 static int dcCreateDirPath(char *path, int cbPath, filelist_state *state)
     490static int dcCreateDirPath(char *path, int cbPath, char* dir_mask, char* fullpath)
    534491{
    535492    /* State contains the original path passed to the plugin (fullpath) and
     
    539496     */
    540497    int cbDir;
    541     int cbMask = strlen(state->dir_mask) + 1;
     498    int cbMask = strlen(dir_mask) + 1;
    542499    if (cbMask > cbPath)
    543500    {
     
    551508    {
    552509       cbDir--; /* Exclude the slash. */
    553        memcpy(path, state->fullpath, cbDir);
     510       memcpy(path, fullpath, cbDir);
    554511    }
    555512    path[cbDir] = 0;
     
    562519 */
    563520
    564 int dircache_create(Resource *pRes)
    565 {
    566     struct DirectoryCache **ppdc = &pRes->pdc;
    567     unsigned long ulExpirationTime = pRes->cachetimeout;
    568     int cMaxEntries = pRes->cachedepth;
     521int dircache_create( DirectoryCache **ppdc, void* pRes,
     522                     int cachetimeout, int cachedepth)
     523{
     524    unsigned long ulExpirationTime = cachetimeout;
     525    int cMaxEntries = cachedepth;
    569526    int rc;
    570527
    571     debuglocal(pRes, 9, "dircache_create: %u seconds, %d entries\n", ulExpirationTime, cMaxEntries);
    572 
    573     rc = dcCreate(ppdc);
    574 
     528    debuglocal( pRes, 9, "dircache_create: %u seconds, %d entries\n", ulExpirationTime, cMaxEntries);
     529
     530    rc = dcCreate(ppdc, pRes);
    575531    if (rc == NO_ERROR)
    576532    {
    577533        dcEnable (*ppdc, 1, ulExpirationTime, cMaxEntries);
    578     }
    579 
    580     debuglocal(pRes, 9, "dircache_create: %p, rc = %d\n", *ppdc, rc);
     534
     535    }
     536
     537    debuglocal( (*ppdc)->resource, 9, "dircache_create: %p, rc = %d\n", *ppdc, rc);
    581538    return rc;
    582539}
    583540
    584 void dircache_delete(Resource *pRes)
    585 {
    586     DirectoryCache *pdc = pRes->pdc;
    587     debuglocal(pRes, 9, "dircache_delete: %p\n", pdc);
     541void dircache_delete(DirectoryCache *pdc)
     542{
     543    debuglocal(pdc->resource, 9, "dircache_delete: %p\n", pdc);
    588544
    589545    if (pdc)
     
    593549}
    594550
    595 
    596 int dircache_list_files(PFNADDDIRENTRY fn,
    597                         filelist_state *state,
     551int dircache_list_files(DirectoryCache *pdc, PFNADDDIRENTRY fn,
     552                        void* plist,
     553                        char* dir_mask, char* fullpath,
    598554                        int *ptotal_received)
    599555{
    600556    int rc;
    601     DirectoryCache *pdc = state->pConn->pRes->pdc;
    602 
    603     int cbPath = strlen(state->fullpath) + 1;
    604     char *path = alloca(cbPath);
    605     if (!dcCreateDirPath(path, cbPath, state))
     557
     558    int cbPath = strlen(fullpath) + 1;
     559    char *path = (char*) alloca(cbPath);
     560    if (!dcCreateDirPath(path, cbPath, dir_mask, fullpath))
    606561    {
    607562        return 0;
    608563    }
    609564
    610     debuglocal(state->pConn->pRes, 9, "dircache_list_files [%s]\n", path);
    611 
     565    debuglocal(pdc->resource, 9, "dircache_list_files [%s]\n", path);
    612566    if (!pdc)
    613567    {
     
    617571    lockRequest (pdc->mutex);
    618572
    619     rc = dcRead (state->pConn->pRes, path, fn, state, ptotal_received, 0);
     573    rc = dcRead (pdc, path, fn, plist, ptotal_received, 0);
    620574
    621575    lockRelease (pdc->mutex);
     
    624578}
    625579
    626 void *dircache_write_begin(filelist_state *state,
     580void *dircache_write_begin(DirectoryCache *pdc,
     581                           char* dir_mask, char* fullpath,
    627582                           int cFiles)
    628583{
    629     DirectoryCache *pdc = state->pConn->pRes->pdc;
    630584    DirectoryCacheEntry *pdce = NULL;
    631585
    632     int cbPath = strlen(state->fullpath) + 1;
    633     char *path = alloca(cbPath);
    634     if (!dcCreateDirPath(path, cbPath, state))
     586    int cbPath = strlen(fullpath) + 1;
     587    char *path = (char*) alloca(cbPath);
     588    if (!dcCreateDirPath(path, cbPath, dir_mask, fullpath))
    635589    {
    636590        return NULL;
    637591    }
    638592
    639     debuglocal(state->pConn->pRes, 9, "dircache_write_begin pdc %p path [%s]\n", pdc, path);
     593    debuglocal(pdc->resource, 9, "dircache_write_begin pdc %p path [%s]\n", pdc, path);
    640594
    641595    if (!pdc)
     
    655609    }
    656610   
    657     pdce = dcWriteBegin (state->pConn->pRes, path, cFiles);
     611    pdce = dcWriteBegin (pdc, path, cFiles);
    658612   
    659613    lockRelease (pdc->mutex);
    660614
    661     debuglocal(state->pConn->pRes, 9, "dircache_write_begin returning ctx %p\n", pdce);
     615    debuglocal(pdc->resource, 9, "dircache_write_begin returning ctx %p\n", pdce);
    662616    return (void *)pdce;
    663617}
    664618
    665 void dircache_write_entry(Resource *pRes, void *dircachectx, const smbwrp_fileinfo *finfo)
     619void dircache_write_entry(DirectoryCache *pdc, void *dircachectx,
     620                          const smbwrp_fileinfo *finfo)
    666621{
    667622    DirectoryCacheEntry *pdce = (DirectoryCacheEntry *)dircachectx;
    668623
    669     debuglocal(pRes, 9, "dircache_write_entry %p\n", pdce);
     624    debuglocal(pdc->resource, 9, "dircache_write_entry %p\n", pdce);
    670625   
    671626    if (!pdce)
     
    676631    lockRequest (pdce->pdc->mutex);
    677632   
    678     dceWriteEntry (pRes, pdce, finfo);
     633    dceWriteEntry (pdc, pdce, finfo);
    679634   
    680635    lockRelease (pdce->pdc->mutex);
    681636}
    682637
    683 void dircache_write_end(Resource *pRes, void *dircachectx)
     638void dircache_write_end(DirectoryCache *pdc, void *dircachectx)
    684639{
    685640    DirectoryCacheEntry *pdce = (DirectoryCacheEntry *)dircachectx;
    686     DirectoryCache *pdc;
    687 
    688     debuglocal(pRes, 9, "dircache_write_end: pdce %p\n", pdce);
     641
     642    debuglocal(pdc->resource, 9, "dircache_write_end: pdce %p\n", pdce);
    689643
    690644    if (!pdce)
     
    692646        return;
    693647    }
    694    
    695     pdc = pdce->pdc;
    696648   
    697649    lockRequest (pdc->mutex);
     
    704656    else
    705657    {
    706         dceAdjust (pRes, pdce);
     658        dceAdjust (pdc, pdce);
    707659        dcInsertEntry (pdce);
    708660    }
     
    711663}
    712664
    713 void dircache_invalidate(const char *path,
    714                          Resource *pRes,
     665void dircache_invalidate(DirectoryCache *pdc,
     666                         const char *path,
    715667                         int fParent)
    716668{
    717     struct DirectoryCache *pdc = pRes->pdc;
    718     debuglocal(pRes, 9, "dircache_invalidate [%s], parent %d\n", path, fParent);
     669    debuglocal(pdc->resource, 9, "dircache_invalidate [%s], parent %d\n", path, fParent);
    719670
    720671    if (!pdc)
     
    731682        memcpy(p, path, cb);
    732683        char *lastSlash = ph->fsphStrRChr(p, '\\');
     684        if (!lastSlash)
     685            lastSlash = ph->fsphStrRChr(p, '/');
    733686        if (lastSlash)
    734687        {
    735688            *lastSlash = 0;
    736             dcInvalidate (pRes, p, 0);
     689            dcInvalidate (pdc, p, 0);
    737690        }
    738691        else
    739692        {
    740             dcInvalidate (pRes, "", 0);
     693            dcInvalidate (pdc, "", 0);
    741694        }
    742695    }
    743696    else
    744697    {
    745         dcInvalidate (pRes, path, 0);
     698        dcInvalidate (pdc, path, 0);
    746699    }
    747700   
     
    751704}
    752705
    753 int dircache_find_path(Resource *pRes,
     706int dircache_find_path(DirectoryCache *pdc,
    754707                       const char *path,
    755708                       smbwrp_fileinfo *finfo,
    756709                       unsigned long *pulAge)
    757710{
    758     struct DirectoryCache *pdc = pRes->pdc;
    759711    int cb;
    760712    char *p;
     
    762714    int fFound = 0;
    763715
    764     debuglocal(pRes, 9, "dircache_find_path [%s]\n", path);
     716    debuglocal(pdc->resource, 9, "dircache_find_path [%s]\n", path);
    765717
    766718    if (!pdc)
     
    782734    memcpy(p, path, cb);
    783735    lastSlash = ph->fsphStrRChr(p, '\\');
     736    if (!lastSlash)
     737        lastSlash = ph->fsphStrRChr(p, '/');
    784738    if (lastSlash)
    785739    {
    786740        *lastSlash = 0;
    787         fFound = dcFindPath (pRes, pdc, path, p, lastSlash + 1, finfo, pulAge);
     741        fFound = dcFindPath (pdc, path, p, lastSlash + 1, finfo, pulAge);
    788742    }
    789743    else
    790744    {
    791745        /* Find in the root directory. p is the name. */
    792         fFound = dcFindPath (pRes, pdc, path, "", p, finfo, pulAge);
     746        fFound = dcFindPath (pdc, path, "", p, finfo, pulAge);
    793747    }
    794748   
Note: See TracChangeset for help on using the changeset viewer.