📄 store_dir_coss.c
字号:
*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; char *new; char *cln; char *outbuf; int outbuf_offset; int fd; dlink_node *current;};#define CLEAN_BUF_SZ 16384/* * Begin the process to write clean cache state. For COSS this means * opening some log files and allocating write buffers. Return 0 if * we succeed, and assign the 'func' and 'data' return pointers. */static intstoreCossDirWriteCleanStart(SwapDir * sd){ //CossInfo *cs = (CossInfo *) sd->fsdata; struct _clean_state *state = xcalloc(1, sizeof(*state));#if HAVE_FCHMOD struct stat sb;#endif state->new = xstrdup(storeCossDirSwapLogFile(sd, ".clean")); state->fd = file_open(state->new, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY); if (state->fd < 0) { xfree(state->new); xfree(state); return -1; } sd->log.clean.write = NULL; sd->log.clean.state = NULL; state->cur = xstrdup(storeCossDirSwapLogFile(sd, NULL)); state->cln = xstrdup(storeCossDirSwapLogFile(sd, ".last-clean")); state->outbuf = xcalloc(CLEAN_BUF_SZ, 1); state->outbuf_offset = 0; unlink(state->cln); debug(20, 3) ("storeCOssDirWriteCleanLogs: 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 = storeCossDirWriteCleanEntry; sd->log.clean.state = state; return 0;}static const StoreEntry *storeCossDirCleanLogNextEntry(SwapDir * sd){ struct _clean_state *state = sd->log.clean.state; const StoreEntry *entry; if (!state) return NULL; if (!state->current) return NULL; entry = (const StoreEntry *) state->current->data; state->current = state->current->prev; return entry;}/* * "write" an entry to the clean log file. */static voidstoreCossDirWriteCleanEntry(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 (FD_WRITE_METHOD(state->fd, state->outbuf, state->outbuf_offset) < 0) { debug(50, 0) ("storeCossDirWriteCleanLogs: %s: write: %s\n", state->new, xstrerror()); debug(20, 0) ("storeCossDirWriteCleanLogs: 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; return; } state->outbuf_offset = 0; }}static voidstoreCossDirWriteCleanDone(SwapDir * sd){ struct _clean_state *state = sd->log.clean.state; if (NULL == state) return; if (state->fd < 0) return; if (FD_WRITE_METHOD(state->fd, state->outbuf, state->outbuf_offset) < 0) { debug(50, 0) ("storeCossDirWriteCleanLogs: %s: write: %s\n", state->new, xstrerror()); debug(20, 0) ("storeCossDirWriteCleanLogs: 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. */ storeCossDirCloseSwapLog(sd); /* rename */ if (state->fd >= 0) {#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_) file_close(state->fd); state->fd = -1;#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 | O_BINARY)); /* 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 voidstoreSwapLogDataFree(void *s){ memFree(s, MEM_SWAP_LOG_DATA);}static voidstoreCossDirSwapLog(const SwapDir * sd, const StoreEntry * e, int op){ CossInfo *cs = (CossInfo *) 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(cs->swaplog_fd, -1, s, sizeof(storeSwapLogData), NULL, NULL, (FREE *) storeSwapLogDataFree);}static voidstoreCossCreateStripe(SwapDir * SD, const char *path){ char *block; int swap; int i; CossInfo *cs = (CossInfo *) SD->fsdata; debug(47, 1) ("Creating COSS stripe %s\n", path); swap = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600); block = (char *) xcalloc(COSS_MEMBUF_SZ, 1); for (i = 0; i < cs->numstripes; ++i) { if (write(swap, block, COSS_MEMBUF_SZ) < COSS_MEMBUF_SZ) { fatalf("Failed to create COSS stripe %s\n", path); } } close(swap); xfree(block);}static voidstoreCossDirNewfs(SwapDir * SD){ struct stat st; if (stat(SD->path, &st) == 0) { if (S_ISDIR(st.st_mode)) { if (stat(stripePath(SD), &st) != 0) storeCossCreateStripe(SD, stripePath(SD)); } } else storeCossCreateStripe(SD, (const char *) SD->path);}/* * Only "free" the filesystem specific stuff here */static voidstoreCossDirFree(SwapDir * SD){ CossInfo *cs = (CossInfo *) SD->fsdata; if (cs->swaplog_fd > -1) { file_close(cs->swaplog_fd); cs->swaplog_fd = -1; } xfree(cs->stripes); xfree(cs->memstripes); xfree(cs); SD->fsdata = NULL; /* Will aid debugging... */}/* we are shutting down, flush all membufs to disk */static voidstoreCossDirShutdown(SwapDir * SD){ CossInfo *cs = (CossInfo *) SD->fsdata; debug(47, 1) ("COSS: %s: syncing\n", stripePath(SD)); storeCossSync(SD); /* This'll call a_file_syncqueue() or a aioSync() */#if !USE_AUFSOPS a_file_closequeue(&cs->aq);#endif file_close(cs->fd); cs->fd = -1; xfree((void *) cs->stripe_path); if (cs->swaplog_fd > -1) { file_close(cs->swaplog_fd); cs->swaplog_fd = -1; } n_coss_dirs--;}/* * storeCossDirCheckObj * * This routine is called by storeDirSelectSwapDir to see if the given * object is able to be stored on this filesystem. COSS filesystems will * not store everything. We don't check for maxobjsize here since its * done by the upper layers. */intstoreCossDirCheckObj(SwapDir * SD, const StoreEntry * e){ CossInfo *cs = SD->fsdata; int objsize = objectLen(e) + e->mem_obj->swap_hdr_sz; /* Check if the object is a special object, we can't cache these */ if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) return 0; if (cs->rebuild.rebuilding == 1) return 0; /* Check to see if the object is going to waste too much disk space */ if (objsize > cs->sizerange_max) return 0; return 1;}intstoreCossDirCheckLoadAv(SwapDir * SD, store_op_t op){ CossInfo *cs = (CossInfo *) SD->fsdata;#if USE_AUFSOPS float disk_size_weight, current_write_weight; int cur_load_interval = (squid_curtime / cs->load_interval) % 2; int ql = 0;#endif int loadav; /* Return load, cs->aq.aq_numpending out of MAX_ASYNCOP */#if USE_AUFSOPS ql = aioQueueSize(); if (ql == 0) loadav = COSS_LOAD_BASE; else loadav = COSS_LOAD_BASE + (ql * COSS_LOAD_QUEUE_WEIGHT / MAGIC1); /* We want to try an keep the disks at a similar write rate * otherwise the LRU algorithm breaks * * The queue length has a 10% weight on the load * The number of stripes written has a 90% weight */ disk_size_weight = (float) max_coss_dir_size / SD->max_size; current_write_weight = (float) cs->loadcalc[cur_load_interval] * COSS_LOAD_STRIPE_WEIGHT / MAX_LOAD_VALUE; loadav += disk_size_weight * current_write_weight; /* Remove the folowing check if we want to allow COSS partitions to get * too busy to accept new objects */ if (loadav > MAX_LOAD_VALUE) loadav = MAX_LOAD_VALUE; /* Finally, we want to reject all new obects if the number of full stripes * is too large */ if (cs->numfullstripes > cs->hitonlyfullstripes) loadav += MAX_LOAD_VALUE; debug(47, 9) ("storeAufsDirCheckObj: load=%d\n", loadav); return loadav;#else loadav = cs->aq.aq_numpending * MAX_LOAD_VALUE / MAX_ASYNCOP; return loadav;#endif}/* * storeCossDirCallback - do the IO completions */static intstoreCossDirCallback(SwapDir * SD){ CossInfo *cs = (CossInfo *) SD->fsdata; storeCossFreeDeadMemBufs(cs);#if USE_AUFSOPS /* I believe this call, at the present, checks all callbacks for all SDs, not just ours */ return aioCheckCallbacks(SD);#else return a_file_callback(&cs->aq);#endif}/* ========== LOCAL FUNCTIONS ABOVE, GLOBAL FUNCTIONS BELOW ========== */static voidstoreCossDirStats(SwapDir * SD, StoreEntry * sentry){ CossInfo *cs = (CossInfo *) SD->fsdata; storeAppendPrintf(sentry, "\n"); storeAppendPrintf(sentry, "Maximum Size: %d KB\n", SD->max_size); storeAppendPrintf(sentry, "Current Size: %d KB\n", SD->cur_size); storeAppendPrintf(sentry, "Percent Used: %0.2f%%\n", 100.0 * SD->cur_size / SD->max_size); storeAppendPrintf(sentry, "Current load metric: %d / %d\n", storeCossDirCheckLoadAv(SD, ST_OP_CREATE), MAX_LOAD_VALUE); storeAppendPrintf(sentry, "Number of object collisions: %d\n", (int) cs->numcollisions);#if 0 /* is this applicable? I Hope not .. */ storeAppendPrintf(sentry, "Filemap bits in use: %d of %d (%d%%)\n", SD->map->n_files_in_map, SD->map->max_n_files,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -