📄 store_dir_aufs.c
字号:
* value. j equals the total number of AUFS level 2 * swap directories */ for (n = 0; n < n_asyncufs_dirs; n++) { sd = &Config.cacheSwap.swapDirs[asyncufs_dir_index[n]]; aioinfo = (squidaioinfo_t *) sd->fsdata; j += (aioinfo->l1 * aioinfo->l2); } swap_index = (int) (squid_random() % j); } if (0 == store_dirs_rebuilding) { n = storeAufsDirClean(swap_index); swap_index++; if (swap_index < 0) swap_index = 0; } eventAdd("storeDirClean", storeAufsDirCleanEvent, NULL, 15.0 * exp(-0.25 * n), 1);}/* * Does swapfile number 'fn' belong in cachedir #F0, * level1 dir #F1, level2 dir #F2? */static intstoreAufsFilenoBelongsHere(int fn, int F0, int F1, int F2){ int D1, D2; int L1, L2; int filn = fn; squidaioinfo_t *aioinfo; assert(F0 < Config.cacheSwap.n_configured); aioinfo = (squidaioinfo_t *) Config.cacheSwap.swapDirs[F0].fsdata; L1 = aioinfo->l1; L2 = aioinfo->l2; D1 = ((filn / L2) / L2) % L1; if (F1 != D1) return 0; D2 = (filn / L2) % L2; if (F2 != D2) return 0; return 1;}intstoreAufsDirValidFileno(SwapDir * SD, sfileno filn, int flag){ squidaioinfo_t *aioinfo = (squidaioinfo_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 > aioinfo->map->max_n_files) return 0; return 1;}voidstoreAufsDirMaintain(SwapDir * SD){ squidaioinfo_t *aioinfo = (squidaioinfo_t *) SD->fsdata; 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(47, 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 && aioinfo->map->n_files_in_map < FILEMAP_MAX) break; if (removed >= max_remove) break; e = walker->Next(walker); if (!e) break; /* no more objects */ removed++; storeRelease(e); } walker->Done(walker); debug(47, (removed ? 2 : 3)) ("storeAufsDirMaintain: %s removed %d/%d f=%.03f max_scan=%d\n", SD->path, removed, max_remove, f, max_scan);}/* * storeAufsDirCheckObj * * This routine is called by storeDirSelectSwapDir to see if the given * object is able to be stored on this filesystem. AUFS filesystems will * happily store anything as long as the LRU time isn't too small. */intstoreAufsDirCheckObj(SwapDir * SD, const StoreEntry * e){ return 1;}intstoreAufsDirCheckLoadAv(SwapDir * SD, store_op_t op){ int loadav, ql; ql = aioQueueSize(); if (ql == 0) { return AUFS_LOAD_BASE; } loadav = AUFS_LOAD_BASE + (ql * AUFS_LOAD_QUEUE_WEIGHT / MAGIC1); return loadav;}/* * storeAufsDirRefObj * * This routine is called whenever an object is referenced, so we can * maintain replacement information within the storage fs. */voidstoreAufsDirRefObj(SwapDir * SD, StoreEntry * e){ debug(47, 3) ("storeAufsDirRefObj: referencing %p %d/%d\n", e, e->swap_dirn, e->swap_filen); if (SD->repl->Referenced) SD->repl->Referenced(SD->repl, e, &e->repl);}/* * storeAufsDirUnrefObj * This routine is called whenever the last reference to an object is * removed, to maintain replacement information within the storage fs. */voidstoreAufsDirUnrefObj(SwapDir * SD, StoreEntry * e){ debug(47, 3) ("storeAufsDirUnrefObj: referencing %p %d/%d\n", e, e->swap_dirn, e->swap_filen); if (SD->repl->Dereferenced) SD->repl->Dereferenced(SD->repl, e, &e->repl);}/* * storeAufsDirUnlinkFile * * This routine unlinks a file and pulls it out of the bitmap. * It used to be in storeAufsUnlink(), however an interface change * forced this bit of code here. Eeek. */voidstoreAufsDirUnlinkFile(SwapDir * SD, sfileno f){ debug(79, 3) ("storeAufsDirUnlinkFile: unlinking fileno %08X\n", f); /* storeAufsDirMapBitReset(SD, f); */#if USE_TRUNCATE aioTruncate(storeAufsDirFullPath(SD, f, NULL), NULL, NULL);#else aioUnlink(storeAufsDirFullPath(SD, f, NULL), NULL, NULL);#endif}/* * Add and remove the given StoreEntry from the replacement policy in * use. */voidstoreAufsDirReplAdd(SwapDir * SD, StoreEntry * e){ debug(47, 4) ("storeAufsDirReplAdd: added node %p to dir %d\n", e, SD->index); SD->repl->Add(SD->repl, e, &e->repl);}voidstoreAufsDirReplRemove(StoreEntry * e){ SwapDir *SD = INDEXSD(e->swap_dirn); debug(47, 4) ("storeAufsDirReplRemove: remove node %p from dir %d\n", e, SD->index); SD->repl->Remove(SD->repl, e, &e->repl);}/* ========== LOCAL FUNCTIONS ABOVE, GLOBAL FUNCTIONS BELOW ========== */voidstoreAufsDirStats(SwapDir * SD, StoreEntry * sentry){ squidaioinfo_t *aioinfo = SD->fsdata;#ifdef HAVE_STATVFS fsblkcnt_t totl_kb; fsblkcnt_t free_kb; fsfilcnt_t totl_in; fsfilcnt_t free_in;#else int totl_kb = 0; int free_kb = 0; int totl_in = 0; int free_in = 0;#endif int x; storeAppendPrintf(sentry, "First level subdirectories: %d\n", aioinfo->l1); storeAppendPrintf(sentry, "Second level subdirectories: %d\n", aioinfo->l2); 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", storeAufsDirCheckLoadAv(SD, ST_OP_CREATE), MAX_LOAD_VALUE); storeAppendPrintf(sentry, "Filemap bits in use: %d of %d (%d%%)\n", aioinfo->map->n_files_in_map, aioinfo->map->max_n_files, percent(aioinfo->map->n_files_in_map, aioinfo->map->max_n_files)); x = storeDirGetUFSStats(SD->path, &totl_kb, &free_kb, &totl_in, &free_in); if (0 == x) {#ifdef HAVE_STATVFS storeAppendPrintf(sentry, "Filesystem Space in use: %" PRIu64 "/%" PRIu64 " KB (%.0f%%)\n", (uint64_t) (totl_kb - free_kb), (uint64_t) totl_kb, dpercent(totl_kb - free_kb, totl_kb)); storeAppendPrintf(sentry, "Filesystem Inodes in use: %" PRIu64 "/%" PRIu64 " (%.0f%%)\n", (uint64_t) (totl_in - free_in), (uint64_t) totl_in, dpercent(totl_in - free_in, totl_in));#else storeAppendPrintf(sentry, "Filesystem Space in use: %d/%d KB (%d%%)\n", totl_kb - free_kb, totl_kb, percent(totl_kb - free_kb, totl_kb)); storeAppendPrintf(sentry, "Filesystem Inodes in use: %d/%d (%d%%)\n", totl_in - free_in, totl_in, percent(totl_in - free_in, totl_in));#endif } storeAppendPrintf(sentry, "Flags:"); if (SD->flags.selected) storeAppendPrintf(sentry, " SELECTED"); if (SD->flags.read_only) storeAppendPrintf(sentry, " READ-ONLY"); storeAppendPrintf(sentry, "\n");}static struct cache_dir_option options[] ={#if NOT_YET_DONE {"L1", storeAufsDirParseL1, storeAufsDirDumpL1}, {"L2", storeAufsDirParseL2, storeAufsDirDumpL2},#endif {NULL, NULL}};/* * storeAufsDirReconfigure * * This routine is called when the given swapdir needs reconfiguring */static voidstoreAufsDirReconfigure(SwapDir * sd, int index, char *path){ int i; int size; int l1; int l2; i = GetInteger(); size = i << 10; /* Mbytes to kbytes */ if (size <= 0) fatal("storeAufsDirReconfigure: invalid size value"); i = GetInteger(); l1 = i; if (l1 <= 0) fatal("storeAufsDirReconfigure: invalid level 1 directories value"); i = GetInteger(); l2 = i; if (l2 <= 0) fatal("storeAufsDirReconfigure: invalid level 2 directories value"); /* just reconfigure it */ if (size == sd->max_size) debug(3, 1) ("Cache dir '%s' size remains unchanged at %d KB\n", path, size); else debug(3, 1) ("Cache dir '%s' size changed to %d KB\n", path, size); sd->max_size = size; parse_cachedir_options(sd, options, 0); return;}voidstoreAufsDirDump(StoreEntry * entry, SwapDir * s){ squidaioinfo_t *aioinfo = (squidaioinfo_t *) s->fsdata; storeAppendPrintf(entry, " %d %d %d", s->max_size >> 10, aioinfo->l1, aioinfo->l2); dump_cachedir_options(entry, options, s);}/* * Only "free" the filesystem specific stuff here */static voidstoreAufsDirFree(SwapDir * s){ squidaioinfo_t *aioinfo = (squidaioinfo_t *) s->fsdata; if (aioinfo->swaplog_fd > -1) { file_close(aioinfo->swaplog_fd); aioinfo->swaplog_fd = -1; } filemapFreeMemory(aioinfo->map); xfree(aioinfo); s->fsdata = NULL; /* Will aid debugging... */}char *storeAufsDirFullPath(SwapDir * SD, sfileno filn, char *fullpath){ LOCAL_ARRAY(char, fullfilename, SQUID_MAXPATHLEN); squidaioinfo_t *aioinfo = (squidaioinfo_t *) SD->fsdata; int L1 = aioinfo->l1; int L2 = aioinfo->l2; if (!fullpath) fullpath = fullfilename; fullpath[0] = '\0'; snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X/%08X", SD->path, ((filn / L2) / L2) % L1, (filn / L2) % L2, filn); return fullpath;}/* * storeAufsCleanupDoubleCheck * * This is called by storeCleanup() if -S was given on the command line. */static intstoreAufsCleanupDoubleCheck(SwapDir * sd, StoreEntry * e){ struct stat sb; if (stat(storeAufsDirFullPath(sd, e->swap_filen, NULL), &sb) < 0) { debug(47, 0) ("storeAufsCleanupDoubleCheck: MISSING SWAP FILE\n"); debug(47, 0) ("storeAufsCleanupDoubleCheck: FILENO %08X\n", e->swap_filen); debug(47, 0) ("storeAufsCleanupDoubleCheck: PATH %s\n", storeAufsDirFullPath(sd, e->swap_filen, NULL)); storeEntryDump(e, 0); return -1; } if (e->swap_file_sz != sb.st_size) { debug(47, 0) ("storeAufsCleanupDoubleCheck: SIZE MISMATCH\n"); debug(47, 0) ("storeAufsCleanupDoubleCheck: FILENO %08X\n", e->swap_filen); debug(47, 0) ("storeAufsCleanupDoubleCheck: PATH %s\n", storeAufsDirFullPath(sd, e->swap_filen, NULL)); debug(47, 0) ("storeAufsCleanupDoubleCheck: ENTRY SIZE: %ld, FILE SIZE: %ld\n", (long int) e->swap_file_sz, (long int) sb.st_size); storeEntryDump(e, 0); return -1; } return 0;}/* * storeAufsDirParse * * Called when a *new* fs is being setup. */static voidstoreAufsDirParse(SwapDir * sd, int index, char *path){ int i; int size; int l1; int l2; squidaioinfo_t *aioinfo; i = GetInteger(); size = i << 10; /* Mbytes to kbytes */ if (size <= 0) fatal("storeAufsDirParse: invalid size value"); i = GetInteger(); l1 = i; if (l1 <= 0) fatal("storeAufsDirParse: invalid level 1 directories value"); i = GetInteger(); l2 = i; if (l2 <= 0) fatal("storeAufsDirParse: invalid level 2 directories value"); aioinfo = xmalloc(sizeof(squidaioinfo_t)); if (aioinfo == NULL) fatal("storeAufsDirParse: couldn't xmalloc() squidaioinfo_t!\n"); sd->index = index; sd->path = xstrdup(path); sd->max_size = size; sd->fsdata = aioinfo; aioinfo->l1 = l1; aioinfo->l2 = l2; aioinfo->swaplog_fd = -1; aioinfo->map = NULL; /* Debugging purposes */ aioinfo->suggest = 0; sd->checkconfig = storeAufsCheckConfig; sd->init = storeAufsDirInit; sd->newfs = storeAufsDirNewfs; sd->dump = storeAufsDirDump; sd->freefs = storeAufsDirFree; sd->dblcheck = storeAufsCleanupDoubleCheck; sd->statfs = storeAufsDirStats; sd->maintainfs = storeAufsDirMaintain; sd->checkobj = storeAufsDirCheckObj; sd->checkload = storeAufsDirCheckLoadAv; sd->refobj = storeAufsDirRefObj; sd->unrefobj = storeAufsDirUnrefObj; sd->callback = aioCheckCallbacks; sd->sync = aioSync; sd->obj.create = storeAufsCreate; sd->obj.open = storeAufsOpen; sd->obj.close = storeAufsClose; sd->obj.read = storeAufsRead; sd->obj.write = storeAufsWrite; sd->obj.unlink = storeAufsUnlink; sd->obj.recycle = storeAufsRecycle; sd->log.open = storeAufsDirOpenSwapLog; sd->log.close = storeAufsDirCloseSwapLog; sd->log.write = storeAufsDirSwapLog; sd->log.clean.start = storeAufsDirWriteCleanStart; sd->log.clean.nextentry = storeAufsDirCleanLogNextEntry; sd->log.clean.done = storeAufsDirWriteCleanDone; parse_cachedir_options(sd, options, 0); /* Initialise replacement policy stuff */ sd->repl = createRemovalPolicy(Config.replPolicy); asyncufs_dir_index = realloc(asyncufs_dir_index, (n_asyncufs_dirs + 1) * sizeof(*asyncufs_dir_index)); asyncufs_dir_index[n_asyncufs_dirs++] = index;}/* * Initial setup / end destruction */static voidstoreAufsDirDone(void){ aioDone(); memPoolDestroy(squidaio_state_pool); memPoolDestroy(aufs_qread_pool); memPoolDestroy(aufs_qwrite_pool); asyncufs_initialised = 0;}voidstoreFsSetup_aufs(storefs_entry_t * storefs){ assert(!asyncufs_initialised); storefs->parsefunc = storeAufsDirParse; storefs->reconfigurefunc = storeAufsDirReconfigure; storefs->donefunc = storeAufsDirDone; squidaio_state_pool = memPoolCreate("AUFS IO State data", sizeof(squidaiostate_t)); aufs_qread_pool = memPoolCreate("AUFS Queued read data", sizeof(queued_read)); aufs_qwrite_pool = memPoolCreate("AUFS Queued write data", sizeof(queued_write)); asyncufs_initialised = 1; aioInit();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -