/* * submit a request to create a cache object for writing. * The StoreEntry structure is sent as a hint to the filesystem * to what will be stored in this object, to allow the filesystem * to select different polices depending on object size or type. */ storeIOState * storeCreate(StoreEntry * e, STIOCB * file_callback, STIOCB * close_callback, void *callback_data) { size_t objsize; sdirno dirn; SwapDir *SD; storeIOState *sio; store_io_stats.create.calls++; /* This is just done for logging purposes */ objsize = objectLen(e); if (objsize != -1) objsize += e->mem_obj->swap_hdr_sz; /* * Pick the swapdir * We assume that the header has been packed by now .. */ 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: Selected dir '%d' for obj size '%ld'\n", dirn, (long int) 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++; else store_io_stats.create.success++; return sio; }
/* * Build a TLV list for a StoreEntry */ tlv * storeSwapMetaBuild(StoreEntry * e) { tlv *TLV = NULL; /* we'll return this */ tlv **T = &TLV; const char *url; const char *vary; const squid_off_t objsize = objectLen(e); assert(e->mem_obj != NULL); assert(e->swap_status == SWAPOUT_WRITING); url = storeUrl(e); debug(20, 3) ("storeSwapMetaBuild: %s\n", url); T = storeSwapTLVAdd(STORE_META_KEY, e->hash.key, SQUID_MD5_DIGEST_LENGTH, T); #if SIZEOF_SQUID_FILE_SZ == SIZEOF_SIZE_T T = storeSwapTLVAdd(STORE_META_STD, &e->timestamp, STORE_HDR_METASIZE, T); #else T = storeSwapTLVAdd(STORE_META_STD_LFS, &e->timestamp, STORE_HDR_METASIZE, T); #endif T = storeSwapTLVAdd(STORE_META_URL, url, strlen(url) + 1, T); if (objsize > -1) { T = storeSwapTLVAdd(STORE_META_OBJSIZE, &objsize, sizeof(objsize), T); } vary = e->mem_obj->vary_headers; if (vary) T = storeSwapTLVAdd(STORE_META_VARY_HEADERS, vary, strlen(vary) + 1, T); if (e->mem_obj->store_url) T = storeSwapTLVAdd(STORE_META_STOREURL, e->mem_obj->store_url, strlen(e->mem_obj->store_url) + 1, T); if (e->dirkey) T = storeSwapTLVAdd(STORE_META_KEY_URL, e->dirkey, SQUID_MD5_DIGEST_LENGTH, T); return TLV; }
/* * This function is used below to decide if we have any more data to * send to the client. If the store_status is STORE_PENDING, then we * do have more data to send. If its STORE_OK, then * we continue checking. If the object length is negative, then we * don't know the real length and must open the swap file to find out. * If the length is >= 0, then we compare it to the requested copy * offset. */ static int storeClientNoMoreToSend(StoreEntry * e, store_client * sc) { squid_off_t len; if (e->store_status == STORE_PENDING) return 0; if ((len = objectLen(e)) < 0) return 0; if (sc->copy_offset < len) return 0; return 1; }
static int swdaeSwapDirRoundRobin(cache_select_t *cache, const StoreEntry * e) { static int dirn = 0; int i; int load; SwapDir *sd; squid_off_t objsize = objectLen(e); for (i = 0; i < cache->dir.count; i++) { cache->dirn = cache->dirn % cache->dir.count; dirn = (int)cache->dir.items[cache->dirn]; cache->dirn++; if (0 > dirn || dirn >= Config.cacheSwap.n_configured) continue; sd = &Config.cacheSwap.swapDirs[dirn]; if (sd->flags.read_only) { debug(172, 5)("%s %s: %s read_only\n", PMOD_NAME, __func__, sd->path); continue; } if (sd->cur_size > sd->max_size) { debug(172, 5)("%s %s: %scur_size > sd->max_size\n", PMOD_NAME, __func__, sd->path); continue; } if (!swdaeSwapDirSwapDirSize(dirn, objsize)) { debug(172,5)("%s %s objsize isn't Suitable %s %s\n",PMOD_NAME, __func__, sd->path, storeUrl(e)); continue; } if (sd->checkobj(sd, e) == 0) { debug(172,5)("%s %s checkobj(sd,e) == 0\n", PMOD_NAME, sd->path); continue; } load = sd->checkload(sd, ST_OP_CREATE); if (load < 0 || load > 2000) { debug(172, 5)("%s %s Load too high %s\n", PMOD_NAME, sd->path, storeUrl(e)); continue; } debug(172,3)("%s %s select [%s] store %s\n", PMOD_NAME, __func__, sd->path, storeUrl(e)); return dirn; } debug(172, 7)("%s %s nomatch %s\n", PMOD_NAME, __func__, storeUrl(e)); return -1; }
static int swdaeSwapDirLeastLoad(cache_select_t *cache, const StoreEntry *e) { squid_off_t objsize; int most_free = 0, cur_free; squid_off_t least_objsize = -1; int least_load = INT_MAX; int load; int dirn = 0; int dirn_no = -1; int i; SwapDir *sd; /* Calculate the object size */ objsize = objectLen(e); if (objsize != -1) objsize += e->mem_obj->swap_hdr_sz; for (i = 0; i < cache->dir.count; i++) { cache->dirn = cache->dirn % cache->dir.count; dirn = (int)cache->dir.items[cache->dirn]; cache->dirn++; if (0 > dirn || dirn >= Config.cacheSwap.n_configured) continue; sd = &Config.cacheSwap.swapDirs[dirn]; sd->flags.selected = 0; if (sd->flags.read_only) { debug(172, 5)("%s %s %s read_only\n", PMOD_NAME, __func__,sd->path); continue; } if (sd->cur_size > sd->max_size) { debug(172, 5)("%s %s %s cur_size > sd->max_size\n", PMOD_NAME, __func__, sd->path); continue; } if (!swdaeSwapDirSwapDirSize(dirn, objsize)) { debug(172,5)("%s %s objsize isn't Suitable %s %s\n", PMOD_NAME, __func__, sd->path, storeUrl(e)); continue; } if (sd->checkobj(sd, e) == 0) { debug(172,5)("%s %s %s checkobj(sd,e) == 0\n",PMOD_NAME, __func__, sd->path); continue; } load = sd->checkload(sd, ST_OP_CREATE); if (load < 0 || load > 2000) { debug(172, 5)("%s %s %s Load too high %s\n", PMOD_NAME, __func__, sd->path, storeUrl(e)); continue; } if (load > least_load) continue; cur_free = sd->max_size - sd->cur_size; /* If the load is equal, then look in more details */ if (load == least_load) { /* closest max_objsize fit */ if (least_objsize != -1) if (sd->max_objsize > least_objsize || sd->max_objsize == -1) continue; /* most free */ if (cur_free < most_free) continue; } least_load = load; least_objsize = sd->max_objsize; most_free = cur_free; dirn_no = dirn; } if (dirn_no >= 0) { sd = &Config.cacheSwap.swapDirs[dirn_no]; debug(172,5)("%s %s Select [%s] store %s\n", PMOD_NAME, __func__, sd->path, storeUrl(e)); Config.cacheSwap.swapDirs[dirn_no].flags.selected = 1; }else { debug(172,5)("%s %s Select Null store %s\n",PMOD_NAME, __func__, storeUrl(e)); } return dirn_no; }