📄 store_dir_coss.c
字号:
storeAppendPrintf(sentry, "dead_stripes: %d\n", coss_stats.dead_stripes); storeAppendPrintf(sentry, "alloc.alloc: %d\n", coss_stats.alloc.alloc); storeAppendPrintf(sentry, "alloc.realloc: %d\n", coss_stats.alloc.realloc); storeAppendPrintf(sentry, "alloc.memalloc: %d\n", coss_stats.alloc.memalloc); storeAppendPrintf(sentry, "alloc.collisions: %d\n", coss_stats.alloc.collisions); storeAppendPrintf(sentry, "disk_overflows: %d\n", coss_stats.disk_overflows); storeAppendPrintf(sentry, "stripe_overflows: %d\n", coss_stats.stripe_overflows); storeAppendPrintf(sentry, "open_mem_hits: %d\n", coss_stats.open_mem_hits); storeAppendPrintf(sentry, "open_mem_misses: %d\n", coss_stats.open_mem_misses);}voidstoreFsSetup_coss(storefs_entry_t * storefs){ assert(!coss_initialised); storefs->parsefunc = storeCossDirParse; storefs->reconfigurefunc = storeCossDirReconfigure; storefs->donefunc = storeCossDirDone; coss_state_pool = memPoolCreate("COSS IO State data", sizeof(CossState)); coss_index_pool = memPoolCreate("COSS index data", sizeof(CossIndexNode)); coss_realloc_pool = memPoolCreate("COSS pending realloc", sizeof(CossPendingReloc)); coss_op_pool = memPoolCreate("COSS pending operation", sizeof(CossReadOp)); cachemgrRegister(SWAPDIR_COSS, "COSS Stats", storeCossStats, 0, 1); coss_initialised = 1;}/* New storedir rebuilding code! */static void storeDirCoss_ReadStripe(RebuildState * rb);static void storeDirCoss_ParseStripeBuffer(RebuildState * rb);static void storeCoss_ConsiderStoreEntry(RebuildState * rb, const cache_key * key, StoreEntry * e);#if USE_AUFSOPSstatic voidstoreDirCoss_ReadStripeComplete(int fd, void *my_data, const char *buf, int aio_return, int aio_errno)#elsestatic voidstoreDirCoss_ReadStripeComplete(int fd, const char *buf, int r_len, int r_errflag, void *my_data)#endif{ RebuildState *rb = my_data; SwapDir *SD = rb->sd; CossInfo *cs = SD->fsdata;#if USE_AUFSOPS int r_errflag; int r_len; r_len = aio_return; if (aio_errno) r_errflag = aio_errno == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR; else r_errflag = DISK_OK; xmemcpy(cs->rebuild.buf, buf, r_len);#endif debug(47, 2) ("COSS: %s: stripe %d, read %d bytes, status %d\n", stripePath(SD), cs->rebuild.curstripe, r_len, r_errflag); cs->rebuild.reading = 0; if (r_errflag != DISK_OK) { debug(47, 2) ("COSS: %s: stripe %d: error! Ignoring objects in this stripe.\n", stripePath(SD), cs->rebuild.curstripe); goto nextstripe; } cs->rebuild.buflen = r_len; /* parse the stripe contents */ /* * XXX note: the read should be put before the parsing so they can happen * simultaneously. This'll require some code-shifting so the read buffer * and parse buffer are different. This might speed up the read speed; * the disk throughput isn't being reached at the present. */ storeDirCoss_ParseStripeBuffer(rb); nextstripe: cs->rebuild.curstripe++; if (cs->rebuild.curstripe >= cs->numstripes) { /* Completed the rebuild - move onto the next phase */ debug(47, 2) ("COSS: %s: completed reading the stripes.\n", stripePath(SD)); storeCossRebuildComplete(rb); return; } else { /* Next stripe */ storeDirCoss_ReadStripe(rb); }}static voidstoreDirCoss_ReadStripe(RebuildState * rb){ SwapDir *SD = rb->sd; CossInfo *cs = SD->fsdata; assert(cs->rebuild.reading == 0); cs->rebuild.reading = 1; /* Use POSIX AIO for now */ debug(47, 2) ("COSS: %s: reading stripe %d\n", stripePath(SD), cs->rebuild.curstripe); if (cs->rebuild.curstripe > rb->report_current) { debug(47, 1) ("COSS: %s: Rebuilding (%d %% completed - %d/%d stripes)\n", stripePath(SD), cs->rebuild.curstripe * 100 / cs->numstripes, cs->rebuild.curstripe, cs->numstripes); rb->report_current += rb->report_interval; }#if USE_AUFSOPS /* XXX this should be a prime candidate to use a modified aioRead which doesn't malloc a damned buffer */ aioRead(cs->fd, (off_t) cs->rebuild.curstripe * COSS_MEMBUF_SZ, COSS_MEMBUF_SZ, storeDirCoss_ReadStripeComplete, rb);#else a_file_read(&cs->aq, cs->fd, cs->rebuild.buf, COSS_MEMBUF_SZ, (off_t) cs->rebuild.curstripe * COSS_MEMBUF_SZ, storeDirCoss_ReadStripeComplete, rb);#endif}static voidstoreDirCoss_StartDiskRebuild(RebuildState * rb){ SwapDir *SD = rb->sd; CossInfo *cs = SD->fsdata; assert(cs->rebuild.rebuilding == 0); assert(cs->numstripes > 0); assert(cs->rebuild.buf == NULL); assert(cs->fd >= 0); cs->rebuild.rebuilding = 1; cs->rebuild.curstripe = 0; cs->rebuild.buf = xmalloc(COSS_MEMBUF_SZ); rb->report_interval = cs->numstripes / COSS_REPORT_INTERVAL; rb->report_current = 0; debug(47, 2) ("COSS: %s: Beginning disk rebuild.\n", stripePath(SD)); storeDirCoss_ReadStripe(rb);}/* * Take a stripe and attempt to place objects into it */static voidstoreDirCoss_ParseStripeBuffer(RebuildState * rb){ SwapDir *SD = rb->sd; CossInfo *cs = SD->fsdata; tlv *t, *tlv_list; int j = 0; int bl = 0; int tmp; squid_off_t *l, len; int blocksize = cs->blksz_mask + 1; StoreEntry tmpe; cache_key key[MD5_DIGEST_CHARS]; sfileno filen; assert(cs->rebuild.rebuilding == 1); assert(cs->numstripes > 0); assert(cs->rebuild.buf != NULL); if (cs->rebuild.buflen == 0) { debug(47, 3) ("COSS: %s: stripe %d: read 0 bytes, skipping stripe\n", stripePath(SD), cs->rebuild.curstripe); return; } while (j < cs->rebuild.buflen) { l = NULL; bl = 0; /* XXX there's no bounds checking on the buffer being passed into storeSwapMetaUnpack! */ tlv_list = storeSwapMetaUnpack(cs->rebuild.buf + j, &bl); if (tlv_list == NULL) { debug(47, 3) ("COSS: %s: stripe %d: offset %d gives NULL swapmeta data; end of stripe\n", stripePath(SD), cs->rebuild.curstripe, j); return; } filen = (off_t) j / (off_t) blocksize + (off_t) ((off_t) cs->rebuild.curstripe * (off_t) COSS_MEMBUF_SZ / (off_t) blocksize); debug(47, 3) ("COSS: %s: stripe %d: filen %d: header size %d\n", stripePath(SD), cs->rebuild.curstripe, filen, bl); /* COSS objects will have an object size written into the metadata */ memset(&tmpe, 0, sizeof(tmpe)); memset(key, 0, sizeof(key)); for (t = tlv_list; t; t = t->next) { switch (t->type) { case STORE_META_URL: debug(47, 3) (" URL: %s\n", (char *) t->value); break; case STORE_META_OBJSIZE: l = t->value; debug(47, 3) ("Size: %" PRINTF_OFF_T " (len %d)\n", *l, t->length); break; case STORE_META_KEY: assert(t->length == MD5_DIGEST_CHARS); xmemcpy(key, t->value, MD5_DIGEST_CHARS); break;#if SIZEOF_SQUID_FILE_SZ == SIZEOF_SIZE_T case STORE_META_STD: assert(t->length == STORE_HDR_METASIZE); xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE); break;#else case STORE_META_STD_LFS: assert(t->length == STORE_HDR_METASIZE); xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE); break; case STORE_META_STD: assert(t->length == STORE_HDR_METASIZE_OLD); { struct { time_t timestamp; time_t lastref; time_t expires; time_t lastmod; size_t swap_file_sz; u_short refcount; u_short flags; } *tmp = t->value; assert(sizeof(*tmp) == STORE_HDR_METASIZE_OLD); tmpe.timestamp = tmp->timestamp; tmpe.lastref = tmp->lastref; tmpe.expires = tmp->expires; tmpe.lastmod = tmp->lastmod; tmpe.swap_file_sz = tmp->swap_file_sz; tmpe.refcount = tmp->refcount; tmpe.flags = tmp->flags; } break;#endif } } /* Make sure we have an object; if we don't then it may be an indication of trouble */ if (l == NULL) { debug(47, 3) ("COSS: %s: stripe %d: Object with no size; end of stripe\n", stripePath(SD), cs->rebuild.curstripe); storeSwapTLVFree(tlv_list); return; } len = *l; /* Finally, make sure there's enough data left in this stripe to satisfy the object * we've just been informed about */ if ((cs->rebuild.buflen - j) < (len + bl)) { debug(47, 3) ("COSS: %s: stripe %d: Not enough data in this stripe for this object, bye bye.\n", stripePath(SD), cs->rebuild.curstripe); storeSwapTLVFree(tlv_list); return; } /* Houston, we have an object */ if (storeKeyNull(key)) { debug(47, 3) ("COSS: %s: stripe %d: null data, next!\n", stripePath(SD), cs->rebuild.curstripe); goto nextobject; } rb->counts.scancount++; tmpe.hash.key = key; /* Check sizes */ if (tmpe.swap_file_sz == 0) { tmpe.swap_file_sz = len + bl; } if (tmpe.swap_file_sz != (len + bl)) { debug(47, 3) ("COSS: %s: stripe %d: file size mismatch (%" PRINTF_OFF_T " != %" PRINTF_OFF_T ")\n", stripePath(SD), cs->rebuild.curstripe, tmpe.swap_file_sz, len); goto nextobject; } if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) { debug(47, 3) ("COSS: %s: stripe %d: private key flag set, ignoring.\n", stripePath(SD), cs->rebuild.curstripe); rb->counts.badflags++; goto nextobject; } /* Time to consider the object! */ tmpe.swap_filen = filen; tmpe.swap_dirn = SD->index; debug(47, 3) ("COSS: %s Considering filneumber %d\n", stripePath(SD), tmpe.swap_filen); storeCoss_ConsiderStoreEntry(rb, key, &tmpe); nextobject: /* Free the TLV data */ storeSwapTLVFree(tlv_list); tlv_list = NULL; /* Now, advance to the next block-aligned offset after this object */ j = j + len + bl; /* And now, the blocksize! */ tmp = j / blocksize; tmp = (tmp + 1) * blocksize; j = tmp; }}static voidstoreCoss_AddStoreEntry(RebuildState * rb, const cache_key * key, StoreEntry * e){ StoreEntry *ne; SwapDir *SD = rb->sd; CossInfo *cs = SD->fsdata; rb->counts.objcount++; /* The Passed-in store entry is temporary; don't bloody use it directly! */ assert(e->swap_dirn == SD->index); ne = new_StoreEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL); ne->store_status = STORE_OK; storeSetMemStatus(ne, NOT_IN_MEMORY); ne->swap_status = SWAPOUT_DONE; ne->swap_filen = e->swap_filen; ne->swap_dirn = SD->index; ne->swap_file_sz = e->swap_file_sz; ne->lock_count = 0; ne->lastref = e->lastref; ne->timestamp = e->timestamp; ne->expires = e->expires; ne->lastmod = e->lastmod; ne->refcount = e->refcount; ne->flags = e->flags; EBIT_SET(ne->flags, ENTRY_CACHABLE); EBIT_CLR(ne->flags, RELEASE_REQUEST); EBIT_CLR(ne->flags, KEY_PRIVATE); ne->ping_status = PING_NONE; EBIT_CLR(ne->flags, ENTRY_VALIDATED); storeHashInsert(ne, key); /* do it after we clear KEY_PRIVATE */ storeCossAdd(SD, ne, cs->rebuild.curstripe); storeEntryDump(ne, 5); assert(ne->repl.data != NULL); assert(e->repl.data == NULL);}static voidstoreCoss_DeleteStoreEntry(RebuildState * rb, const cache_key * key, StoreEntry * e){ assert(rb->counts.objcount >= 0); /* XXX are these counters even correct, considering e could be a different storedir? */ rb->counts.objcount--; assert(e->swap_dirn >= 0); storeRecycle(e);}/* * Consider inserting the given StoreEntry into the given * COSS directory. * * The rules for doing this is reasonably simple: * * If the object doesn't exist in the cache then we simply * add it to the current stripe list * * If the object does exist in the cache then we compare * "freshness"; if the newer object is fresher then we * remove it from its stripe and re-add it to the current * stripe. */static voidstoreCoss_ConsiderStoreEntry(RebuildState * rb, const cache_key * key, StoreEntry * e){ StoreEntry *oe; /* Check for clashes */ oe = storeGet(key); if (oe == NULL) { rb->cosscounts.new++; debug(47, 3) ("COSS: Adding filen %d\n", e->swap_filen); /* no clash! woo, can add and forget */ storeCoss_AddStoreEntry(rb, key, e); return; } /* This isn't valid - its possible we have a fresher object in another store */ /* unlike the UFS-based stores we don't "delete" the disk object when we * have deleted the object; its one of the annoying things about COSS. */ //assert(oe->swap_dirn == SD->index); /* Dang, its a clash. See if its fresher */ /* Fresher? Its a new object: deallocate the old one, reallocate the new one */ if (e->lastref > oe->lastref) { debug(47, 3) ("COSS: fresher object for filen %d found (%ld -> %ld)\n", oe->swap_filen, (long int) oe->timestamp, (long int) e->timestamp); rb->cosscounts.fresher++; storeCoss_DeleteStoreEntry(rb, key, oe); oe = NULL; storeCoss_AddStoreEntry(rb, key, e); return; } /* * Not fresher? Its the same object then we /should/ probably relocate it; I'm * not sure what should be done here. */ if (oe->timestamp == e->timestamp && oe->expires == e->expires) { debug(47, 3) ("COSS: filen %d -> %d (since they're the same!)\n", oe->swap_filen, e->swap_filen); rb->cosscounts.reloc++; storeCoss_DeleteStoreEntry(rb, key, oe); oe = NULL; storeCoss_AddStoreEntry(rb, key, e); return; } debug(47, 3) ("COSS: filen %d: ignoring this one for some reason\n", e->swap_filen); rb->cosscounts.unknown++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -