Author: adrian.chadd
Date: Sun May  3 17:43:28 2009
New Revision: 14036

Added:
    branches/LUSCA_HEAD/src/fs/aufs/store_log_aufs.h
Modified:
    branches/LUSCA_HEAD/src/fs/aufs/store_dir_aufs.c
    branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.c
    branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.h

Log:
Continue breaking apart the AUFS dir code into separate source files.

There's a bit of dirty prototyping in store_log_aufs.h which doesn't belong  
there.
I'll unwind that a little more next.



Modified: branches/LUSCA_HEAD/src/fs/aufs/store_dir_aufs.c
==============================================================================
--- branches/LUSCA_HEAD/src/fs/aufs/store_dir_aufs.c    (original)
+++ branches/LUSCA_HEAD/src/fs/aufs/store_dir_aufs.c    Sun May  3 17:43:28  
2009
@@ -40,6 +40,7 @@
  #include "store_asyncufs.h"
  #include "store_bitmap_aufs.h"
  #include "store_rebuild_aufs.h"
+#include "store_log_aufs.h"

  #define DefaultLevelOneDirs     16
  #define DefaultLevelTwoDirs     256
@@ -58,22 +59,7 @@
  static int storeAufsDirVerifyDirectory(const char *path);
  static void storeAufsDirCreateSwapSubDirs(SwapDir *);
  static char *storeAufsDirSwapLogFile(SwapDir *, const char *);
-static EVH storeAufsDirRebuildFromDirectory;
-static EVH storeAufsDirRebuildFromSwapLog;
-static int storeAufsDirGetNextFile(RebuildState *, sfileno *, int *size);
-static StoreEntry *storeAufsDirAddDiskRestore(SwapDir * SD, const  
cache_key * key,
-    sfileno 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 storeAufsDirRebuild(SwapDir * sd);
-static void storeAufsDirCloseTmpSwapLog(SwapDir * sd);
-static int storeAufsDirOpenTmpSwapLog(SwapDir *, int *, int *);
+
  static STLOGOPEN storeAufsDirOpenSwapLog;
  static STINIT storeAufsDirInit;
  static STFREE storeAufsDirFree;
@@ -89,14 +75,13 @@
  static STCHECKOBJ storeAufsDirCheckObj;
  static STCHECKLOADAV storeAufsDirCheckLoadAv;
  static STREFOBJ storeAufsDirRefObj;
-static STUNREFOBJ storeAufsDirUnrefObj;
+/* static STUNREFOBJ storeAufsDirUnrefObj; */
+
  static QS rev_int_sort;
  static int storeAufsDirClean(int swap_index);
  static EVH storeAufsDirCleanEvent;
-static int storeAufsFilenoBelongsHere(int fn, int F0, int F1, int F2);
  static int storeAufsCleanupDoubleCheck(SwapDir *, StoreEntry *);
  static void storeAufsDirStats(SwapDir *, StoreEntry *);
-static int storeAufsDirValidFileno(SwapDir *, sfileno, int);
  static void storeAufsSync(SwapDir *);

  /* The MAIN externally visible function */
@@ -306,572 +291,7 @@
      (void) storeDirGetBlkSize(sd->path, &sd->fs.blksize);
  }

-static void
-storeAufsDirRebuildComplete(RebuildState * rb)
-{
-    if (rb->log_fd) {
-       debug(47, 1) ("Done reading %s swaplog (%d entries)\n",
-           rb->sd->path, rb->n_read);
-       file_close(rb->log_fd);
-       rb->log_fd = -1;
-    } else {
-       debug(47, 1) ("Done scanning %s (%d entries)\n",
-           rb->sd->path, rb->counts.scancount);
-    }
-    store_dirs_rebuilding--;
-    storeAufsDirCloseTmpSwapLog(rb->sd);
-    storeRebuildComplete(&rb->counts);
-    cbdataFree(rb);
-}
-
-static void
-storeAufsDirRebuildFromDirectory(void *data)
-{
-    RebuildState *rb = data;
-    SwapDir *SD = rb->sd;
-    LOCAL_ARRAY(char, hdr_buf, SM_PAGE_SIZE);
-    StoreEntry *e = NULL;
-    StoreEntry tmpe;
-    cache_key key[SQUID_MD5_DIGEST_LENGTH];
-    sfileno filn = 0;
-    int count;
-    int size;
-    struct stat sb;
-    int swap_hdr_len;
-    int fd = -1;
-    tlv *tlv_list;
-    tlv *t;
-    assert(rb != NULL);
-    debug(47, 3) ("storeAufsDirRebuildFromDirectory: DIR #%d\n",  
rb->sd->index);
-    for (count = 0; count < rb->speed; count++) {
-       assert(fd == -1);
-       fd = storeAufsDirGetNextFile(rb, &filn, &size);
-       if (fd == -2) {
-           storeAufsDirRebuildComplete(rb);
-           return;
-       } else if (fd < 0) {
-           continue;
-       }
-       assert(fd > -1);
-       /* lets get file stats here */
-       if (fstat(fd, &sb) < 0) {
-           debug(47, 1) ("storeAufsDirRebuildFromDirectory: fstat(FD %d): 
%s\n",
-               fd, xstrerror());
-           file_close(fd);
-           store_open_disk_fd--;
-           fd = -1;
-           continue;
-       }
-       if ((++rb->counts.scancount & 0xFFFF) == 0)
-           debug(47, 3) ("  %s %7d files opened so far.\n",
-               rb->sd->path, rb->counts.scancount);
-       debug(47, 9) ("file_in: fd=%d %08X\n", fd, filn);
-       CommStats.syscalls.disk.reads++;
-       if (FD_READ_METHOD(fd, hdr_buf, SM_PAGE_SIZE) < 0) {
-           debug(47, 1) ("storeAufsDirRebuildFromDirectory: read(FD %d): %s\n",
-               fd, xstrerror());
-           file_close(fd);
-           store_open_disk_fd--;
-           fd = -1;
-           continue;
-       }
-       file_close(fd);
-       store_open_disk_fd--;
-       fd = -1;
-       swap_hdr_len = 0;
-#if USE_TRUNCATE
-       if (sb.st_size == 0)
-           continue;
-#endif
-       tlv_list = storeSwapMetaUnpack(hdr_buf, &swap_hdr_len);
-       if (tlv_list == NULL) {
-           debug(47, 1) ("storeAufsDirRebuildFromDirectory: failed to get meta 
 
data\n");
-           /* XXX shouldn't this be a call to storeAufsUnlink ? */
-           storeAufsDirUnlinkFile(SD, filn);
-           continue;
-       }
-       debug(47, 3) ("storeAufsDirRebuildFromDirectory: successful swap meta  
unpacking\n");
-       memset(key, '\0', SQUID_MD5_DIGEST_LENGTH);
-       memset(&tmpe, '\0', sizeof(StoreEntry));
-       for (t = tlv_list; t; t = t->next) {
-           switch (t->type) {
-           case STORE_META_KEY:
-               assert(t->length == SQUID_MD5_DIGEST_LENGTH);
-               xmemcpy(key, t->value, SQUID_MD5_DIGEST_LENGTH);
-               break;
-#if SIZEOF_SQUID_FILE_SZ == SIZEOF_SIZE_T
-           case STORE_META_STD:
-               assert(t->length == STORE_HDR_METASIZE);
-               xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE);
-               break;
-#else
-           case STORE_META_STD_LFS:
-               assert(t->length == STORE_HDR_METASIZE);
-               xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE);
-               break;
-           case STORE_META_STD:
-               assert(t->length == STORE_HDR_METASIZE_OLD);
-               {
-                   struct {
-                       time_t timestamp;
-                       time_t lastref;
-                       time_t expires;
-                       time_t lastmod;
-                       size_t swap_file_sz;
-                       u_short refcount;
-                       u_short flags;
-                   }     *tmp = t->value;
-                   assert(sizeof(*tmp) == STORE_HDR_METASIZE_OLD);
-                   tmpe.timestamp = tmp->timestamp;
-                   tmpe.lastref = tmp->lastref;
-                   tmpe.expires = tmp->expires;
-                   tmpe.lastmod = tmp->lastmod;
-                   tmpe.swap_file_sz = tmp->swap_file_sz;
-                   tmpe.refcount = tmp->refcount;
-                   tmpe.flags = tmp->flags;
-               }
-               break;
-#endif
-           default:
-               break;
-           }
-       }
-       storeSwapTLVFree(tlv_list);
-       tlv_list = NULL;
-       if (storeKeyNull(key)) {
-           debug(47, 1) ("storeAufsDirRebuildFromDirectory: NULL key\n");
-           storeAufsDirUnlinkFile(SD, filn);
-           continue;
-       }
-       tmpe.hash.key = key;
-       /* check sizes */
-       if (tmpe.swap_file_sz == 0) {
-           tmpe.swap_file_sz = sb.st_size;
-       } else if (tmpe.swap_file_sz == sb.st_size - swap_hdr_len) {
-           tmpe.swap_file_sz = sb.st_size;
-       } else if (tmpe.swap_file_sz != sb.st_size) {
-           debug(47, 1) ("storeAufsDirRebuildFromDirectory: SIZE  
MISMATCH %ld!=%ld\n",
-               (long int) tmpe.swap_file_sz, (long int) sb.st_size);
-           storeAufsDirUnlinkFile(SD, filn);
-           continue;
-       }
-       if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) {
-           storeAufsDirUnlinkFile(SD, filn);
-           rb->counts.badflags++;
-           continue;
-       }
-       e = storeGet(key);
-       if (e && e->lastref >= tmpe.lastref) {
-           /* key already exists, current entry is newer */
-           /* keep old, ignore new */
-           rb->counts.dupcount++;
-           continue;
-       } else if (NULL != e) {
-           /* URL already exists, this swapfile not being used */
-           /* junk old, load new */
-           storeRelease(e);    /* release old entry */
-           rb->counts.dupcount++;
-       }
-       rb->counts.objcount++;
-       storeEntryDump(&tmpe, 5);
-       e = storeAufsDirAddDiskRestore(SD, key,
-           filn,
-           tmpe.swap_file_sz,
-           tmpe.expires,
-           tmpe.timestamp,
-           tmpe.lastref,
-           tmpe.lastmod,
-           tmpe.refcount,      /* refcount */
-           tmpe.flags,         /* flags */
-           (int) rb->flags.clean);
-       storeDirSwapLog(e, SWAP_LOG_ADD);
-    }
-    eventAdd("storeRebuild", storeAufsDirRebuildFromDirectory, rb, 0.0, 1);
-}
-
-static int
-storeAufsDirRebuildFromSwapLogObject(RebuildState *rb, storeSwapLogData s)
-{
-       SwapDir *SD = rb->sd;
-       StoreEntry *e = NULL;
-       double x;
-       int used;                       /* is swapfile already in use? */
-       int disk_entry_newer;   /* is the log entry newer than current entry? */
-
-       /*
-        * BC: during 2.4 development, we changed the way swap file
-        * numbers are assigned and stored.  The high 16 bits used
-        * to encode the SD index number.  There used to be a call
-        * to storeDirProperFileno here that re-assigned the index
-        * bits.  Now, for backwards compatibility, we just need
-        * to mask it off.
-        */
-       s.swap_filen &= 0x00FFFFFF;
-       debug(47, 3) ("storeAufsDirRebuildFromSwapLog: %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.
-                */
-               storeRecycle(e);
-               rb->counts.cancelcount++;
-           }
-           return -1;
-       } else {
-           x = log(++rb->counts.bad_log_op) / log(10.0);
-           if (0.0 == x - (double) (int) x)
-               debug(47, 1) ("WARNING: %d invalid swap log entries found\n",
-                   rb->counts.bad_log_op);
-           rb->counts.invalid++;
-           return -1;
-       }
-       if (!storeAufsDirValidFileno(SD, s.swap_filen, 0)) {
-           rb->counts.invalid++;
-           return -1;
-       }
-       if (EBIT_TEST(s.flags, KEY_PRIVATE)) {
-           rb->counts.badflags++;
-           return -1;
-       }
-       e = storeGet(s.key);
-       used = storeAufsDirMapBitTest(SD, s.swap_filen);
-       /* If this URL already exists in the cache, does the swap log
-        * appear to have a newer entry?  Compare 'lastref' from the
-        * swap log to e->lastref. */
-       disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0;
-       if (used && !disk_entry_newer) {
-           /* log entry is old, ignore it */
-           rb->counts.clashcount++;
-           return -1;
-       } else if (used && e && e->swap_filen == s.swap_filen && e->swap_dirn 
==  
SD->index) {
-           /* swapfile taken, same URL, newer, update meta */
-           if (e->store_status == STORE_OK) {
-               e->lastref = s.timestamp;
-               e->timestamp = s.timestamp;
-               e->expires = s.expires;
-               e->lastmod = s.lastmod;
-               e->flags = s.flags;
-               e->refcount += s.refcount;
-               storeAufsDirUnrefObj(SD, e);
-           } else {
-               debug_trap("storeAufsDirRebuildFromSwapLog: bad condition");
-               debug(47, 1) ("\tSee %s:%d\n", __FILE__, __LINE__);
-           }
-           return -1;
-       } else if (used) {
-           /* swapfile in use, not by this URL, log entry is newer */
-           /* This is sorta bad: the log entry should NOT be newer at this
-            * point.  If the log is dirty, the filesize check should have
-            * caught this.  If the log is clean, there should never be a
-            * newer entry. */
-           debug(47, 1) ("WARNING: newer swaplog entry for dirno %d,  
fileno %08X\n",
-               SD->index, s.swap_filen);
-           /* I'm tempted to remove the swapfile here just to be safe,
-            * but there is a bad race condition in the NOVM version if
-            * the swapfile has recently been opened for writing, but
-            * not yet opened for reading.  Because we can't map
-            * swapfiles back to StoreEntrys, we don't know the state
-            * of the entry using that file.  */
-           /* We'll assume the existing entry is valid, probably because
-            * the swap file number got taken while we rebuild */
-           rb->counts.clashcount++;
-           return -1;
-       } else if (e && !disk_entry_newer) {
-           /* key already exists, current entry is newer */
-           /* keep old, ignore new */
-           rb->counts.dupcount++;
-           return -1;
-       } else if (e) {
-           /* key already exists, this swapfile not being used */
-           /* junk old, load new */
-           storeRecycle(e);
-           rb->counts.dupcount++;
-       } else {
-           /* URL doesnt exist, swapfile not in use */
-           /* load new */
-           (void) 0;
-       }
-       /* update store_swap_size */
-       rb->counts.objcount++;
-       e = storeAufsDirAddDiskRestore(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);
-       return 1;
-}
-
-static void
-storeAufsDirRebuildFromSwapLog(void *data)
-{
-    RebuildState *rb = data;
-    char buf[256];
-    storeSwapLogData s;
-    int count;
-    size_t ss;
-
-    assert(rb != NULL);
-    if (rb->flags.old_swaplog_entry_size)
-       ss = sizeof(storeSwapLogDataOld);
-    else
-       ss = sizeof(storeSwapLogData);
-    assert(ss < sizeof(buf));
-
-    /* load a number of objects per invocation */
-    for (count = 0; count < rb->speed; count++) {
-       /* Read the swaplog entry, new or old */
-       /* XXX this will be slow - one read() per entry .. */
-       /* XXX so obviously it needs to be changed and quickly .. */
-       if (read(rb->log_fd, buf, ss) != ss) {
-           storeAufsDirRebuildComplete(rb);
-           return;
-       }
-       rb->n_read++;
-
-       /* Is it an old-style entry? convert it if needed */
-       if (rb->flags.old_swaplog_entry_size) {
-               (void) storeSwapLogUpgradeEntry(&s, (storeSwapLogDataOld *) 
buf);
-       } else {
-               memcpy(&s, buf, sizeof(s));
-       }
-       storeAufsDirRebuildFromSwapLogObject(rb, s);
-
-       if ((++rb->counts.scancount & 0xFFF) == 0) {
-           struct stat sb;
-           if (0 == fstat(rb->log_fd, &sb))
-               storeRebuildProgress(rb->sd->index, (int) sb.st_size / ss, 
rb->n_read);
-       }
-    }
-    eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 1);
-}
-
-static void
-storeAufsDirRebuildFromSwapLogCheckVersion(void *data)
-{
-    RebuildState *rb = data;
-    storeSwapLogHeader hdr;
-
-    /* XXX should be aioRead() with a callback.. */
-    if (read(rb->log_fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
-       storeAufsDirRebuildComplete(rb);
-       return;
-    }
-    if (hdr.op == SWAP_LOG_VERSION) {
-       if (lseek(rb->log_fd, hdr.record_size, SEEK_SET) < 0) {
-           storeAufsDirRebuildComplete(rb);
-           return;
-       }
-       if (hdr.version == 1 && hdr.record_size == sizeof(storeSwapLogData)) {
-           rb->flags.old_swaplog_entry_size = 0;
-           eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 
1);
-           return;
-       }
-#if SIZEOF_SQUID_FILE_SZ != SIZEOF_SIZE_T
-       if (hdr.version == 1 && hdr.record_size == sizeof(storeSwapLogDataOld)) 
{
-           debug(47, 1) ("storeAufsDirRebuildFromSwapLog: Found current 
version  
but without large file support. Upgrading\n");
-           rb->flags.old_swaplog_entry_size = 1;
-           eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 
1);
-           return;
-       }
-#endif
-       debug(47, 1) ("storeAufsDirRebuildFromSwapLog: Unsupported swap.state  
version %d size %d\n",
-           hdr.version, hdr.record_size);
-       storeAufsDirRebuildComplete(rb);
-       return;
-    }
-    lseek(rb->log_fd, SEEK_SET, 0);
-    debug(47, 1) ("storeAufsDirRebuildFromSwapLog: Old version detected.  
Upgrading\n");
-#if SIZEOF_SQUID_FILE_SZ == SIZEOF_SIZE_T
-    rb->flags.old_swaplog_entry_size = 0;
-    eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 1);
-#else
-    rb->flags.old_swaplog_entry_size = 1;
-    eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 1);
-#endif
-}
-
-static int
-storeAufsDirGetNextFile(RebuildState * rb, sfileno * filn_p, int *size)
-{
-    SwapDir *SD = rb->sd;
-    squidaioinfo_t *aioinfo = (squidaioinfo_t *) SD->fsdata;
-    int fd = -1;
-    int used = 0;
-    int dirs_opened = 0;
-    debug(47, 3) ("storeAufsDirGetNextFile: flag=%d, %d: /%02X/%02X\n",
-       rb->flags.init,
-       rb->sd->index,
-       rb->curlvl1,
-       rb->curlvl2);
-    if (rb->done)
-       return -2;
-    while (fd < 0 && rb->done == 0) {
-       fd = -1;
-       if (0 == rb->flags.init) {      /* initialize, open first file */
-           rb->done = 0;
-           rb->curlvl1 = 0;
-           rb->curlvl2 = 0;
-           rb->in_dir = 0;
-           rb->flags.init = 1;
-           assert(Config.cacheSwap.n_configured > 0);
-       }
-       if (0 == rb->in_dir) {  /* we need to read in a new directory */
-           snprintf(rb->fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X",
-               rb->sd->path,
-               rb->curlvl1, rb->curlvl2);
-           if (dirs_opened)
-               return -1;
-           rb->td = opendir(rb->fullpath);
-           dirs_opened++;
-           if (rb->td == NULL) {
-               debug(47, 1) ("storeAufsDirGetNextFile: opendir: %s: %s\n",
-                   rb->fullpath, xstrerror());
-           } else {
-               rb->entry = readdir(rb->td);    /* skip . and .. */
-               rb->entry = readdir(rb->td);
-               if (rb->entry == NULL && errno == ENOENT)
-                   debug(47, 1) ("storeAufsDirGetNextFile: directory does not  
exist!.\n");
-               debug(47, 3) ("storeAufsDirGetNextFile: Directory %s\n", 
rb->fullpath);
-           }
-       }
-       if (rb->td != NULL && (rb->entry = readdir(rb->td)) != NULL) {
-           rb->in_dir++;
-           if (sscanf(rb->entry->d_name, "%x", &rb->fn) != 1) {
-               debug(47, 3) ("storeAufsDirGetNextFile: invalid %s\n",
-                   rb->entry->d_name);
-               continue;
-           }
-           if (!storeAufsFilenoBelongsHere(rb->fn, rb->sd->index, rb->curlvl1, 
 
rb->curlvl2)) {
-               debug(47, 3) ("storeAufsDirGetNextFile: %08X does not belong  
in %d/%d/%d\n",
-                   rb->fn, rb->sd->index, rb->curlvl1, rb->curlvl2);
-               continue;
-           }
-           used = storeAufsDirMapBitTest(SD, rb->fn);
-           if (used) {
-               debug(47, 3) ("storeAufsDirGetNextFile: Locked, continuing with 
 
next.\n");
-               continue;
-           }
-           snprintf(rb->fullfilename, SQUID_MAXPATHLEN, "%s/%s",
-               rb->fullpath, rb->entry->d_name);
-           debug(47, 3) ("storeAufsDirGetNextFile: Opening %s\n",  
rb->fullfilename);
-           fd = file_open(rb->fullfilename, O_RDONLY | O_BINARY);
-           if (fd < 0)
-               debug(47, 1) ("storeAufsDirGetNextFile: %s: %s\n", 
rb->fullfilename,  
xstrerror());
-           else
-               store_open_disk_fd++;
-           continue;
-       }
-       if (rb->td != NULL)
-           closedir(rb->td);
-       rb->td = NULL;
-       rb->in_dir = 0;
-       if (++rb->curlvl2 < aioinfo->l2)
-           continue;
-       rb->curlvl2 = 0;
-       if (++rb->curlvl1 < aioinfo->l1)
-           continue;
-       rb->curlvl1 = 0;
-       rb->done = 1;
-    }
-    *filn_p = rb->fn;
-    return fd;
-}
-
-/* Add a new object to the cache with empty memory copy and pointer to disk
- * use to rebuild store from disk. */
-static StoreEntry *
-storeAufsDirAddDiskRestore(SwapDir * SD, const cache_key * key,
-    sfileno 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(47, 5) ("storeAufsAddDiskRestore: %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);
-    e->store_status = STORE_OK;
-    storeSetMemStatus(e, NOT_IN_MEMORY);
-    e->swap_status = SWAPOUT_DONE;
-    e->swap_filen = file_number;
-    e->swap_dirn = SD->index;
-    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);
-    storeAufsDirMapBitSet(SD, e->swap_filen);
-    storeHashInsert(e, key);   /* do it after we clear KEY_PRIVATE */
-    storeAufsDirReplAdd(SD, e);
-    return e;
-}
-
-CBDATA_TYPE(RebuildState);
-
-static void
-storeAufsDirRebuild(SwapDir * sd)
-{
-    RebuildState *rb;
-    int clean = 0;
-    int zero = 0;
-    int log_fd;
-    EVH *func = NULL;
-    CBDATA_INIT_TYPE(RebuildState);
-    rb = cbdataAlloc(RebuildState);
-    rb->sd = sd;
-    rb->speed = opt_foreground_rebuild ? 1 << 30 : 50;
-    /*
-     * If the swap.state file exists in the cache_dir, then
-     * we'll use storeAufsDirRebuildFromSwapLog(), otherwise we'll
-     * use storeAufsDirRebuildFromDirectory() to open up each file
-     * and suck in the meta data.
-     */
-    log_fd = storeAufsDirOpenTmpSwapLog(sd, &clean, &zero);
-    if (! log_fd || zero) {
-       if (log_fd)
-           file_close(log_fd);
-       func = storeAufsDirRebuildFromDirectory;
-    } else {
-       func = storeAufsDirRebuildFromSwapLogCheckVersion;
-       rb->log_fd = log_fd;
-       rb->flags.clean = (unsigned int) clean;
-    }
-    debug(47, 1) ("Rebuilding storage in %s (%s)\n", sd->path,  
clean ? "CLEAN" : "DIRTY");
-    store_dirs_rebuilding++;
-    eventAdd("storeRebuild", func, rb, 0.0, 1);
-}
-
-static void
+void
  storeAufsDirCloseTmpSwapLog(SwapDir * sd)
  {
      squidaioinfo_t *aioinfo = (squidaioinfo_t *) sd->fsdata;
@@ -918,7 +338,7 @@
        (FREE *) storeSwapLogDataFree);
  }

-static int
+int
  storeAufsDirOpenTmpSwapLog(SwapDir * sd, int *clean_flag, int *zero_flag)
  {
      squidaioinfo_t *aioinfo = (squidaioinfo_t *) sd->fsdata;
@@ -1289,7 +709,7 @@
   * Does swapfile number 'fn' belong in cachedir #F0,
   * level1 dir #F1, level2 dir #F2?
   */
-static int
+int
  storeAufsFilenoBelongsHere(int fn, int F0, int F1, int F2)
  {
      int D1, D2;

Added: branches/LUSCA_HEAD/src/fs/aufs/store_log_aufs.h
==============================================================================
--- (empty file)
+++ branches/LUSCA_HEAD/src/fs/aufs/store_log_aufs.h    Sun May  3 17:43:28  
2009
@@ -0,0 +1,12 @@
+#ifndef        __STORE_LOG_AUFS_H__
+#define        __STORE_LOG_AUFS_H__
+
+extern int storeAufsDirOpenTmpSwapLog(SwapDir *, int *, int *);
+extern void storeAufsDirCloseTmpSwapLog(SwapDir * sd);
+
+/* XXX not specifically meant to be here */
+extern int storeAufsFilenoBelongsHere(int fn, int F0, int F1, int F2);
+extern int storeAufsDirValidFileno(SwapDir *, sfileno, int);
+extern STUNREFOBJ storeAufsDirUnrefObj;
+
+#endif

Modified: branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.c
==============================================================================
--- branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.c        (original)
+++ branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.c        Sun May  3  
17:43:28 2009
@@ -0,0 +1,611 @@
+
+/*
+ * $Id: store_dir_aufs.c 14035 2009-05-03 23:17:56Z adrian.chadd $
+ *
+ * DEBUG: section 47    Store Directory Routines
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+
+#include "../../libasyncio/aiops.h"
+#include "../../libasyncio/async_io.h"
+#include "store_asyncufs.h"
+#include "store_bitmap_aufs.h"
+#include "store_rebuild_aufs.h"
+#include "store_log_aufs.h"
+
+#define STORE_META_BUFSZ 4096
+
+static void
+storeAufsDirRebuildComplete(RebuildState * rb)
+{
+    if (rb->log_fd) {
+       debug(47, 1) ("Done reading %s swaplog (%d entries)\n",
+           rb->sd->path, rb->n_read);
+       file_close(rb->log_fd);
+       rb->log_fd = -1;
+    } else {
+       debug(47, 1) ("Done scanning %s (%d entries)\n",
+           rb->sd->path, rb->counts.scancount);
+    }
+    store_dirs_rebuilding--;
+    storeAufsDirCloseTmpSwapLog(rb->sd);
+    storeRebuildComplete(&rb->counts);
+    cbdataFree(rb);
+}
+
+static int
+storeAufsDirGetNextFile(RebuildState * rb, sfileno * filn_p, int *size)
+{
+    SwapDir *SD = rb->sd;
+    squidaioinfo_t *aioinfo = (squidaioinfo_t *) SD->fsdata;
+    int fd = -1;
+    int used = 0;
+    int dirs_opened = 0;
+    debug(47, 3) ("storeAufsDirGetNextFile: flag=%d, %d: /%02X/%02X\n",
+       rb->flags.init,
+       rb->sd->index,
+       rb->curlvl1,
+       rb->curlvl2);
+    if (rb->done)
+       return -2;
+    while (fd < 0 && rb->done == 0) {
+       fd = -1;
+       if (0 == rb->flags.init) {      /* initialize, open first file */
+           rb->done = 0;
+           rb->curlvl1 = 0;
+           rb->curlvl2 = 0;
+           rb->in_dir = 0;
+           rb->flags.init = 1;
+           assert(Config.cacheSwap.n_configured > 0);
+       }
+       if (0 == rb->in_dir) {  /* we need to read in a new directory */
+           snprintf(rb->fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X",
+               rb->sd->path,
+               rb->curlvl1, rb->curlvl2);
+           if (dirs_opened)
+               return -1;
+           rb->td = opendir(rb->fullpath);
+           dirs_opened++;
+           if (rb->td == NULL) {
+               debug(47, 1) ("storeAufsDirGetNextFile: opendir: %s: %s\n",
+                   rb->fullpath, xstrerror());
+           } else {
+               rb->entry = readdir(rb->td);    /* skip . and .. */
+               rb->entry = readdir(rb->td);
+               if (rb->entry == NULL && errno == ENOENT)
+                   debug(47, 1) ("storeAufsDirGetNextFile: directory does not  
exist!.\n");
+               debug(47, 3) ("storeAufsDirGetNextFile: Directory %s\n", 
rb->fullpath);
+           }
+       }
+       if (rb->td != NULL && (rb->entry = readdir(rb->td)) != NULL) {
+           rb->in_dir++;
+           if (sscanf(rb->entry->d_name, "%x", &rb->fn) != 1) {
+               debug(47, 3) ("storeAufsDirGetNextFile: invalid %s\n",
+                   rb->entry->d_name);
+               continue;
+           }
+           if (!storeAufsFilenoBelongsHere(rb->fn, rb->sd->index, rb->curlvl1, 
 
rb->curlvl2)) {
+               debug(47, 3) ("storeAufsDirGetNextFile: %08X does not belong  
in %d/%d/%d\n",
+                   rb->fn, rb->sd->index, rb->curlvl1, rb->curlvl2);
+               continue;
+           }
+           used = storeAufsDirMapBitTest(SD, rb->fn);
+           if (used) {
+               debug(47, 3) ("storeAufsDirGetNextFile: Locked, continuing with 
 
next.\n");
+               continue;
+           }
+           snprintf(rb->fullfilename, SQUID_MAXPATHLEN, "%s/%s",
+               rb->fullpath, rb->entry->d_name);
+           debug(47, 3) ("storeAufsDirGetNextFile: Opening %s\n",  
rb->fullfilename);
+           fd = file_open(rb->fullfilename, O_RDONLY | O_BINARY);
+           if (fd < 0)
+               debug(47, 1) ("storeAufsDirGetNextFile: %s: %s\n", 
rb->fullfilename,  
xstrerror());
+           else
+               store_open_disk_fd++;
+           continue;
+       }
+       if (rb->td != NULL)
+           closedir(rb->td);
+       rb->td = NULL;
+       rb->in_dir = 0;
+       if (++rb->curlvl2 < aioinfo->l2)
+           continue;
+       rb->curlvl2 = 0;
+       if (++rb->curlvl1 < aioinfo->l1)
+           continue;
+       rb->curlvl1 = 0;
+       rb->done = 1;
+    }
+    *filn_p = rb->fn;
+    return fd;
+}
+
+/* Add a new object to the cache with empty memory copy and pointer to disk
+ * use to rebuild store from disk. */
+static StoreEntry *
+storeAufsDirAddDiskRestore(SwapDir * SD, const cache_key * key,
+    sfileno 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(47, 5) ("storeAufsAddDiskRestore: %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);
+    e->store_status = STORE_OK;
+    storeSetMemStatus(e, NOT_IN_MEMORY);
+    e->swap_status = SWAPOUT_DONE;
+    e->swap_filen = file_number;
+    e->swap_dirn = SD->index;
+    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);
+    storeAufsDirMapBitSet(SD, e->swap_filen);
+    storeHashInsert(e, key);   /* do it after we clear KEY_PRIVATE */
+    storeAufsDirReplAdd(SD, e);
+    return e;
+}
+
+
+static void
+storeAufsDirRebuildFromDirectory(void *data)
+{
+    RebuildState *rb = data;
+    SwapDir *SD = rb->sd;
+    LOCAL_ARRAY(char, hdr_buf, SM_PAGE_SIZE);
+    StoreEntry *e = NULL;
+    StoreEntry tmpe;
+    cache_key key[SQUID_MD5_DIGEST_LENGTH];
+    sfileno filn = 0;
+    int count;
+    int size;
+    struct stat sb;
+    int swap_hdr_len;
+    int fd = -1;
+    tlv *tlv_list;
+    tlv *t;
+    assert(rb != NULL);
+    debug(47, 3) ("storeAufsDirRebuildFromDirectory: DIR #%d\n",  
rb->sd->index);
+    for (count = 0; count < rb->speed; count++) {
+       assert(fd == -1);
+       fd = storeAufsDirGetNextFile(rb, &filn, &size);
+       if (fd == -2) {
+           storeAufsDirRebuildComplete(rb);
+           return;
+       } else if (fd < 0) {
+           continue;
+       }
+       assert(fd > -1);
+       /* lets get file stats here */
+       if (fstat(fd, &sb) < 0) {
+           debug(47, 1) ("storeAufsDirRebuildFromDirectory: fstat(FD %d): 
%s\n",
+               fd, xstrerror());
+           file_close(fd);
+           store_open_disk_fd--;
+           fd = -1;
+           continue;
+       }
+       if ((++rb->counts.scancount & 0xFFFF) == 0)
+           debug(47, 3) ("  %s %7d files opened so far.\n",
+               rb->sd->path, rb->counts.scancount);
+       debug(47, 9) ("file_in: fd=%d %08X\n", fd, filn);
+       CommStats.syscalls.disk.reads++;
+       if (FD_READ_METHOD(fd, hdr_buf, SM_PAGE_SIZE) < 0) {
+           debug(47, 1) ("storeAufsDirRebuildFromDirectory: read(FD %d): %s\n",
+               fd, xstrerror());
+           file_close(fd);
+           store_open_disk_fd--;
+           fd = -1;
+           continue;
+       }
+       file_close(fd);
+       store_open_disk_fd--;
+       fd = -1;
+       swap_hdr_len = 0;
+#if USE_TRUNCATE
+       if (sb.st_size == 0)
+           continue;
+#endif
+       tlv_list = storeSwapMetaUnpack(hdr_buf, &swap_hdr_len);
+       if (tlv_list == NULL) {
+           debug(47, 1) ("storeAufsDirRebuildFromDirectory: failed to get meta 
 
data\n");
+           /* XXX shouldn't this be a call to storeAufsUnlink ? */
+           storeAufsDirUnlinkFile(SD, filn);
+           continue;
+       }
+       debug(47, 3) ("storeAufsDirRebuildFromDirectory: successful swap meta  
unpacking\n");
+       memset(key, '\0', SQUID_MD5_DIGEST_LENGTH);
+       memset(&tmpe, '\0', sizeof(StoreEntry));
+       for (t = tlv_list; t; t = t->next) {
+           switch (t->type) {
+           case STORE_META_KEY:
+               assert(t->length == SQUID_MD5_DIGEST_LENGTH);
+               xmemcpy(key, t->value, SQUID_MD5_DIGEST_LENGTH);
+               break;
+#if SIZEOF_SQUID_FILE_SZ == SIZEOF_SIZE_T
+           case STORE_META_STD:
+               assert(t->length == STORE_HDR_METASIZE);
+               xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE);
+               break;
+#else
+           case STORE_META_STD_LFS:
+               assert(t->length == STORE_HDR_METASIZE);
+               xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE);
+               break;
+           case STORE_META_STD:
+               assert(t->length == STORE_HDR_METASIZE_OLD);
+               {
+                   struct {
+                       time_t timestamp;
+                       time_t lastref;
+                       time_t expires;
+                       time_t lastmod;
+                       size_t swap_file_sz;
+                       u_short refcount;
+                       u_short flags;
+                   }     *tmp = t->value;
+                   assert(sizeof(*tmp) == STORE_HDR_METASIZE_OLD);
+                   tmpe.timestamp = tmp->timestamp;
+                   tmpe.lastref = tmp->lastref;
+                   tmpe.expires = tmp->expires;
+                   tmpe.lastmod = tmp->lastmod;
+                   tmpe.swap_file_sz = tmp->swap_file_sz;
+                   tmpe.refcount = tmp->refcount;
+                   tmpe.flags = tmp->flags;
+               }
+               break;
+#endif
+           default:
+               break;
+           }
+       }
+       storeSwapTLVFree(tlv_list);
+       tlv_list = NULL;
+       if (storeKeyNull(key)) {
+           debug(47, 1) ("storeAufsDirRebuildFromDirectory: NULL key\n");
+           storeAufsDirUnlinkFile(SD, filn);
+           continue;
+       }
+       tmpe.hash.key = key;
+       /* check sizes */
+       if (tmpe.swap_file_sz == 0) {
+           tmpe.swap_file_sz = sb.st_size;
+       } else if (tmpe.swap_file_sz == sb.st_size - swap_hdr_len) {
+           tmpe.swap_file_sz = sb.st_size;
+       } else if (tmpe.swap_file_sz != sb.st_size) {
+           debug(47, 1) ("storeAufsDirRebuildFromDirectory: SIZE  
MISMATCH %ld!=%ld\n",
+               (long int) tmpe.swap_file_sz, (long int) sb.st_size);
+           storeAufsDirUnlinkFile(SD, filn);
+           continue;
+       }
+       if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) {
+           storeAufsDirUnlinkFile(SD, filn);
+           rb->counts.badflags++;
+           continue;
+       }
+       e = storeGet(key);
+       if (e && e->lastref >= tmpe.lastref) {
+           /* key already exists, current entry is newer */
+           /* keep old, ignore new */
+           rb->counts.dupcount++;
+           continue;
+       } else if (NULL != e) {
+           /* URL already exists, this swapfile not being used */
+           /* junk old, load new */
+           storeRelease(e);    /* release old entry */
+           rb->counts.dupcount++;
+       }
+       rb->counts.objcount++;
+       storeEntryDump(&tmpe, 5);
+       e = storeAufsDirAddDiskRestore(SD, key,
+           filn,
+           tmpe.swap_file_sz,
+           tmpe.expires,
+           tmpe.timestamp,
+           tmpe.lastref,
+           tmpe.lastmod,
+           tmpe.refcount,      /* refcount */
+           tmpe.flags,         /* flags */
+           (int) rb->flags.clean);
+       storeDirSwapLog(e, SWAP_LOG_ADD);
+    }
+    eventAdd("storeRebuild", storeAufsDirRebuildFromDirectory, rb, 0.0, 1);
+}
+
+static int
+storeAufsDirRebuildFromSwapLogObject(RebuildState *rb, storeSwapLogData s)
+{
+       SwapDir *SD = rb->sd;
+       StoreEntry *e = NULL;
+       double x;
+       int used;                       /* is swapfile already in use? */
+       int disk_entry_newer;   /* is the log entry newer than current entry? */
+
+       /*
+        * BC: during 2.4 development, we changed the way swap file
+        * numbers are assigned and stored.  The high 16 bits used
+        * to encode the SD index number.  There used to be a call
+        * to storeDirProperFileno here that re-assigned the index
+        * bits.  Now, for backwards compatibility, we just need
+        * to mask it off.
+        */
+       s.swap_filen &= 0x00FFFFFF;
+       debug(47, 3) ("storeAufsDirRebuildFromSwapLog: %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.
+                */
+               storeRecycle(e);
+               rb->counts.cancelcount++;
+           }
+           return -1;
+       } else {
+           x = log(++rb->counts.bad_log_op) / log(10.0);
+           if (0.0 == x - (double) (int) x)
+               debug(47, 1) ("WARNING: %d invalid swap log entries found\n",
+                   rb->counts.bad_log_op);
+           rb->counts.invalid++;
+           return -1;
+       }
+       if (!storeAufsDirValidFileno(SD, s.swap_filen, 0)) {
+           rb->counts.invalid++;
+           return -1;
+       }
+       if (EBIT_TEST(s.flags, KEY_PRIVATE)) {
+           rb->counts.badflags++;
+           return -1;
+       }
+       e = storeGet(s.key);
+       used = storeAufsDirMapBitTest(SD, s.swap_filen);
+       /* If this URL already exists in the cache, does the swap log
+        * appear to have a newer entry?  Compare 'lastref' from the
+        * swap log to e->lastref. */
+       disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0;
+       if (used && !disk_entry_newer) {
+           /* log entry is old, ignore it */
+           rb->counts.clashcount++;
+           return -1;
+       } else if (used && e && e->swap_filen == s.swap_filen && e->swap_dirn 
==  
SD->index) {
+           /* swapfile taken, same URL, newer, update meta */
+           if (e->store_status == STORE_OK) {
+               e->lastref = s.timestamp;
+               e->timestamp = s.timestamp;
+               e->expires = s.expires;
+               e->lastmod = s.lastmod;
+               e->flags = s.flags;
+               e->refcount += s.refcount;
+               storeAufsDirUnrefObj(SD, e);
+           } else {
+               debug_trap("storeAufsDirRebuildFromSwapLog: bad condition");
+               debug(47, 1) ("\tSee %s:%d\n", __FILE__, __LINE__);
+           }
+           return -1;
+       } else if (used) {
+           /* swapfile in use, not by this URL, log entry is newer */
+           /* This is sorta bad: the log entry should NOT be newer at this
+            * point.  If the log is dirty, the filesize check should have
+            * caught this.  If the log is clean, there should never be a
+            * newer entry. */
+           debug(47, 1) ("WARNING: newer swaplog entry for dirno %d,  
fileno %08X\n",
+               SD->index, s.swap_filen);
+           /* I'm tempted to remove the swapfile here just to be safe,
+            * but there is a bad race condition in the NOVM version if
+            * the swapfile has recently been opened for writing, but
+            * not yet opened for reading.  Because we can't map
+            * swapfiles back to StoreEntrys, we don't know the state
+            * of the entry using that file.  */
+           /* We'll assume the existing entry is valid, probably because
+            * the swap file number got taken while we rebuild */
+           rb->counts.clashcount++;
+           return -1;
+       } else if (e && !disk_entry_newer) {
+           /* key already exists, current entry is newer */
+           /* keep old, ignore new */
+           rb->counts.dupcount++;
+           return -1;
+       } else if (e) {
+           /* key already exists, this swapfile not being used */
+           /* junk old, load new */
+           storeRecycle(e);
+           rb->counts.dupcount++;
+       } else {
+           /* URL doesnt exist, swapfile not in use */
+           /* load new */
+           (void) 0;
+       }
+       /* update store_swap_size */
+       rb->counts.objcount++;
+       e = storeAufsDirAddDiskRestore(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);
+       return 1;
+}
+
+static void
+storeAufsDirRebuildFromSwapLog(void *data)
+{
+    RebuildState *rb = data;
+    char buf[256];
+    storeSwapLogData s;
+    int count;
+    size_t ss;
+
+    assert(rb != NULL);
+    if (rb->flags.old_swaplog_entry_size)
+       ss = sizeof(storeSwapLogDataOld);
+    else
+       ss = sizeof(storeSwapLogData);
+    assert(ss < sizeof(buf));
+
+    /* load a number of objects per invocation */
+    for (count = 0; count < rb->speed; count++) {
+       /* Read the swaplog entry, new or old */
+       /* XXX this will be slow - one read() per entry .. */
+       /* XXX so obviously it needs to be changed and quickly .. */
+       if (read(rb->log_fd, buf, ss) != ss) {
+           storeAufsDirRebuildComplete(rb);
+           return;
+       }
+       rb->n_read++;
+
+       /* Is it an old-style entry? convert it if needed */
+       if (rb->flags.old_swaplog_entry_size) {
+               (void) storeSwapLogUpgradeEntry(&s, (storeSwapLogDataOld *) 
buf);
+       } else {
+               memcpy(&s, buf, sizeof(s));
+       }
+       storeAufsDirRebuildFromSwapLogObject(rb, s);
+
+       if ((++rb->counts.scancount & 0xFFF) == 0) {
+           struct stat sb;
+           if (0 == fstat(rb->log_fd, &sb))
+               storeRebuildProgress(rb->sd->index, (int) sb.st_size / ss, 
rb->n_read);
+       }
+    }
+    eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 1);
+}
+
+static void
+storeAufsDirRebuildFromSwapLogCheckVersion(void *data)
+{
+    RebuildState *rb = data;
+    storeSwapLogHeader hdr;
+
+    /* XXX should be aioRead() with a callback.. */
+    if (read(rb->log_fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+       storeAufsDirRebuildComplete(rb);
+       return;
+    }
+    if (hdr.op == SWAP_LOG_VERSION) {
+       if (lseek(rb->log_fd, hdr.record_size, SEEK_SET) < 0) {
+           storeAufsDirRebuildComplete(rb);
+           return;
+       }
+       if (hdr.version == 1 && hdr.record_size == sizeof(storeSwapLogData)) {
+           rb->flags.old_swaplog_entry_size = 0;
+           eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 
1);
+           return;
+       }
+#if SIZEOF_SQUID_FILE_SZ != SIZEOF_SIZE_T
+       if (hdr.version == 1 && hdr.record_size == sizeof(storeSwapLogDataOld)) 
{
+           debug(47, 1) ("storeAufsDirRebuildFromSwapLog: Found current 
version  
but without large file support. Upgrading\n");
+           rb->flags.old_swaplog_entry_size = 1;
+           eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 
1);
+           return;
+       }
+#endif
+       debug(47, 1) ("storeAufsDirRebuildFromSwapLog: Unsupported swap.state  
version %d size %d\n",
+           hdr.version, hdr.record_size);
+       storeAufsDirRebuildComplete(rb);
+       return;
+    }
+    lseek(rb->log_fd, SEEK_SET, 0);
+    debug(47, 1) ("storeAufsDirRebuildFromSwapLog: Old version detected.  
Upgrading\n");
+#if SIZEOF_SQUID_FILE_SZ == SIZEOF_SIZE_T
+    rb->flags.old_swaplog_entry_size = 0;
+    eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 1);
+#else
+    rb->flags.old_swaplog_entry_size = 1;
+    eventAdd("storeRebuild", storeAufsDirRebuildFromSwapLog, rb, 0.0, 1);
+#endif
+}
+
+CBDATA_TYPE(RebuildState);
+
+void
+storeAufsDirRebuild(SwapDir * sd)
+{
+    RebuildState *rb;
+    int clean = 0;
+    int zero = 0;
+    int log_fd;
+    EVH *func = NULL;
+    CBDATA_INIT_TYPE(RebuildState);
+    rb = cbdataAlloc(RebuildState);
+    rb->sd = sd;
+    rb->speed = opt_foreground_rebuild ? 1 << 30 : 50;
+    /*
+     * If the swap.state file exists in the cache_dir, then
+     * we'll use storeAufsDirRebuildFromSwapLog(), otherwise we'll
+     * use storeAufsDirRebuildFromDirectory() to open up each file
+     * and suck in the meta data.
+     */
+    log_fd = storeAufsDirOpenTmpSwapLog(sd, &clean, &zero);
+    if (! log_fd || zero) {
+       if (log_fd)
+           file_close(log_fd);
+       func = storeAufsDirRebuildFromDirectory;
+    } else {
+       func = storeAufsDirRebuildFromSwapLogCheckVersion;
+       rb->log_fd = log_fd;
+       rb->flags.clean = (unsigned int) clean;
+    }
+    debug(47, 1) ("Rebuilding storage in %s (%s)\n", sd->path,  
clean ? "CLEAN" : "DIRTY");
+    store_dirs_rebuilding++;
+    eventAdd("storeRebuild", func, rb, 0.0, 1);
+}

Modified: branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.h
==============================================================================
--- branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.h        (original)
+++ branches/LUSCA_HEAD/src/fs/aufs/store_rebuild_aufs.h        Sun May  3  
17:43:28 2009
@@ -24,6 +24,6 @@
      struct _store_rebuild_data counts;
  };

-
+extern void storeAufsDirRebuild(SwapDir * sd);

  #endif

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"lusca-commit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/lusca-commit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to