--------------------- PatchSet 1094 Date: 2001/01/05 14:28:21 Author: adri Branch: modio Tag: (none) Log: The initial skeletal implementation of storeLookup() - the async replacement for storeGet() / storeGetPublic(). storeLookup() takes a callback (STDONE) and callback_data and will call callback(callback_data, StoreEntry) at completion. if StoreEntry is NULL, the lookup failed, otherwise the lookup suceeded. * totally canabalise the hash storedir code - we won't need that associated gunk with the old-school UFS because we'll be deleting it all soon. * Implement storeLookup() which will start off a blocking lookup (and hence take a callback for completion) but only on storedir 0. I'd have to track state between storedir calls, and that won't help very much when I don't have any storedirs going yet! * implement a NULL storeHashGet() which returns NULL for now (but will start to perform lookups after this ..) * remove storeOpen() - storeLookup() will replace it * stick an #if 0 .. #endif around the store_swapin.c routines. They will eventually be moved into a library and used, but not just yet .. NOTES: * Once storeLookup() is completely in I plan on changing its name back to storeGet(). I'm just dodging symbol conflicts right now, so pardon the ambiguity. Members: src/protos.h:1.2.2.11->1.2.2.12 src/store_io.c:1.2->1.2.2.1 src/store_swapin.c:1.2.2.1->1.2.2.2 src/structs.h:1.2.2.12->1.2.2.13 src/typedefs.h:1.2.2.5->1.2.2.6 src/fs/hash/store_dir_hash.c:1.1.2.1->1.1.2.2 src/fs/hash/store_hash.h:1.1.2.1->1.1.2.2 src/fs/hash/store_io_hash.c:1.1.2.1->1.1.2.2 Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.2.2.11 retrieving revision 1.2.2.12 diff -u -r1.2.2.11 -r1.2.2.12 --- squid/src/protos.h 4 Jan 2001 16:29:41 -0000 1.2.2.11 +++ squid/src/protos.h 5 Jan 2001 14:28:21 -0000 1.2.2.12 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.2.2.11 2001/01/04 16:29:41 adri Exp $ + * $Id: protos.h,v 1.2.2.12 2001/01/05 14:28:21 adri Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -876,6 +876,7 @@ extern void storeReplSetup(void); /* store_io.c */ +extern void storeLookup(const char *, const method_t , STGETDONE *, void *); extern storeIOState *storeCreate(StoreEntry *, STFNCB *, STIOCB *, void *); extern storeIOState *storeOpen(StoreEntry *, STFNCB *, STIOCB *, void *); extern void storeClose(storeIOState *); Index: squid/src/store_io.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/store_io.c,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -r1.2 -r1.2.2.1 --- squid/src/store_io.c 21 Oct 2000 15:16:13 -0000 1.2 +++ squid/src/store_io.c 5 Jan 2001 14:28:21 -0000 1.2.2.1 @@ -18,7 +18,8 @@ * to select different polices depending on object size or type. */ storeIOState * -storeCreate(StoreEntry * e, STIOCB * file_callback, STIOCB * close_callback, void *callback_data) +storeCreate(StoreEntry * e, STIOCB * file_callback, STIOCB * close_callback, + void *callback_data) { size_t objsize; sdirno dirn; @@ -29,7 +30,7 @@ /* This is just done for logging purposes */ objsize = objectLen(e); if (objsize != -1) - objsize += e->mem_obj->swap_hdr_sz; + objsize += e->mem_obj->swap_hdr_sz; /* * Pick the swapdir @@ -37,32 +38,43 @@ */ dirn = storeDirSelectSwapDir(e); if (dirn == -1) { - debug(20, 2) ("storeCreate: no valid swapdirs for this object\n"); - store_io_stats.create.select_fail++; - return NULL; + debug(20, 2) ("storeCreate: no valid swapdirs for this object\n"); + store_io_stats.create.select_fail++; + return NULL; } - debug(20, 2) ("storeCreate: Selected dir '%d' for obj size '%d'\n", dirn, objsize); + debug(20, 2) ("storeCreate: Selected dir '%d' for obj size '%d'\n", dirn, + objsize); SD = &Config.cacheSwap.swapDirs[dirn]; /* Now that we have a fs to use, call its storeCreate function */ sio = SD->obj.create(SD, e, file_callback, close_callback, callback_data); if (NULL == sio) - store_io_stats.create.create_fail++; + store_io_stats.create.create_fail++; else - store_io_stats.create.success++; + store_io_stats.create.success++; return sio; } + /* - * storeOpen() is purely for reading .. + * storeLookup - the eventual replacement for storeGet()/storeGetPublic() + * + * This function handles issuing lookups to each of the object stores. + * A callback/data pair will be called with the StoreEntry referencing + * the object if one is found, or NULL is returned. + * + * Yes, its inefficient right now, but there isn't much we can do about + * it until we've got *something* that works.. */ -storeIOState * -storeOpen(StoreEntry * e, STFNCB * file_callback, STIOCB * callback, - void *callback_data) +void +storeLookup(const char *uri, const method_t method, STGETDONE *callback, + void *callback_data) { - SwapDir *SD = &Config.cacheSwap.swapDirs[e->swap_dirn]; - return SD->obj.open(SD, e, file_callback, callback, callback_data); + /* Only begin a lookup in StoreDir 0 for now */ + SwapDir *sd = INDEXSD(0); + + sd->obj.get(sd, uri, method, callback, callback_data); } void Index: squid/src/store_swapin.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/store_swapin.c,v retrieving revision 1.2.2.1 retrieving revision 1.2.2.2 diff -u -r1.2.2.1 -r1.2.2.2 --- squid/src/store_swapin.c 9 Nov 2000 15:25:07 -0000 1.2.2.1 +++ squid/src/store_swapin.c 5 Jan 2001 14:28:21 -0000 1.2.2.2 @@ -1,6 +1,6 @@ /* - * $Id: store_swapin.c,v 1.2.2.1 2000/11/09 15:25:07 adri Exp $ + * $Id: store_swapin.c,v 1.2.2.2 2001/01/05 14:28:21 adri Exp $ * * DEBUG: section 20 Storage Manager Swapin Functions * AUTHOR: Duane Wessels @@ -38,6 +38,7 @@ static STIOCB storeSwapInFileClosed; static STFNCB storeSwapInFileNotify; +#if 0 void storeSwapInStart(store_client * sc) { @@ -94,3 +95,4 @@ e->swap_filen = sio->swap_filen; e->swap_dirn = sio->swap_dirn; } +#endif Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.2.2.12 retrieving revision 1.2.2.13 diff -u -r1.2.2.12 -r1.2.2.13 --- squid/src/structs.h 4 Jan 2001 14:23:12 -0000 1.2.2.12 +++ squid/src/structs.h 5 Jan 2001 14:28:21 -0000 1.2.2.13 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.2.2.12 2001/01/04 14:23:12 adri Exp $ + * $Id: structs.h,v 1.2.2.13 2001/01/05 14:28:21 adri Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -1373,8 +1373,8 @@ STCALLBACK *callback; /* Handle pending callbacks */ STSYNC *sync; /* Sync the directory */ struct { - STOBJCREATE *create; - STOBJOPEN *open; + STOBJCREATE *create; + STOBJGET *get; STOBJCLOSE *close; STOBJREAD *read; STOBJWRITE *write; Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.2.2.5 retrieving revision 1.2.2.6 diff -u -r1.2.2.5 -r1.2.2.6 --- squid/src/typedefs.h 27 Dec 2000 11:04:06 -0000 1.2.2.5 +++ squid/src/typedefs.h 5 Jan 2001 14:28:21 -0000 1.2.2.6 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.2.2.5 2000/12/27 11:04:06 adri Exp $ + * $Id: typedefs.h,v 1.2.2.6 2001/01/05 14:28:21 adri Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -248,13 +248,20 @@ typedef int STCALLBACK(SwapDir *); typedef void STSYNC(SwapDir *); -typedef storeIOState *STOBJCREATE(SwapDir *, StoreEntry *, STFNCB *, STIOCB *, void *); -typedef storeIOState *STOBJOPEN(SwapDir *, StoreEntry *, STFNCB *, STIOCB *, void *); +/* store lookup callback */ +typedef void STGETDONE(void *, StoreEntry *); + +/* store IO functions */ +typedef storeIOState *STOBJCREATE(SwapDir *, StoreEntry *, STFNCB *, STIOCB *, + void *); typedef void STOBJCLOSE(SwapDir *, storeIOState *); typedef void STOBJREAD(SwapDir *, storeIOState *, char *, size_t, off_t, STRCB *, void *); typedef void STOBJWRITE(SwapDir *, storeIOState *, char *, size_t, off_t, FREE *); typedef void STOBJUNLINK(SwapDir *, StoreEntry *); +typedef void STOBJGET(SwapDir *, const char *, const method_t, STGETDONE *, + void *); + typedef void STLOGOPEN(SwapDir *); typedef void STLOGCLOSE(SwapDir *); typedef void STLOGWRITE(const SwapDir *, const StoreEntry *, int); @@ -281,6 +288,7 @@ typedef void STRPUBLIC(StoreEntry *); typedef void STRPRIVATE(StoreEntry *); + typedef double hbase_f(double); typedef void StatHistBinDumper(StoreEntry *, int idx, double val, double size, int count); Index: squid/src/fs/hash/store_dir_hash.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/fs/hash/Attic/store_dir_hash.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- squid/src/fs/hash/store_dir_hash.c 16 Dec 2000 09:29:03 -0000 1.1.2.1 +++ squid/src/fs/hash/store_dir_hash.c 5 Jan 2001 14:28:22 -0000 1.1.2.2 @@ -1,6 +1,6 @@ /* - * $Id: store_dir_hash.c,v 1.1.2.1 2000/12/16 09:29:03 adri Exp $ + * $Id: store_dir_hash.c,v 1.1.2.2 2001/01/05 14:28:22 adri Exp $ * * DEBUG: section 47 Store Directory Routines * AUTHOR: Duane Wessels @@ -46,29 +46,6 @@ #define DefaultLevelTwoDirs 256 #define STORE_META_BHASHZ 4096 -typedef struct _RebuildState RebuildState; -struct _RebuildState { - SwapDir *sd; - int n_read; - FILE *log; - int speed; - int curlvl1; - int curlvl2; - struct { - unsigned int need_to_validate:1; - unsigned int clean:1; - unsigned int init:1; - } flags; - int done; - int in_dir; - int fn; - struct dirent *entry; - DIR *td; - char fullpath[SQUID_MAXPATHLEN]; - char fullfilename[SQUID_MAXPATHLEN]; - struct _store_rebuild_data counts; -}; - static int n_hash_dirs = 0; static int *hash_dir_index = NULL; MemPool *hash_state_pool = NULL; @@ -80,46 +57,19 @@ static int storeHashDirVerifyDirectory(const char *path); static void storeHashDirCreateSwapSubDirs(SwapDir *); static char *storeHashDirSwapLogFile(SwapDir *, const char *); -static EVH storeHashDirRebuildFromDirectory; -static EVH storeHashDirRebuildFromSwapLog; -static int storeHashDirGetNextFile(RebuildState *, int *sfileno, int *size); -static StoreEntry *storeHashDirAddDiskRestore(SwapDir * SD, const cache_key * key, - int file_number, - size_t swap_file_sz, - time_t expires, - time_t timestamp, - time_t lastref, - time_t lastmod, - u_num32 refcount, - u_short flags, - int clean); -static void storeHashDirRebuild(SwapDir * sd); -static void storeHashDirCloseTmpSwapLog(SwapDir * sd); -static FILE *storeHashDirOpenTmpSwapLog(SwapDir *, int *, int *); static STLOGOPEN storeHashDirOpenSwapLog; static STINIT storeHashDirInit; static STFREE storeHashDirFree; -static STLOGCLEANSTART storeHashDirWriteCleanStart; -static STLOGCLEANNEXTENTRY storeHashDirCleanLogNextEntry; -static STLOGCLEANWRITE storeHashDirWriteCleanEntry; -static STLOGCLEANDONE storeHashDirWriteCleanDone; -static STLOGCLOSE storeHashDirCloseSwapLog; -static STLOGWRITE storeHashDirSwapLog; static STNEWFS storeHashDirNewfs; static STDUMP storeHashDirDump; static STMAINTAINFS storeHashDirMaintain; static STCHECKOBJ storeHashDirCheckObj; static STREFOBJ storeHashDirRefObj; static STUNREFOBJ storeHashDirUnrefObj; -static QS rev_int_sort; -static int storeHashDirClean(int swap_index); static EVH storeHashDirCleanEvent; -static int storeHashDirIs(SwapDir * sd); -static int storeHashFilenoBelongsHere(int fn, int F0, int F1, int F2); static int storeHashCleanupDoubleCheck(SwapDir *, StoreEntry *); static void storeHashDirStats(SwapDir *, StoreEntry *); static void storeHashDirInitBitmap(SwapDir *); -static int storeHashDirValidFileno(SwapDir *, sfileno, int); /* * These functions were ripped straight out of the heart of store_dir.c. @@ -336,22 +286,6 @@ } static void -storeHashDirCloseSwapLog(SwapDir * sd) -{ - hashinfo_t *hashinfo = (hashinfo_t *) sd->fsdata; - if (hashinfo->swaplog_fd < 0) /* not open */ - return; - file_close(hashinfo->swaplog_fd); - debug(47, 3) ("Cache Dir #%d log closed on FD %d\n", - sd->index, hashinfo->swaplog_fd); - hashinfo->swaplog_fd = -1; - n_hash_dirs--; - assert(n_hash_dirs >= 0); - if (0 == n_hash_dirs) - safe_free(hash_dir_index); -} - -static void storeHashDirInit(SwapDir * sd) { static int started_clean_event = 0; @@ -363,571 +297,12 @@ if (storeHashDirVerifyCacheDirs(sd) < 0) fatal(errmsg); storeHashDirOpenSwapLog(sd); - storeHashDirRebuild(sd); if (!started_clean_event) { eventAdd("storeDirClean", storeHashDirCleanEvent, NULL, 15.0, 1); started_clean_event = 1; } } -static void -storeHashDirRebuildFromDirectory(void *data) -{ - RebuildState *rb = data; - SwapDir *SD = rb->sd; - LOCAL_ARRAY(char, hdr_buf, SM_PAGE_SIZE); - StoreEntry *e = NULL; - StoreEntry tmpe; - cache_key key[MD5_DIGEST_CHARS]; - int sfileno = 0; - int count; - int size; - struct stat sb; - int swap_hdr_len; - int fd = -1; - tlv *tlv_list; - tlv *t; - assert(rb != NULL); - debug(20, 3) ("storeHashDirRebuildFromDirectory: DIR #%d\n", rb->sd->index); - for (count = 0; count < rb->speed; count++) { - assert(fd == -1); - fd = storeHashDirGetNextFile(rb, &sfileno, &size); - if (fd == -2) { - debug(20, 1) ("Done scanning %s swaplog (%d entries)\n", - rb->sd->path, rb->n_read); - store_dirs_rebuilding--; - storeHashDirCloseTmpSwapLog(rb->sd); - storeRebuildComplete(&rb->counts); - cbdataFree(rb); - return; - } else if (fd < 0) { - continue; - } - assert(fd > -1); - /* lets get file stats here */ - if (fstat(fd, &sb) < 0) { - debug(20, 1) ("storeHashDirRebuildFromDirectory: fstat(FD %d): %s\n", - fd, xstrerror()); - file_close(fd); - store_open_disk_fd--; - fd = -1; - continue; - } - if ((++rb->counts.scancount & 0xFFFF) == 0) - debug(20, 3) (" %s %7d files opened so far.\n", - rb->sd->path, rb->counts.scancount); - debug(20, 9) ("file_in: fd=%d %08X\n", fd, sfileno); - statCounter.syscalls.disk.reads++; - if (read(fd, hdr_buf, SM_PAGE_SIZE) < 0) { - debug(20, 1) ("storeHashDirRebuildFromDirectory: read(FD %d): %s\n", - fd, xstrerror()); - file_close(fd); - store_open_disk_fd--; - fd = -1; - continue; - } - file_close(fd); - store_open_disk_fd--; - fd = -1; - swap_hdr_len = 0; -#if USE_TRUNCATE - if (sb.st_size == 0) - continue; -#endif - tlv_list = storeSwapMetaUnpack(hdr_buf, &swap_hdr_len); - if (tlv_list == NULL) { - debug(20, 1) ("storeHashDirRebuildFromDirectory: failed to get meta data\n"); - /* XXX shouldn't this be a call to storeHashUnlink ? */ - storeHashDirUnlinkFile(SD, sfileno); - continue; - } - debug(20, 3) ("storeHashDirRebuildFromDirectory: successful swap meta unpacking\n"); - memset(key, '\0', MD5_DIGEST_CHARS); - memset(&tmpe, '\0', sizeof(StoreEntry)); - for (t = tlv_list; t; t = t->next) { - switch (t->type) { - case STORE_META_KEY: - assert(t->length == MD5_DIGEST_CHARS); - xmemcpy(key, t->value, MD5_DIGEST_CHARS); - break; - case STORE_META_STD: - assert(t->length == STORE_HDR_METASIZE); - xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE); - break; - default: - break; - } - } - storeSwapTLVFree(tlv_list); - tlv_list = NULL; - if (storeKeyNull(key)) { - debug(20, 1) ("storeHashDirRebuildFromDirectory: NULL key\n"); - storeHashDirUnlinkFile(SD, sfileno); - continue; - } - tmpe.hash.key = key; - /* check sizes */ - if (tmpe.swap_file_sz == 0) { - tmpe.swap_file_sz = sb.st_size; - } else if (tmpe.swap_file_sz == sb.st_size - swap_hdr_len) { - tmpe.swap_file_sz = sb.st_size; - } else if (tmpe.swap_file_sz != sb.st_size) { - debug(20, 1) ("storeHashDirRebuildFromDirectory: SIZE MISMATCH %d!=%d\n", - tmpe.swap_file_sz, (int) sb.st_size); - storeHashDirUnlinkFile(SD, sfileno); - continue; - } - if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) { - storeHashDirUnlinkFile(SD, sfileno); - rb->counts.badflags++; - continue; - } - e = storeGet(key); - if (e && e->lastref >= tmpe.lastref) { - /* key already exists, current entry is newer */ - /* keep old, ignore new */ - rb->counts.dupcount++; - continue; - } else if (NULL != e) { - /* URL already exists, this swapfile not being used */ - /* junk old, load new */ - storeRelease(e); /* release old entry */ - rb->counts.dupcount++; - } - rb->counts.objcount++; - storeEntryDump(&tmpe, 5); - e = storeHashDirAddDiskRestore(SD, key, - sfileno, - tmpe.swap_file_sz, - tmpe.expires, - tmpe.timestamp, - tmpe.lastref, - tmpe.lastmod, - tmpe.refcount, /* refcount */ - tmpe.flags, /* flags */ - (int) rb->flags.clean); - storeDirSwapLog(e, SWAP_LOG_ADD); - } - eventAdd("storeRebuild", storeHashDirRebuildFromDirectory, rb, 0.0, 1); -} - -static void -storeHashDirRebuildFromSwapLog(void *data) -{ - RebuildState *rb = data; - SwapDir *SD = rb->sd; - StoreEntry *e = NULL; - storeSwapLogData s; - size_t ss = sizeof(storeSwapLogData); - int count; - int used; /* is swapfile already in use? */ - int disk_entry_newer; /* is the log entry newer than current entry? */ - double x; - assert(rb != NULL); - /* load a number of objects per invocation */ - for (count = 0; count < rb->speed; count++) { - if (fread(&s, ss, 1, rb->log) != 1) { - debug(20, 1) ("Done reading %s swaplog (%d entries)\n", - rb->sd->path, rb->n_read); - fclose(rb->log); - rb->log = NULL; - store_dirs_rebuilding--; - storeHashDirCloseTmpSwapLog(rb->sd); - storeRebuildComplete(&rb->counts); - cbdataFree(rb); - return; - } - rb->n_read++; - if (s.op <= SWAP_LOG_NOP) - continue; - if (s.op >= SWAP_LOG_MAX) - continue; - /* - * BC: during 2.4 development, we changed the way swap file - * numbers are assigned and stored. The high 16 bits used - * to encode the SD index number. There used to be a call - * to storeDirProperFileno here that re-assigned the index - * bits. Now, for backwards compatibility, we just need - * to mask it off. - */ - s.swap_filen &= 0x00FFFFFF; - debug(20, 3) ("storeHashDirRebuildFromSwapLog: %s %s %08X\n", - swap_log_op_str[(int) s.op], - storeKeyText(s.key), - s.swap_filen); - if (s.op == SWAP_LOG_ADD) { - (void) 0; - } else if (s.op == SWAP_LOG_DEL) { - if ((e = storeGet(s.key)) != NULL) { - /* - * Make sure we don't unlink the file, it might be - * in use by a subsequent entry. Also note that - * we don't have to subtract from store_swap_size - * because adding to store_swap_size happens in - * the cleanup procedure. - */ - storeExpireNow(e); - storeReleaseRequest(e); - storeHashDirReplRemove(e); - if (e->swap_filen > -1) { - storeHashDirMapBitReset(SD, e->swap_filen); - e->swap_filen = -1; - e->swap_dirn = -1; - } - storeRelease(e); - rb->counts.objcount--; - rb->counts.cancelcount++; - } - continue; - } else { - x = log(++rb->counts.bad_log_op) / log(10.0); - if (0.0 == x - (double) (int) x) - debug(20, 1) ("WARNING: %d invalid swap log entries found\n", - rb->counts.bad_log_op); - rb->counts.invalid++; - continue; - } - if ((++rb->counts.scancount & 0xFFF) == 0) { - struct stat sb; - if (0 == fstat(fileno(rb->log), &sb)) - storeRebuildProgress(SD->index, - (int) sb.st_size / ss, rb->n_read); - } - if (!storeHashDirValidFileno(SD, s.swap_filen, 0)) { - rb->counts.invalid++; - continue; - } - if (EBIT_TEST(s.flags, KEY_PRIVATE)) { - rb->counts.badflags++; - continue; - } - e = storeGet(s.key); - used = storeHashDirMapBitTest(SD, s.swap_filen); - /* If this URL already exists in the cache, does the swap log - * appear to have a newer entry? Compare 'lastref' from the - * swap log to e->lastref. */ - disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0; - if (used && !disk_entry_newer) { - /* log entry is old, ignore it */ - rb->counts.clashcount++; - continue; - } else if (used && e && e->swap_filen == s.swap_filen && e->swap_dirn == SD->index) { - /* swapfile taken, same URL, newer, update meta */ - if (e->store_status == STORE_OK) { - e->lastref = s.timestamp; - e->timestamp = s.timestamp; - e->expires = s.expires; - e->lastmod = s.lastmod; - e->flags = s.flags; - e->refcount += s.refcount; - storeHashDirUnrefObj(SD, e); - } else { - debug_trap("storeHashDirRebuildFromSwapLog: bad condition"); - debug(20, 1) ("\tSee %s:%d\n", __FILE__, __LINE__); - } - continue; - } else if (used) { - /* swapfile in use, not by this URL, log entry is newer */ - /* This is sorta bad: the log entry should NOT be newer at this - * point. If the log is dirty, the filesize check should have - * caught this. If the log is clean, there should never be a - * newer entry. */ - debug(20, 1) ("WARNING: newer swaplog entry for dirno %d, fileno %08X\n", - SD->index, s.swap_filen); - /* I'm tempted to remove the swapfile here just to be safe, - * but there is a bad race condition in the NOVM version if - * the swapfile has recently been opened for writing, but - * not yet opened for reading. Because we can't map - * swapfiles back to StoreEntrys, we don't know the state - * of the entry using that file. */ - /* We'll assume the existing entry is valid, probably because - * were in a slow rebuild and the the swap file number got taken - * and the validation procedure hasn't run. */ - assert(rb->flags.need_to_validate); - rb->counts.clashcount++; - continue; - } else if (e && !disk_entry_newer) { - /* key already exists, current entry is newer */ - /* keep old, ignore new */ - rb->counts.dupcount++; - continue; - } else if (e) { - /* key already exists, this swapfile not being used */ - /* junk old, load new */ - storeExpireNow(e); - storeReleaseRequest(e); - storeHashDirReplRemove(e); - if (e->swap_filen > -1) { - /* Make sure we don't actually unlink the file */ - storeHashDirMapBitReset(SD, e->swap_filen); - e->swap_filen = -1; - e->swap_dirn = -1; - } - storeRelease(e); - rb->counts.dupcount++; - } else { - /* URL doesnt exist, swapfile not in use */ - /* load new */ - (void) 0; - } - /* update store_swap_size */ - rb->counts.objcount++; - e = storeHashDirAddDiskRestore(SD, s.key, - s.swap_filen, - s.swap_file_sz, - s.expires, - s.timestamp, - s.lastref, - s.lastmod, - s.refcount, - s.flags, - (int) rb->flags.clean); - storeDirSwapLog(e, SWAP_LOG_ADD); - } - eventAdd("storeRebuild", storeHashDirRebuildFromSwapLog, rb, 0.0, 1); -} - -static int -storeHashDirGetNextFile(RebuildState * rb, int *sfileno, int *size) -{ - SwapDir *SD = rb->sd; - hashinfo_t *hashinfo = (hashinfo_t *) SD->fsdata; - int fd = -1; - int used = 0; - int dirs_opened = 0; - debug(20, 3) ("storeHashDirGetNextFile: flag=%d, %d: /%02X/%02X\n", - rb->flags.init, - rb->sd->index, - rb->curlvl1, rb->curlvl2); - if (rb->done) - return -2; - while (fd < 0 && rb->done == 0) { - fd = -1; - if (0 == rb->flags.init) { /* initialize, open first file */ - rb->done = 0; - rb->curlvl1 = 0; - rb->curlvl2 = 0; - rb->in_dir = 0; - rb->flags.init = 1; - assert(Config.cacheSwap.n_configured > 0); - } - if (0 == rb->in_dir) { /* we need to read in a new directory */ - snprintf(rb->fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X", - rb->sd->path, - rb->curlvl1, - rb->curlvl2); - if (rb->flags.init && rb->td != NULL) - closedir(rb->td); - rb->td = NULL; - if (dirs_opened) - return -1; - rb->td = opendir(rb->fullpath); - dirs_opened++; - if (rb->td == NULL) { - debug(50, 1) ("storeHashDirGetNextFile: opendir: %s: %s\n", - rb->fullpath, xstrerror()); - } else { - rb->entry = readdir(rb->td); /* skip . and .. */ - rb->entry = readdir(rb->td); - if (rb->entry == NULL && errno == ENOENT) - debug(20, 1) ("storeHashDirGetNextFile: directory does not exist!.\n"); - debug(20, 3) ("storeHashDirGetNextFile: Directory %s\n", rb->fullpath); - } - } - if (rb->td != NULL && (rb->entry = readdir(rb->td)) != NULL) { - rb->in_dir++; - if (sscanf(rb->entry->d_name, "%x", &rb->fn) != 1) { - debug(20, 3) ("storeHashDirGetNextFile: invalid %s\n", - rb->entry->d_name); - continue; - } - if (!storeHashFilenoBelongsHere(rb->fn, rb->sd->index, rb->curlvl1, rb->curlvl2)) { - debug(20, 3) ("storeHashDirGetNextFile: %08X does not belong in %d/%d/%d\n", - rb->fn, rb->sd->index, rb->curlvl1, rb->curlvl2); - continue; - } - used = storeHashDirMapBitTest(SD, rb->fn); - if (used) { - debug(20, 3) ("storeHashDirGetNextFile: Locked, continuing with next.\n"); - continue; - } - snprintf(rb->fullfilename, SQUID_MAXPATHLEN, "%s/%s", - rb->fullpath, rb->entry->d_name); - debug(20, 3) ("storeHashDirGetNextFile: Opening %s\n", rb->fullfilename); - fd = file_open(rb->fullfilename, O_RDONLY); - if (fd < 0) - debug(50, 1) ("storeHashDirGetNextFile: %s: %s\n", rb->fullfilename, xstrerror()); - else - store_open_disk_fd++; - continue; - } - rb->in_dir = 0; - if (++rb->curlvl2 < hashinfo->l2) - continue; - rb->curlvl2 = 0; - if (++rb->curlvl1 < hashinfo->l1) - continue; - rb->curlvl1 = 0; - rb->done = 1; - } - *sfileno = rb->fn; - return fd; -} - -/* Add a new object to the cache with empty memory copy and pointer to disk - * use to rebuild store from disk. */ -static StoreEntry * -storeHashDirAddDiskRestore(SwapDir * SD, const cache_key * key, - int file_number, - size_t swap_file_sz, - time_t expires, - time_t timestamp, - time_t lastref, - time_t lastmod, - u_num32 refcount, - u_short flags, - int clean) -{ - StoreEntry *e = NULL; - debug(20, 5) ("storeHashAddDiskRestore: %s, fileno=%08X\n", storeKeyText(key), file_number); - /* if you call this you'd better be sure file_number is not - * already in use! */ - e = new_StoreEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL); - e->store_status = STORE_OK; - storeSetMemStatus(e, NOT_IN_MEMORY); - e->swap_status = SWAPOUT_DONE; - e->swap_filen = file_number; - e->swap_dirn = SD->index; - e->swap_file_sz = swap_file_sz; - e->lock_count = 0; - e->lastref = lastref; - e->timestamp = timestamp; - e->expires = expires; - e->lastmod = lastmod; - e->refcount = refcount; - e->flags = flags; - EBIT_SET(e->flags, ENTRY_CACHABLE); - EBIT_CLR(e->flags, RELEASE_REQUEST); - EBIT_CLR(e->flags, KEY_PRIVATE); - e->ping_status = PING_NONE; - EBIT_CLR(e->flags, ENTRY_VALIDATED); - storeHashDirMapBitSet(SD, e->swap_filen); - storeHashInsert(e, key); /* do it after we clear KEY_PRIVATE */ - storeHashDirReplAdd(SD, e); - return e; -} - -static void -storeHashDirRebuild(SwapDir * sd) -{ - RebuildState *rb = xcalloc(1, sizeof(*rb)); - int clean = 0; - int zero = 0; - FILE *fp; - EVH *func = NULL; - rb->sd = sd; - rb->speed = opt_foreground_rebuild ? 1 << 30 : 50; - /* - * If the swap.state file exists in the cache_dir, then - * we'll use storeHashDirRebuildFromSwapLog(), otherwise we'll - * use storeHashDirRebuildFromDirectory() to open up each file - * and suck in the meta data. - */ - fp = storeHashDirOpenTmpSwapLog(sd, &clean, &zero); - if (fp == NULL || zero) { - if (fp != NULL) - fclose(fp); - func = storeHashDirRebuildFromDirectory; - } else { - func = storeHashDirRebuildFromSwapLog; - rb->log = fp; - rb->flags.clean = (unsigned int) clean; - } - if (!clean) - rb->flags.need_to_validate = 1; - debug(20, 1) ("Rebuilding storage in %s (%s)\n", - sd->path, clean ? "CLEAN" : "DIRTY"); - store_dirs_rebuilding++; - cbdataAdd(rb, cbdataXfree, 0); - eventAdd("storeRebuild", func, rb, 0.0, 1); -} - -static void -storeHashDirCloseTmpSwapLog(SwapDir * sd) -{ - hashinfo_t *hashinfo = (hashinfo_t *) sd->fsdata; - char *swaplog_path = xstrdup(storeHashDirSwapLogFile(sd, NULL)); - char *new_path = xstrdup(storeHashDirSwapLogFile(sd, ".new")); - int fd; - file_close(hashinfo->swaplog_fd); -#ifdef _SQUID_OS2_ - if (unlink(swaplog_path) < 0) { - debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror()); - fatal("storeHashDirCloseTmpSwapLog: unlink failed"); - } -#endif - if (xrename(new_path, swaplog_path) < 0) { - fatal("storeHashDirCloseTmpSwapLog: rename failed"); - } - fd = file_open(swaplog_path, O_WRONLY | O_CREAT); - if (fd < 0) { - debug(50, 1) ("%s: %s\n", swaplog_path, xstrerror()); - fatal("storeHashDirCloseTmpSwapLog: Failed to open swap log."); - } - safe_free(swaplog_path); - safe_free(new_path); - hashinfo->swaplog_fd = fd; - debug(47, 3) ("Cache Dir #%d log opened on FD %d\n", sd->index, fd); -} - -static FILE * -storeHashDirOpenTmpSwapLog(SwapDir * sd, int *clean_flag, int *zero_flag) -{ - hashinfo_t *hashinfo = (hashinfo_t *) sd->fsdata; - char *swaplog_path = xstrdup(storeHashDirSwapLogFile(sd, NULL)); - char *clean_path = xstrdup(storeHashDirSwapLogFile(sd, ".last-clean")); - char *new_path = xstrdup(storeHashDirSwapLogFile(sd, ".new")); - struct stat log_sb; - struct stat clean_sb; - FILE *fp; - int fd; - if (stat(swaplog_path, &log_sb) < 0) { - debug(47, 1) ("Cache Dir #%d: No log file\n", sd->index); - safe_free(swaplog_path); - safe_free(clean_path); - safe_free(new_path); - return NULL; - } - *zero_flag = log_sb.st_size == 0 ? 1 : 0; - /* close the existing write-only FD */ - if (hashinfo->swaplog_fd >= 0) - file_close(hashinfo->swaplog_fd); - /* open a write-only FD for the new log */ - fd = file_open(new_path, O_WRONLY | O_CREAT | O_TRUNC); - if (fd < 0) { - debug(50, 1) ("%s: %s\n", new_path, xstrerror()); - fatal("storeDirOpenTmpSwapLog: Failed to open swap log."); - } - hashinfo->swaplog_fd = fd; - /* open a read-only stream of the old log */ - fp = fopen(swaplog_path, "r"); - if (fp == NULL) { - debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror()); - fatal("Failed to open swap log for reading"); - } - memset(&clean_sb, '\0', sizeof(struct stat)); - if (stat(clean_path, &clean_sb) < 0) - *clean_flag = 0; - else if (clean_sb.st_mtime < log_sb.st_mtime) - *clean_flag = 0; - else - *clean_flag = 1; - safeunlink(clean_path, 1); - safe_free(swaplog_path); - safe_free(clean_path); - safe_free(new_path); - return fp; -} struct _clean_state { char *cur; @@ -939,180 +314,6 @@ RemovalPolicyWalker *walker; }; -#define CLEAN_BUF_SZ 16384 -/* - * Begin the process to write clean cache state. For HASH this means - * opening some log files and allocating write buffers. Return 0 if - * we succeed, and assign the 'func' and 'data' return pointers. - */ -static int -storeHashDirWriteCleanStart(SwapDir * sd) -{ - struct _clean_state *state = xcalloc(1, sizeof(*state)); - struct stat sb; - sd->log.clean.write = NULL; - sd->log.clean.state = NULL; - state->new = xstrdup(storeHashDirSwapLogFile(sd, ".clean")); - state->fd = file_open(state->new, O_WRONLY | O_CREAT | O_TRUNC); - if (state->fd < 0) { - xfree(state->new); - xfree(state); - return -1; - } - state->cur = xstrdup(storeHashDirSwapLogFile(sd, NULL)); - state->cln = xstrdup(storeHashDirSwapLogFile(sd, ".last-clean")); - state->outbuf = xcalloc(CLEAN_BUF_SZ, 1); - state->outbuf_offset = 0; - state->walker = sd->repl->WalkInit(sd->repl); - unlink(state->new); - unlink(state->cln); - debug(20, 3) ("storeDirWriteCleanLogs: opened %s, FD %d\n", - state->new, state->fd); -#if HAVE_FCHMOD - if (stat(state->cur, &sb) == 0) - fchmod(state->fd, sb.st_mode); -#endif - sd->log.clean.write = storeHashDirWriteCleanEntry; - sd->log.clean.state = state; - return 0; -} - -/* - * Get the next entry that is a candidate for clean log writing - */ -const StoreEntry * -storeHashDirCleanLogNextEntry(SwapDir * sd) -{ - const StoreEntry *entry = NULL; - struct _clean_state *state = sd->log.clean.state; - if (state->walker) - entry = state->walker->Next(state->walker); - return entry; -} - -/* - * "write" an entry to the clean log file. - */ -static void -storeHashDirWriteCleanEntry(SwapDir * sd, const StoreEntry * e) -{ - storeSwapLogData s; - static size_t ss = sizeof(storeSwapLogData); - struct _clean_state *state = sd->log.clean.state; - memset(&s, '\0', ss); - s.op = (char) SWAP_LOG_ADD; - s.swap_filen = e->swap_filen; - s.timestamp = e->timestamp; - s.lastref = e->lastref; - s.expires = e->expires; - s.lastmod = e->lastmod; - s.swap_file_sz = e->swap_file_sz; - s.refcount = e->refcount; - s.flags = e->flags; - xmemcpy(&s.key, e->hash.key, MD5_DIGEST_CHARS); - xmemcpy(state->outbuf + state->outbuf_offset, &s, ss); - state->outbuf_offset += ss; - /* buffered write */ - if (state->outbuf_offset + ss > CLEAN_BUF_SZ) { - if (write(state->fd, state->outbuf, state->outbuf_offset) < 0) { - debug(50, 0) ("storeDirWriteCleanLogs: %s: write: %s\n", - state->new, xstrerror()); - debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile not replaced.\n"); - file_close(state->fd); - state->fd = -1; - unlink(state->new); - safe_free(state); - sd->log.clean.state = NULL; - sd->log.clean.write = NULL; - } - state->outbuf_offset = 0; - } -} - -static void -storeHashDirWriteCleanDone(SwapDir * sd) -{ - struct _clean_state *state = sd->log.clean.state; - if (NULL == state) - return; - if (state->fd < 0) - return; - state->walker->Done(state->walker); - if (write(state->fd, state->outbuf, state->outbuf_offset) < 0) { - debug(50, 0) ("storeDirWriteCleanLogs: %s: write: %s\n", - state->new, xstrerror()); - debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile " - "not replaced.\n"); - file_close(state->fd); - state->fd = -1; - unlink(state->new); - } - safe_free(state->outbuf); - /* - * You can't rename open files on Microsoft "operating systems" - * so we have to close before renaming. - */ - storeHashDirCloseSwapLog(sd); - /* rename */ - if (state->fd >= 0) { -#ifdef _SQUID_OS2_ - file_close(state->fd); - state->fd = -1; - if (unlink(cur) < 0) - debug(50, 0) ("storeDirWriteCleanLogs: unlinkd failed: %s, %s\n", - xstrerror(), cur); -#endif - xrename(state->new, state->cur); - } - /* touch a timestamp file if we're not still validating */ - if (store_dirs_rebuilding) - (void) 0; - else if (state->fd < 0) - (void) 0; - else - file_close(file_open(state->cln, O_WRONLY | O_CREAT | O_TRUNC)); - /* close */ - safe_free(state->cur); - safe_free(state->new); - safe_free(state->cln); - if (state->fd >= 0) - file_close(state->fd); - state->fd = -1; - safe_free(state); - sd->log.clean.state = NULL; - sd->log.clean.write = NULL; -} - -static void -storeSwapLogDataFree(void *s) -{ - memFree(s, MEM_SWAP_LOG_DATA); -} - -static void -storeHashDirSwapLog(const SwapDir * sd, const StoreEntry * e, int op) -{ - hashinfo_t *hashinfo = (hashinfo_t *) sd->fsdata; - storeSwapLogData *s = memAllocate(MEM_SWAP_LOG_DATA); - s->op = (char) op; - s->swap_filen = e->swap_filen; - s->timestamp = e->timestamp; - s->lastref = e->lastref; - s->expires = e->expires; - s->lastmod = e->lastmod; - s->swap_file_sz = e->swap_file_sz; - s->refcount = e->refcount; - s->flags = e->flags; - xmemcpy(s->key, e->hash.key, MD5_DIGEST_CHARS); - file_write(hashinfo->swaplog_fd, - -1, - s, - sizeof(storeSwapLogData), - NULL, - NULL, - (FREE *) storeSwapLogDataFree); -} - static void storeHashDirNewfs(SwapDir * sd) { @@ -1121,219 +322,21 @@ storeHashDirCreateSwapSubDirs(sd); } -static int -rev_int_sort(const void *A, const void *B) -{ - const int *i1 = A; - const int *i2 = B; - return *i2 - *i1; -} - -static int -storeHashDirClean(int swap_index) -{ - DIR *dp = NULL; - struct dirent *de = NULL; - LOCAL_ARRAY(char, p1, MAXPATHLEN + 1); - LOCAL_ARRAY(char, p2, MAXPATHLEN + 1); -#if USE_TRUNCATE - struct stat sb; -#endif - int files[20]; - int swapfileno; - int fn; /* same as swapfileno, but with dirn bits set */ - int n = 0; - int k = 0; - int N0, N1, N2; - int D0, D1, D2; - SwapDir *SD; - hashinfo_t *hashinfo; - N0 = n_hash_dirs; - D0 = hash_dir_index[swap_index % N0]; - SD = &Config.cacheSwap.swapDirs[D0]; - hashinfo = (hashinfo_t *) SD->fsdata; - N1 = hashinfo->l1; - D1 = (swap_index / N0) % N1; - N2 = hashinfo->l2; - D2 = ((swap_index / N0) / N1) % N2; - snprintf(p1, SQUID_MAXPATHLEN, "%s/%02X/%02X", - Config.cacheSwap.swapDirs[D0].path, D1, D2); - debug(36, 3) ("storeDirClean: Cleaning directory %s\n", p1); - dp = opendir(p1); - if (dp == NULL) { - if (errno == ENOENT) { - debug(36, 0) ("storeDirClean: WARNING: Creating %s\n", p1); - if (mkdir(p1, 0777) == 0) - return 0; - } - debug(50, 0) ("storeDirClean: %s: %s\n", p1, xstrerror()); - safeunlink(p1, 1); - return 0; - } - while ((de = readdir(dp)) != NULL && k < 20) { - if (sscanf(de->d_name, "%X", &swapfileno) != 1) - continue; - fn = swapfileno; /* XXX should remove this cruft ! */ - if (storeHashDirValidFileno(SD, fn, 1)) - if (storeHashDirMapBitTest(SD, fn)) - if (storeHashFilenoBelongsHere(fn, D0, D1, D2)) - continue; -#if USE_TRUNCATE - if (!stat(de->d_name, &sb)) - if (sb.st_size == 0) - continue; -#endif - files[k++] = swapfileno; - } - closedir(dp); - if (k == 0) - return 0; - qsort(files, k, sizeof(int), rev_int_sort); - if (k > 10) - k = 10; - for (n = 0; n < k; n++) { - debug(36, 3) ("storeDirClean: Cleaning file %08X\n", files[n]); - snprintf(p2, MAXPATHLEN + 1, "%s/%08X", p1, files[n]); -#if USE_TRUNCATE - truncate(p2, 0); -#else - safeunlink(p2, 0); -#endif - statCounter.swap.files_cleaned++; - } - debug(36, 3) ("Cleaned %d unused files from %s\n", k, p1); - return k; -} - static void storeHashDirCleanEvent(void *unused) { - static int swap_index = 0; - int i; - int j = 0; - int n = 0; - /* - * Assert that there are HASH cache_dirs configured, otherwise - * we should never be called. - */ - assert(n_hash_dirs); - if (NULL == hash_dir_index) { - SwapDir *sd; - hashinfo_t *hashinfo; - /* - * Initialize the little array that translates HASH cache_dir - * number into the Config.cacheSwap.swapDirs array index. - */ - hash_dir_index = xcalloc(n_hash_dirs, sizeof(*hash_dir_index)); - for (i = 0, n = 0; i < Config.cacheSwap.n_configured; i++) { - sd = &Config.cacheSwap.swapDirs[i]; - if (!storeHashDirIs(sd)) - continue; - hash_dir_index[n++] = i; - hashinfo = (hashinfo_t *) sd->fsdata; - j += (hashinfo->l1 * hashinfo->l2); - } - assert(n == n_hash_dirs); - /* - * Start the storeHashDirClean() swap_index with a random - * value. j equals the total number of HASH level 2 - * swap directories - */ - swap_index = (int) (squid_random() % j); - } - if (0 == store_dirs_rebuilding) { - n = storeHashDirClean(swap_index); - swap_index++; - } + /* Empty for now */ +#if 0 eventAdd("storeDirClean", storeHashDirCleanEvent, NULL, 15.0 * exp(-0.25 * n), 1); -} - -static int -storeHashDirIs(SwapDir * sd) -{ - if (strncmp(sd->type, "hash", 3) == 0) - return 1; - return 0; -} - -/* - * Does swapfile number 'fn' belong in cachedir #F0, - * level1 dir #F1, level2 dir #F2? - */ -static int -storeHashFilenoBelongsHere(int fn, int F0, int F1, int F2) -{ - int D1, D2; - int L1, L2; - int filn = fn; - hashinfo_t *hashinfo; - assert(F0 < Config.cacheSwap.n_configured); - hashinfo = (hashinfo_t *) Config.cacheSwap.swapDirs[F0].fsdata; - L1 = hashinfo->l1; - L2 = hashinfo->l2; - D1 = ((filn / L2) / L2) % L1; - if (F1 != D1) - return 0; - D2 = (filn / L2) % L2; - if (F2 != D2) - return 0; - return 1; -} - -int -storeHashDirValidFileno(SwapDir * SD, sfileno filn, int flag) -{ - hashinfo_t *hashinfo = (hashinfo_t *) SD->fsdata; - if (filn < 0) - return 0; - /* - * If flag is set it means out-of-range file number should - * be considered invalid. - */ - if (flag) - if (filn > hashinfo->map->max_n_files) - return 0; - return 1; +#endif } void storeHashDirMaintain(SwapDir * SD) { - StoreEntry *e = NULL; - int removed = 0; - int max_scan; - int max_remove; - double f; - RemovalPurgeWalker *walker; - /* We can't delete objects while rebuilding swap */ - if (store_dirs_rebuilding) { - return; - } else { - f = (double) (SD->cur_size - SD->low_size) / (SD->max_size - SD->low_size); - f = f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f; - max_scan = (int) (f * 400.0 + 100.0); - max_remove = (int) (f * 70.0 + 10.0); - /* - * This is kinda cheap, but so we need this priority hack? - */ - } - debug(20, 3) ("storeMaintainSwapSpace: f=%f, max_scan=%d, max_remove=%d\n", f, max_scan, max_remove); - walker = SD->repl->PurgeInit(SD->repl, max_scan); - while (1) { - if (SD->cur_size < SD->low_size) - break; - if (removed >= max_remove) - break; - e = walker->Next(walker); - if (!e) - break; /* no more objects */ - removed++; - storeRelease(e); - } - walker->Done(walker); - debug(20, (removed ? 2 : 3)) ("storeHashDirMaintain: %s removed %d/%d f=%.03f max_scan=%d\n", - SD->path, removed, max_remove, f, max_scan); + /* Do nothing for now */ + return; } /* @@ -1659,18 +662,18 @@ sd->unrefobj = storeHashDirUnrefObj; sd->callback = NULL; sd->sync = NULL; - sd->obj.create = storeHashCreate; - sd->obj.open = storeHashOpen; + + sd->obj.get = storeHashGet; sd->obj.close = storeHashClose; sd->obj.read = storeHashRead; sd->obj.write = storeHashWrite; sd->obj.unlink = storeHashUnlink; - sd->log.open = storeHashDirOpenSwapLog; - sd->log.close = storeHashDirCloseSwapLog; - sd->log.write = storeHashDirSwapLog; - sd->log.clean.start = storeHashDirWriteCleanStart; - sd->log.clean.nextentry = storeHashDirCleanLogNextEntry; - sd->log.clean.done = storeHashDirWriteCleanDone; + sd->log.open = NULL; + sd->log.close = NULL; + sd->log.write = NULL; + sd->log.clean.start = NULL; + sd->log.clean.nextentry = NULL; + sd->log.clean.done = NULL; /* Initialise replacement policy stuff */ sd->repl = createRemovalPolicy(Config.replPolicy); Index: squid/src/fs/hash/store_hash.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/fs/hash/Attic/store_hash.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- squid/src/fs/hash/store_hash.h 16 Dec 2000 09:29:03 -0000 1.1.2.1 +++ squid/src/fs/hash/store_hash.h 5 Jan 2001 14:28:22 -0000 1.1.2.2 @@ -40,8 +40,7 @@ /* * Store IO stuff */ -extern STOBJCREATE storeHashCreate; -extern STOBJOPEN storeHashOpen; +extern STOBJGET storeHashGet; extern STOBJCLOSE storeHashClose; extern STOBJREAD storeHashRead; extern STOBJWRITE storeHashWrite; Index: squid/src/fs/hash/store_io_hash.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/fs/hash/Attic/store_io_hash.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- squid/src/fs/hash/store_io_hash.c 16 Dec 2000 09:29:03 -0000 1.1.2.1 +++ squid/src/fs/hash/store_io_hash.c 5 Jan 2001 14:28:22 -0000 1.1.2.2 @@ -1,6 +1,6 @@ /* - * $Id: store_io_hash.c,v 1.1.2.1 2000/12/16 09:29:03 adri Exp $ + * $Id: store_io_hash.c,v 1.1.2.2 2001/01/05 14:28:22 adri Exp $ * * DEBUG: section 79 Storage Manager HASH Interface * AUTHOR: Duane Wessels @@ -44,6 +44,14 @@ /* === PUBLIC =========================================================== */ +void +storeHashGet(SwapDir *sd, const char *uri, const method_t method, + STGETDONE *callback, void *callback_data) +{ + /* Empty for now , return NULL */ + callback(callback_data, NULL); +} + storeIOState * storeHashOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * callback, void *callback_data)