The unified diff between revisions [cc35419e..] and [f681bbc6..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "src/fs/coss/store_coss.h"
# from [9fb20e426c4f9b4b0842b5f4005ee29fd9903e69]
# to [712f79a4e81633580a6bd795168f7f2cd6bbe02d]
#
# patch "src/fs/coss/store_dir_coss.c"
# from [aaf4dfff6e1cb06e2c31d0530da5d9f6217c84e9]
# to [fe7ccefa847ca91ccb5b9a56dab745d41158090e]
#
============================================================
--- src/fs/coss/store_coss.h 9fb20e426c4f9b4b0842b5f4005ee29fd9903e69
+++ src/fs/coss/store_coss.h 712f79a4e81633580a6bd795168f7f2cd6bbe02d
@@ -24,7 +24,7 @@ typedef struct _cossstripe CossStripe;
* Define this if you would like to use the aufs IO method for
* disk IO instead of the POSIX AIO method.
*/
-#define USE_AUFSOPS 1
+//#define USE_AUFSOPS 1
#if USE_AUFSOPS
/* XXX a hack; the async ops should be broken out! */
@@ -144,6 +144,12 @@ struct _cossinfo {
int numstripes;
struct _cossstripe *stripes;
int curstripe;
+ struct {
+ char rebuilding;
+ char reading;
+ int curstripe;
+ char *buf;
+ } rebuild;
};
struct _cossindex {
============================================================
--- src/fs/coss/store_dir_coss.c aaf4dfff6e1cb06e2c31d0530da5d9f6217c84e9
+++ src/fs/coss/store_dir_coss.c fe7ccefa847ca91ccb5b9a56dab745d41158090e
@@ -62,17 +62,6 @@ static char *storeCossDirSwapLogFile(Swa
};
static char *storeCossDirSwapLogFile(SwapDir *, const char *);
-static EVH storeCossRebuildFromSwapLog;
-static StoreEntry *storeCossAddDiskRestore(SwapDir * SD, const cache_key * key,
- int file_number,
- squid_file_sz 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 storeCossDirRebuild(SwapDir * sd);
static void storeCossDirCloseTmpSwapLog(SwapDir * sd);
static FILE *storeCossDirOpenTmpSwapLog(SwapDir *, int *, int *);
@@ -95,6 +84,8 @@ static OBJH storeCossStats;
static void storeCossDirDumpBlkSize(StoreEntry *, const char *, SwapDir *);
static OBJH storeCossStats;
+static void storeDirCoss_StartDiskRebuild(RebuildState *rb);
+
/* The "only" externally visible function */
STSETUP storeFsSetup_coss;
@@ -174,9 +165,9 @@ storeCossDirInit(SwapDir * sd)
#else
a_file_setupqueue(&cs->aq);
#endif
+ cs->fd = file_open(sd->path, O_RDWR | O_CREAT);
storeCossDirOpenSwapLog(sd);
storeCossDirRebuild(sd);
- cs->fd = file_open(sd->path, O_RDWR | O_CREAT);
if (cs->fd < 0) {
debug(79, 1) ("%s: %s\n", sd->path, xstrerror());
fatal("storeCossDirInit: Failed to open a COSS file.");
@@ -189,6 +180,7 @@ storeCossDirInit(SwapDir * sd)
* page.
*/
sd->fs.blksize = 1 << cs->blksz_bits;
+ comm_quick_poll_required();
}
void
@@ -231,147 +223,6 @@ storeCossRebuildComplete(void *data)
cbdataFree(rb);
}
-static void
-storeCossRebuildFromSwapLog(void *data)
-{
- RebuildState *rb = data;
- StoreEntry *e = NULL;
- storeSwapLogData s;
- size_t ss = sizeof(storeSwapLogData);
- int count;
- 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(79, 1) ("Done reading %s swaplog (%d entries)\n",
- rb->sd->path, rb->n_read);
- fclose(rb->log);
- rb->log = NULL;
- storeCossRebuildComplete(rb);
- return;
- }
- rb->n_read++;
- if (s.op <= SWAP_LOG_NOP)
- continue;
- if (s.op >= SWAP_LOG_MAX)
- continue;
- debug(20, 3) ("storeCossRebuildFromSwapLog: %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) {
- /* Delete unless we already have a newer copy */
- if ((e = storeGet(s.key)) != NULL && s.lastref > e->lastref) {
- /*
- * 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);
- if (e->swap_filen > -1) {
- e->swap_filen = -1;
- }
- storeRelease(e);
- /* Fake an unlink here, this is a bad hack :( */
- storeCossRemove(rb->sd, 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(rb->sd->index,
- (int) sb.st_size / ss, rb->n_read);
- }
- if (EBIT_TEST(s.flags, KEY_PRIVATE)) {
- rb->counts.badflags++;
- continue;
- }
- e = storeGet(s.key);
- if (e) {
- /* key already exists, current entry is newer */
- /* keep old, ignore new */
- rb->counts.dupcount++;
- continue;
- }
- /* update store_swap_size */
- rb->counts.objcount++;
- e = storeCossAddDiskRestore(rb->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("storeCossRebuild", storeCossRebuildFromSwapLog, rb, 0.0, 1);
-}
-
-/* Add a new object to the cache with empty memory copy and pointer to disk
- * use to rebuild store from disk. */
-static StoreEntry *
-storeCossAddDiskRestore(SwapDir * SD, const cache_key * key,
- int file_number,
- squid_file_sz 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) ("storeCossAddDiskRestore: %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;
- e->swap_dirn = SD->index;
- storeSetMemStatus(e, NOT_IN_MEMORY);
- e->swap_status = SWAPOUT_DONE;
- e->swap_filen = file_number;
- 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);
- storeHashInsert(e, key); /* do it after we clear KEY_PRIVATE */
- storeCossAdd(SD, e);
-#if USE_COSS_ALLOC_NOTIFY
- e->swap_filen = storeCossAllocate(SD, e, COSS_ALLOC_NOTIFY);
-#endif
- assert(e->swap_filen >= 0);
- return e;
-}
-
CBDATA_TYPE(RebuildState);
static void
storeCossDirRebuild(SwapDir * sd)
@@ -380,40 +231,16 @@ storeCossDirRebuild(SwapDir * sd)
int clean = 0;
int zero = 0;
FILE *fp;
- EVH *func = NULL;
CBDATA_INIT_TYPE(RebuildState);
rb = cbdataAlloc(RebuildState);
rb->sd = sd;
rb->speed = opt_foreground_rebuild ? 1 << 30 : 50;
- func = storeCossRebuildFromSwapLog;
rb->flags.clean = (unsigned int) clean;
- /*
- * If the swap.state file exists in the cache_dir, then
- * we'll use storeCossRebuildFromSwapLog().
- */
fp = storeCossDirOpenTmpSwapLog(sd, &clean, &zero);
- debug(20, 1) ("Rebuilding COSS storage in %s (%s)\n",
- sd->path, clean ? "CLEAN" : "DIRTY");
- rb->log = fp;
+ fclose(fp);
+ debug(20, 1) ("Rebuilding COSS storage in %s (DIRTY)\n", sd->path);
store_dirs_rebuilding++;
- if (!clean || fp == NULL) {
- /* COSS cannot yet rebuild from a dirty state. If the log
- * is dirty then the COSS contents is thrown away.
- * Why? I guess it is because some contents will be lost,
- * and COSS cannot verify this..
- */
- if (fp != NULL)
- fclose(fp);
- /*
- * XXX Make sure we don't trigger an assertion if this is the first
- * storedir, since if we are, this call will cause storeRebuildComplete
- * to prematurely complete the rebuild process, and then some other
- * storedir will try to rebuild and eventually die.
- */
- eventAdd("storeCossRebuildComplete", storeCossRebuildComplete, rb, 0.0, 0);
- return;
- }
- eventAdd("storeCossRebuild", func, rb, 0.0, 1);
+ storeDirCoss_StartDiskRebuild(rb);
}
static void
@@ -1051,3 +878,64 @@ storeFsSetup_coss(storefs_entry_t * stor
cachemgrRegister("coss", "COSS Stats", storeCossStats, 0, 1);
coss_initialised = 1;
}
+
+/* New storedir rebuilding code! */
+
+static void storeDirCoss_ReadStripe(RebuildState *rb);
+
+static void
+storeDirCoss_ReadStripeComplete(int fd, const char *buf, int r_len, int r_errflag, void *my_data)
+{
+ RebuildState *rb = my_data;
+ SwapDir *SD = rb->sd;
+ CossInfo *cs = SD->fsdata;
+
+ debug(47, 1) ("COSS: %s: read stripe %d, read %d bytes, status %d\n", SD->path, cs->rebuild.curstripe, r_len, r_errflag);
+ cs->rebuild.reading = 0;
+ if (r_errflag != DISK_OK) {
+ debug(47, 1) ("COSS: %s: stripe %d: error! Ignoring objects in this stripe.\n", SD->path, cs->rebuild.curstripe);
+ goto nextstripe;
+ }
+ /* parse the stripe contents */
+
+nextstripe:
+ cs->rebuild.curstripe++;
+ if (cs->rebuild.curstripe >= cs->numstripes) {
+ /* Completed the rebuild - move onto the next phase */
+ debug(47, 1) ("COSS: %s: completed reading the stripes.\n", SD->path);
+ fatal("Done!");
+ } else {
+ /* Next stripe */
+ storeDirCoss_ReadStripe(rb);
+ }
+}
+
+static void
+storeDirCoss_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, 1) ("COSS: %s: reading stripe %d\n", SD->path, cs->rebuild.curstripe);
+ a_file_read(&cs->aq, cs->fd, cs->rebuild.buf, COSS_MEMBUF_SZ, cs->rebuild.curstripe * COSS_MEMBUF_SZ, storeDirCoss_ReadStripeComplete, rb);
+}
+
+static void
+storeDirCoss_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);
+
+ debug(47, 1) ("COSS: %s: Beginning disk rebuild.\n", SD->path);
+ storeDirCoss_ReadStripe(rb);
+}