Changeset 965
- Timestamp:
- Aug 19, 2016, 2:20:38 PM (9 years ago)
- Location:
- trunk/client/src
- Files:
-
- 1 added
- 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 1 6 #include <stdio.h> 2 7 #include <stdlib.h> … … 5 10 #include <time.h> 6 11 7 #define NDPL_LARGEFILES 8 #define INCL_LONGLONG 9 #include <ndextpl2.h> 10 11 #include "smbwrp.h" 12 #include "dircache.h" 12 13 13 14 extern PLUGINHELPERTABLE2L *ph; … … 68 69 } 69 70 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) 71 static int dceCreate (DirectoryCacheEntry **ppdce, DirectoryCache* pdc, const char *path, int cFiles) 112 72 { 113 73 DirectoryCacheEntry *pdce = (DirectoryCacheEntry *)malloc(sizeof(DirectoryCacheEntry)); … … 128 88 pdce->ulHash = computehash (path); 129 89 pdce->ulLastUpdateTime = 0; 130 pdce->pdc = p Res->pdc;90 pdce->pdc = pdc; 131 91 pdce->fInvalid = 0; 132 92 … … 155 115 } 156 116 157 static void dceWriteEntry ( Resource *pRes, DirectoryCacheEntry *pdce, const smbwrp_fileinfo *finfo)117 static void dceWriteEntry (DirectoryCache *pdc, DirectoryCacheEntry *pdce, const smbwrp_fileinfo *finfo) 158 118 { 159 119 if (pdce->cInfos >= pdce->cInfosAllocated) … … 165 125 cNewAllocated * sizeof (smbwrp_fileinfo)); 166 126 167 debuglocal(p Res, 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); 168 128 if (pNewInfos) 169 129 { … … 183 143 } 184 144 185 static void dceAdjust ( Resource *pRes, DirectoryCacheEntry *pdce)145 static void dceAdjust (DirectoryCache *pdc, DirectoryCacheEntry *pdce) 186 146 { 187 147 /* If the entry has too many preallocated info structures, adjust the memory allocation */ … … 196 156 cNewAllocated * sizeof (smbwrp_fileinfo)); 197 157 198 debuglocal(p Res, 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); 199 159 if (pNewInfos) 200 160 { … … 209 169 } 210 170 211 static int dcePathEqualsTo ( Resource *pRes, DirectoryCacheEntry *pdce, const char *path)212 { 213 debuglocal(p Res, 9, "dcePathEqualTo: [%s] [%s]\n", path, pdce->pszPath);171 static int dcePathEqualsTo (DirectoryCache *pdc, DirectoryCacheEntry *pdce, const char *path) 172 { 173 debuglocal(pdc->resource, 9, "dcePathEqualTo: [%s] [%s]\n", path, pdce->pszPath); 214 174 return ph->fsphStrICmp (path, pdce->pszPath) == 0; 215 175 } … … 225 185 } 226 186 227 static struct DirectoryCacheEntry *dcFindDirCache ( Resource *pRes, const char *path, int fPrefix)187 static struct DirectoryCacheEntry *dcFindDirCache (DirectoryCache *pdc, const char *path, int fPrefix) 228 188 { 229 189 unsigned long hash = computehash (path); 230 190 231 DirectoryCacheEntry *iter = p Res->pdc->pEntriesHead;232 233 debuglocal(p Res, 9, "findDirCache: [%s]\n", path);191 DirectoryCacheEntry *iter = pdc->pEntriesHead; 192 193 debuglocal(pdc->resource, 9, "findDirCache: [%s]\n", path); 234 194 235 195 while (iter != NULL) 236 196 { 237 debuglocal(p Res, 9, "findDirCache: entry [%s]\n", iter->pszPath);197 debuglocal(pdc->resource, 9, "findDirCache: entry [%s]\n", iter->pszPath); 238 198 if (fPrefix) 239 199 { … … 246 206 { 247 207 if ( iter->ulHash == hash 248 && dcePathEqualsTo (p Res, iter, path)208 && dcePathEqualsTo (pdc, iter, path) 249 209 ) 250 210 { … … 255 215 } 256 216 257 debuglocal(p Res, 9, "findDirCache: %p\n", iter);217 debuglocal(pdc->resource, 9, "findDirCache: %p\n", iter); 258 218 259 219 return iter; 260 220 } 261 221 262 static int dcCreate (struct DirectoryCache **ppdc )222 static int dcCreate (struct DirectoryCache **ppdc, void* pRes) 263 223 { 264 224 int rc; 265 225 266 226 DirectoryCache *pdc = (DirectoryCache *)malloc(sizeof (DirectoryCache)); 267 268 227 if (!pdc) 269 228 { … … 272 231 273 232 rc = lockCreate (&pdc->mutex); 274 275 233 if (rc != NO_ERROR) 276 234 { … … 285 243 pdc->fEnabled = 0; 286 244 pdc->ulExpirationTime = -1; 245 pdc->resource = pRes; 287 246 288 247 *ppdc = pdc; … … 363 322 }; 364 323 365 static int dcExistsInCache ( Resource *pRes, const char *path)324 static int dcExistsInCache (DirectoryCache *pdc, const char *path) 366 325 { 367 326 int rc = CacheFault; 368 327 369 if (p Res->pdc->fEnabled)370 { 371 if (dcFindDirCache (p Res, path, 0) != NULL)328 if (pdc->fEnabled) 329 { 330 if (dcFindDirCache (pdc, path, 0) != NULL) 372 331 { 373 332 rc = CacheOk; 374 333 } 375 334 376 debuglocal(p Res, 9, "ExistsInCache: [%s], %d\n", path, rc);335 debuglocal(pdc->resource, 9, "ExistsInCache: [%s], %d\n", path, rc); 377 336 } 378 337 … … 380 339 } 381 340 382 static int dcRead ( Resource *pRes, const char *path,341 static int dcRead (DirectoryCache *pdc, const char *path, 383 342 PFNADDDIRENTRY fn, 384 filelist_state *state,343 void* plist, 385 344 int *ptotal_received, int fForceCache) 386 345 { 387 346 int i; 388 389 DirectoryCache *pdc = pRes->pdc;390 347 int rc = CacheFault; 391 348 392 349 if (pdc->fEnabled) 393 350 { 394 351 DirectoryCacheEntry *pdce; 395 352 396 pdce = dcFindDirCache (p Res, path, 0);353 pdce = dcFindDirCache (pdc, path, 0); 397 354 398 355 if (pdce) 399 356 { 400 debuglocal(p Res, 9, "CacheRead: entry %p found for [%s]\n", pdce, path);357 debuglocal(pdc->resource, 9, "dcRead: entry %p found for [%s]\n", pdce, path); 401 358 402 359 if (fForceCache) … … 404 361 for (i = 0; i < pdce->cInfos; i++) 405 362 { 406 fn ("", &pdce->aInfos[i], path, state);363 fn ("", &pdce->aInfos[i], path, plist); 407 364 } 408 365 … … 413 370 if (dceExpired (pdce, pdc->ulExpirationTime)) 414 371 { 415 debuglocal(p Res, 9, "CacheRead: expired\n");372 debuglocal(pdc->resource, 9, "dcRead: expired\n"); 416 373 dcRemoveEntry (pdce); 417 374 dceDelete (pdce); … … 421 378 for (i = 0; i < pdce->cInfos; i++) 422 379 { 423 fn ("", &pdce->aInfos[i], path, state);380 fn ("", &pdce->aInfos[i], path, plist); 424 381 } 425 382 … … 434 391 } 435 392 436 debuglocal(p Res, 9, "CacheRead: [%s], %d\n", path, rc);393 debuglocal(pdc->resource, 9, "dcRead: [%s], %d\n", path, rc); 437 394 } 438 395 … … 440 397 } 441 398 442 static DirectoryCacheEntry *dcWriteBegin ( Resource *pRes, const char *path, int cFiles)399 static DirectoryCacheEntry *dcWriteBegin (DirectoryCache *pdc, const char *path, int cFiles) 443 400 { 444 401 DirectoryCacheEntry *pdce = NULL; 445 402 446 if (p Res->pdc->fEnabled)447 { 448 pdce = dcFindDirCache (p Res, path, 0);403 if (pdc->fEnabled) 404 { 405 pdce = dcFindDirCache (pdc, path, 0); 449 406 450 407 if (!pdce) 451 408 { 452 409 /* Does not exist in the cache yet. */ 453 dceCreate (&pdce, p Res, path, cFiles);410 dceCreate (&pdce, pdc, path, cFiles); 454 411 } 455 412 else … … 466 423 } 467 424 468 debuglocal(p Res, 9, "CacheWriteBegin: %s\n", path);425 debuglocal(pdc->resource, 9, "CacheWriteBegin: %s\n", path); 469 426 } 470 427 … … 473 430 474 431 475 static void dcInvalidate ( Resource *pRes, const char *path, int fPrefix)432 static void dcInvalidate (DirectoryCache *pdc, const char *path, int fPrefix) 476 433 { 477 434 DirectoryCacheEntry *pdce; 478 435 479 debuglocal(p Res, 9, "CacheInvalidate: [%s]\n", path);480 481 pdce = dcFindDirCache (p Res, path, fPrefix);436 debuglocal(pdc->resource, 9, "CacheInvalidate: [%s]\n", path); 437 438 pdce = dcFindDirCache (pdc, path, fPrefix); 482 439 483 440 while (pdce) … … 486 443 dceDelete (pdce); 487 444 488 pdce = dcFindDirCache (p Res, path, fPrefix);489 } 490 } 491 492 static int dcFindPath ( Resource *pRes,DirectoryCache *pdc,445 pdce = dcFindDirCache (pdc, path, fPrefix); 446 } 447 } 448 449 static int dcFindPath (DirectoryCache *pdc, 493 450 const char *path, 494 451 const char *parent, … … 501 458 unsigned long hash = computehash (parent); 502 459 503 debuglocal(p Res, 9, "dcFindPath: [%s][%s]\n", parent, name);460 debuglocal(pdc->resource, 9, "dcFindPath: [%s][%s]\n", parent, name); 504 461 505 462 while (pdce != NULL) 506 463 { 507 debuglocal(p Res, 9, "dcFindPath: entry [%s]\n", pdce->pszPath);464 debuglocal(pdc->resource, 9, "dcFindPath: entry [%s]\n", pdce->pszPath); 508 465 509 466 if ( pdce->ulHash == hash 510 && dcePathEqualsTo (p Res, pdce, parent))467 && dcePathEqualsTo (pdc, pdce, parent)) 511 468 { 512 469 /* This entry should contain the path. */ … … 518 475 *finfo = pdce->aInfos[i]; 519 476 *pulAge = timesec () - pdce->ulLastUpdateTime; 520 debuglocal(p Res, 9, "dircache: FindPath %s found, age %d\n", path, *pulAge);477 debuglocal(pdc->resource, 9, "dircache: FindPath %s found, age %d\n", path, *pulAge); 521 478 return 1; 522 479 } … … 527 484 } 528 485 529 debuglocal(p Res, 9, "dircache: FindPath %s not found\n", path);486 debuglocal(pdc->resource, 9, "dircache: FindPath %s not found\n", path); 530 487 return 0; 531 488 } 532 489 533 static int dcCreateDirPath(char *path, int cbPath, filelist_state *state)490 static int dcCreateDirPath(char *path, int cbPath, char* dir_mask, char* fullpath) 534 491 { 535 492 /* State contains the original path passed to the plugin (fullpath) and … … 539 496 */ 540 497 int cbDir; 541 int cbMask = strlen( state->dir_mask) + 1;498 int cbMask = strlen(dir_mask) + 1; 542 499 if (cbMask > cbPath) 543 500 { … … 551 508 { 552 509 cbDir--; /* Exclude the slash. */ 553 memcpy(path, state->fullpath, cbDir);510 memcpy(path, fullpath, cbDir); 554 511 } 555 512 path[cbDir] = 0; … … 562 519 */ 563 520 564 int dircache_create( Resource *pRes)565 { 566 struct DirectoryCache **ppdc = &pRes->pdc; 567 unsigned long ulExpirationTime = pRes->cachetimeout;568 int cMaxEntries = pRes->cachedepth;521 int dircache_create( DirectoryCache **ppdc, void* pRes, 522 int cachetimeout, int cachedepth) 523 { 524 unsigned long ulExpirationTime = cachetimeout; 525 int cMaxEntries = cachedepth; 569 526 int rc; 570 527 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); 575 531 if (rc == NO_ERROR) 576 532 { 577 533 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); 581 538 return rc; 582 539 } 583 540 584 void dircache_delete(Resource *pRes) 585 { 586 DirectoryCache *pdc = pRes->pdc; 587 debuglocal(pRes, 9, "dircache_delete: %p\n", pdc); 541 void dircache_delete(DirectoryCache *pdc) 542 { 543 debuglocal(pdc->resource, 9, "dircache_delete: %p\n", pdc); 588 544 589 545 if (pdc) … … 593 549 } 594 550 595 596 int dircache_list_files(PFNADDDIRENTRY fn,597 filelist_state *state,551 int dircache_list_files(DirectoryCache *pdc, PFNADDDIRENTRY fn, 552 void* plist, 553 char* dir_mask, char* fullpath, 598 554 int *ptotal_received) 599 555 { 600 556 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)) 606 561 { 607 562 return 0; 608 563 } 609 564 610 debuglocal(state->pConn->pRes, 9, "dircache_list_files [%s]\n", path); 611 565 debuglocal(pdc->resource, 9, "dircache_list_files [%s]\n", path); 612 566 if (!pdc) 613 567 { … … 617 571 lockRequest (pdc->mutex); 618 572 619 rc = dcRead ( state->pConn->pRes, path, fn, state, ptotal_received, 0);573 rc = dcRead (pdc, path, fn, plist, ptotal_received, 0); 620 574 621 575 lockRelease (pdc->mutex); … … 624 578 } 625 579 626 void *dircache_write_begin(filelist_state *state, 580 void *dircache_write_begin(DirectoryCache *pdc, 581 char* dir_mask, char* fullpath, 627 582 int cFiles) 628 583 { 629 DirectoryCache *pdc = state->pConn->pRes->pdc;630 584 DirectoryCacheEntry *pdce = NULL; 631 585 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)) 635 589 { 636 590 return NULL; 637 591 } 638 592 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); 640 594 641 595 if (!pdc) … … 655 609 } 656 610 657 pdce = dcWriteBegin ( state->pConn->pRes, path, cFiles);611 pdce = dcWriteBegin (pdc, path, cFiles); 658 612 659 613 lockRelease (pdc->mutex); 660 614 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); 662 616 return (void *)pdce; 663 617 } 664 618 665 void dircache_write_entry(Resource *pRes, void *dircachectx, const smbwrp_fileinfo *finfo) 619 void dircache_write_entry(DirectoryCache *pdc, void *dircachectx, 620 const smbwrp_fileinfo *finfo) 666 621 { 667 622 DirectoryCacheEntry *pdce = (DirectoryCacheEntry *)dircachectx; 668 623 669 debuglocal(p Res, 9, "dircache_write_entry %p\n", pdce);624 debuglocal(pdc->resource, 9, "dircache_write_entry %p\n", pdce); 670 625 671 626 if (!pdce) … … 676 631 lockRequest (pdce->pdc->mutex); 677 632 678 dceWriteEntry (p Res, pdce, finfo);633 dceWriteEntry (pdc, pdce, finfo); 679 634 680 635 lockRelease (pdce->pdc->mutex); 681 636 } 682 637 683 void dircache_write_end( Resource *pRes, void *dircachectx)638 void dircache_write_end(DirectoryCache *pdc, void *dircachectx) 684 639 { 685 640 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); 689 643 690 644 if (!pdce) … … 692 646 return; 693 647 } 694 695 pdc = pdce->pdc;696 648 697 649 lockRequest (pdc->mutex); … … 704 656 else 705 657 { 706 dceAdjust (p Res, pdce);658 dceAdjust (pdc, pdce); 707 659 dcInsertEntry (pdce); 708 660 } … … 711 663 } 712 664 713 void dircache_invalidate( const char *path,714 Resource *pRes,665 void dircache_invalidate(DirectoryCache *pdc, 666 const char *path, 715 667 int fParent) 716 668 { 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); 719 670 720 671 if (!pdc) … … 731 682 memcpy(p, path, cb); 732 683 char *lastSlash = ph->fsphStrRChr(p, '\\'); 684 if (!lastSlash) 685 lastSlash = ph->fsphStrRChr(p, '/'); 733 686 if (lastSlash) 734 687 { 735 688 *lastSlash = 0; 736 dcInvalidate (p Res, p, 0);689 dcInvalidate (pdc, p, 0); 737 690 } 738 691 else 739 692 { 740 dcInvalidate (p Res, "", 0);693 dcInvalidate (pdc, "", 0); 741 694 } 742 695 } 743 696 else 744 697 { 745 dcInvalidate (p Res, path, 0);698 dcInvalidate (pdc, path, 0); 746 699 } 747 700 … … 751 704 } 752 705 753 int dircache_find_path( Resource *pRes,706 int dircache_find_path(DirectoryCache *pdc, 754 707 const char *path, 755 708 smbwrp_fileinfo *finfo, 756 709 unsigned long *pulAge) 757 710 { 758 struct DirectoryCache *pdc = pRes->pdc;759 711 int cb; 760 712 char *p; … … 762 714 int fFound = 0; 763 715 764 debuglocal(p Res, 9, "dircache_find_path [%s]\n", path);716 debuglocal(pdc->resource, 9, "dircache_find_path [%s]\n", path); 765 717 766 718 if (!pdc) … … 782 734 memcpy(p, path, cb); 783 735 lastSlash = ph->fsphStrRChr(p, '\\'); 736 if (!lastSlash) 737 lastSlash = ph->fsphStrRChr(p, '/'); 784 738 if (lastSlash) 785 739 { 786 740 *lastSlash = 0; 787 fFound = dcFindPath (p Res, pdc, path, p, lastSlash + 1, finfo, pulAge);741 fFound = dcFindPath (pdc, path, p, lastSlash + 1, finfo, pulAge); 788 742 } 789 743 else 790 744 { 791 745 /* Find in the root directory. p is the name. */ 792 fFound = dcFindPath (p Res, pdc, path, "", p, finfo, pulAge);746 fFound = dcFindPath (pdc, path, "", p, finfo, pulAge); 793 747 } 794 748
Note:
See TracChangeset
for help on using the changeset viewer.