The unified diff between revisions [cc35419e..] and [f681bbc6..] is displayed below. It can also be downloaded as a raw diff.

This diff has been restricted to the following files: 'src/fs/coss/store_dir_coss.c'

#
#
# patch "src/fs/coss/store_dir_coss.c"
#  from [aaf4dfff6e1cb06e2c31d0530da5d9f6217c84e9]
#    to [fe7ccefa847ca91ccb5b9a56dab745d41158090e]
#
============================================================
--- 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);
+}