From: adrian <> Date: Fri, 10 Aug 2001 03:41:53 +0000 (+0000) Subject: COSS fixes from diskio. X-Git-Tag: SQUID_3_0_PRE1~1454 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c94af0b96468ba69e7b8253488a699efd16a49cb;p=thirdparty%2Fsquid.git COSS fixes from diskio. This code is now stable, but <2gb and sync. Next, >2gb. --- diff --git a/src/fs/coss/Makefile.in b/src/fs/coss/Makefile.in index 059ab5ae7a..316c9d8307 100644 --- a/src/fs/coss/Makefile.in +++ b/src/fs/coss/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the COSS storage driver for the Squid Object Cache server # -# $Id: Makefile.in,v 1.1 2000/05/03 17:15:47 adrian Exp $ +# $Id: Makefile.in,v 1.2 2001/08/09 21:41:53 adrian Exp $ # FS = coss diff --git a/src/fs/coss/store_coss.h b/src/fs/coss/store_coss.h index 650630b81b..bbd8b77d69 100644 --- a/src/fs/coss/store_coss.h +++ b/src/fs/coss/store_coss.h @@ -5,13 +5,25 @@ #define COSS_MEMBUF_SZ 1048576 #endif +#ifndef COSS_BLOCK_SZ +#define COSS_BLOCK_SZ 512 +#endif + +/* Macros to help block<->offset transiting */ +#define COSS_OFS_TO_BLK(ofs) ((ofs) / COSS_BLOCK_SZ) +#define COSS_BLK_TO_OFS(ofs) ((ofs) * COSS_BLOCK_SZ) + +/* Note that swap_filen in sio/e are actually disk offsets too! */ + +/* What we're doing in storeCossAllocate() */ #define COSS_ALLOC_NOTIFY 0 #define COSS_ALLOC_ALLOCATE 1 #define COSS_ALLOC_REALLOC 2 struct _cossmembuf { - size_t diskstart; - size_t diskend; + dlink_node node; + size_t diskstart; /* in blocks */ + size_t diskend; /* in blocks */ SwapDir *SD; int lockcount; char buffer[COSS_MEMBUF_SZ]; @@ -19,15 +31,14 @@ struct _cossmembuf { unsigned int full:1; unsigned int writing:1; } flags; - struct _cossmembuf *next; }; /* Per-storedir info */ struct _cossinfo { - struct _cossmembuf *membufs; + dlink_list membufs; struct _cossmembuf *current_membuf; - size_t current_offset; + size_t current_offset; /* in Blocks */ int fd; int swaplog_fd; int numcollisions; @@ -49,8 +60,8 @@ struct _cossstate { char *readbuffer; char *requestbuf; size_t requestlen; - size_t requestoffset; - sfileno reqdiskoffset; + size_t requestoffset; /* in blocks */ + sfileno reqdiskoffset; /* in blocks */ struct { unsigned int reading:1; unsigned int writing:1; diff --git a/src/fs/coss/store_dir_coss.cc b/src/fs/coss/store_dir_coss.cc index cdf9d3dafa..623e56fa02 100644 --- a/src/fs/coss/store_dir_coss.cc +++ b/src/fs/coss/store_dir_coss.cc @@ -1,6 +1,6 @@ /* - * $Id: store_dir_coss.cc,v 1.23 2001/07/11 22:29:50 hno Exp $ + * $Id: store_dir_coss.cc,v 1.24 2001/08/09 21:41:53 adrian Exp $ * * DEBUG: section 81 Store COSS Directory Routines * AUTHOR: Eric Stern @@ -764,12 +764,15 @@ storeCossDirParse(SwapDir * sd, int index, char *path) cs->fd = -1; cs->swaplog_fd = -1; cs->numcollisions = 0; - cs->membufs = NULL; /* set when the rebuild completes */ - cs->current_membuf = cs->membufs; + cs->membufs.head = cs->membufs.tail = NULL; /* set when the rebuild completes */ + cs->current_membuf = NULL; cs->index.head = NULL; cs->index.tail = NULL; parse_cachedir_options(sd, NULL, 0); + /* Enforce maxobjsize being set to something */ + if (sd->max_objsize == -1) + fatal("COSS requires max-size to be set to something other than -1!\n"); } @@ -791,6 +794,9 @@ storeCossDirReconfigure(SwapDir * sd, int index, char *path) sd->max_size = size; } parse_cachedir_options(sd, NULL, 1); + /* Enforce maxobjsize being set to something */ + if (sd->max_objsize == -1) + fatal("COSS requires max-size to be set to something other than -1!\n"); } void diff --git a/src/fs/coss/store_io_coss.cc b/src/fs/coss/store_io_coss.cc index 3327da6a3a..8c34bbc106 100644 --- a/src/fs/coss/store_io_coss.cc +++ b/src/fs/coss/store_io_coss.cc @@ -1,6 +1,6 @@ /* - * $Id: store_io_coss.cc,v 1.9 2001/04/20 21:18:43 hno Exp $ + * $Id: store_io_coss.cc,v 1.10 2001/08/09 21:41:53 adrian Exp $ * * DEBUG: section 81 Storage Manager COSS Interface * AUTHOR: Eric Stern @@ -47,9 +47,9 @@ static void storeCossWriteMemBufDone(int fd, int errflag, size_t len, void *my_d static CossMemBuf *storeCossCreateMemBuf(SwapDir * SD, size_t start, sfileno curfn, int *collision); static CBDUNL storeCossIOFreeEntry; -static CBDUNL storeCossMembufFree; CBDATA_TYPE(storeIOState); +CBDATA_TYPE(CossMemBuf); /* === PUBLIC =========================================================== */ @@ -83,35 +83,42 @@ storeCossAllocate(SwapDir * SD, const StoreEntry * e, int which) else allocsize = objectLen(e) + e->mem_obj->swap_hdr_sz; - if (which != COSS_ALLOC_NOTIFY) { - if ((cs->current_offset + allocsize) > (SD->max_size << 10)) { - /* - * tried to allocate past the end of the disk, so wrap - * back to the beginning - */ - cs->current_membuf->flags.full = 1; - cs->current_membuf->diskend = cs->current_offset - 1; - cs->current_offset = 0; /* wrap back to beginning */ - - newmb = storeCossCreateMemBuf(SD, 0, checkf, &coll); - cs->current_membuf = newmb; - } else if ((cs->current_offset + allocsize) > cs->current_membuf->diskend) { - cs->current_membuf->flags.full = 1; - cs->current_membuf->diskend = cs->current_offset - 1; - newmb = storeCossCreateMemBuf(SD, cs->current_offset, - checkf, &coll); - cs->current_membuf = newmb; - } - if (coll == 0) { - retofs = cs->current_offset; - } else { - debug(81, 3) ("storeCossAllocate: Collision\n"); - } + /* Since we're not supporting NOTIFY anymore, lets fail */ + assert(which != COSS_ALLOC_NOTIFY); + + /* Check if we have overflowed the disk .. */ + if ((cs->current_offset + allocsize) > (SD->max_size << 10)) { + /* + * tried to allocate past the end of the disk, so wrap + * back to the beginning + */ + cs->current_membuf->flags.full = 1; + cs->current_membuf->diskend = cs->current_offset - 1; + cs->current_offset = 0; /* wrap back to beginning */ + debug(81, 2) ("storeCossAllocate: wrap to 0\n"); + + newmb = storeCossCreateMemBuf(SD, 0, checkf, &coll); + cs->current_membuf = newmb; + + /* Check if we have overflowed the MemBuf */ + } else if ((cs->current_offset + allocsize) > cs->current_membuf->diskend) { + /* + * Skip the blank space at the end of the stripe. start over. + */ + cs->current_membuf->flags.full = 1; + cs->current_offset = cs->current_membuf->diskend + 1; + debug(81, 2) ("storeCossAllocate: New offset - %d\n", + cs->current_offset); + newmb = storeCossCreateMemBuf(SD, cs->current_offset, checkf, &coll); + cs->current_membuf = newmb; } + /* If we didn't get a collision, then update the current offset and return it */ if (coll == 0) { + retofs = cs->current_offset; cs->current_offset = retofs + allocsize; return retofs; } else { + debug(81, 3) ("storeCossAllocate: Collision\n"); return -1; } } @@ -137,6 +144,12 @@ storeCossCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * c sio->offset = 0; sio->mode = O_WRONLY; + /* + * If we get handed an object with a size of -1, + * the squid code is broken + */ + assert(e->mem_obj->object_sz != -1); + /* * this one is kinda strange - Eric called storeCossAllocate(), then * storeCossOpen(O_RDONLY) .. weird. Anyway, I'm allocating this now. @@ -147,6 +160,7 @@ storeCossCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * c debug(81, 3) ("storeCossCreate: offset %d, size %d, end %d\n", sio->swap_filen, sio->st_size, sio->swap_filen + sio->st_size); sio->callback = callback; + sio->file_callback = file_callback; sio->callback_data = callback_data; cbdataLock(callback_data); sio->e = (StoreEntry *) e; @@ -266,7 +280,6 @@ storeCossRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t of assert(sio->read.callback_data == NULL); sio->read.callback = callback; sio->read.callback_data = callback_data; - cbdataLock(callback_data); debug(81, 3) ("storeCossRead: offset %d\n", offset); sio->offset = offset; cstate->flags.reading = 1; @@ -277,6 +290,7 @@ storeCossRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t of cstate->requestoffset = offset; if (cstate->readbuffer == NULL) { p = storeCossMemPointerFromDiskOffset(SD, sio->swap_filen, NULL); + /* Remember we need to translate the block offset to a disk offset! */ file_read(cs->fd, p, sio->st_size, @@ -300,6 +314,12 @@ storeCossWrite(SwapDir * SD, storeIOState * sio, char *buf, size_t size, off_t o CossMemBuf *membuf; off_t diskoffset; + /* + * If we get handed an object with a size of -1, + * the squid code is broken + */ + assert(sio->e->mem_obj->object_sz != -1); + debug(81, 3) ("storeCossWrite: offset %d, len %d\n", sio->offset, size); diskoffset = sio->swap_filen + sio->offset; dest = storeCossMemPointerFromDiskOffset(SD, diskoffset, &membuf); @@ -348,7 +368,6 @@ storeCossReadDone(int fd, const char *buf, int len, int errflag, void *my_data) sio->read.callback_data = NULL; if (cbdataValid(their_data)) callback(their_data, cstate->requestbuf, rlen); - cbdataUnlock(their_data); } static void @@ -359,6 +378,7 @@ storeCossIOCallback(storeIOState * sio, int errflag) xfree(cstate->readbuffer); if (cbdataValid(sio->callback_data)) sio->callback(sio->callback_data, errflag, sio); + cbdataUnlock(sio->callback_data); sio->callback_data = NULL; cbdataFree(sio); } @@ -367,14 +387,18 @@ static char * storeCossMemPointerFromDiskOffset(SwapDir * SD, size_t offset, CossMemBuf ** mb) { CossMemBuf *t; + dlink_node *m; CossInfo *cs = (CossInfo *) SD->fsdata; - for (t = cs->membufs; t; t = t->next) + for (m = cs->membufs.head; m; m = m->next) { + t = m->data; if ((offset >= t->diskstart) && (offset <= t->diskend)) { if (mb) *mb = t; return &t->buffer[offset - t->diskstart]; } + } + if (mb) *mb = NULL; return NULL; @@ -384,14 +408,17 @@ static void storeCossMemBufLock(SwapDir * SD, storeIOState * e) { CossMemBuf *t; + dlink_node *m; CossInfo *cs = (CossInfo *) SD->fsdata; - for (t = cs->membufs; t; t = t->next) + for (m = cs->membufs.head; m; m = m->next) { + t = m->data; if ((e->swap_filen >= t->diskstart) && (e->swap_filen <= t->diskend)) { debug(81, 3) ("storeCossMemBufLock: locking %08X, lockcount %d\n", t, t->lockcount); t->lockcount++; return; } + } debug(81, 3) ("storeCossMemBufLock: FAILED to lock %08X\n", e); } @@ -399,9 +426,17 @@ static void storeCossMemBufUnlock(SwapDir * SD, storeIOState * e) { CossMemBuf *t; + dlink_node *m, *n; CossInfo *cs = (CossInfo *) SD->fsdata; - for (t = cs->membufs; t; t = t->next) { + for (m = cs->membufs.head; m; m = n) { + /* + * Note that storeCossWriteMemBuf() might call storeCossWriteMemBufDone + * immediately (if the write finishes immediately, of course!) which + * will make m = m->next kinda unworkable. So, get the next pointer. + */ + n = m->next; + t = m->data; if ((e->swap_filen >= t->diskstart) && (e->swap_filen <= t->diskend)) { t->lockcount--; debug(81, 3) ("storeCossMemBufUnlock: unlocking %08X, lockcount %d\n", t, t->lockcount); @@ -416,12 +451,14 @@ storeCossSync(SwapDir * SD) { CossInfo *cs = (CossInfo *) SD->fsdata; CossMemBuf *t; + dlink_node *m; int end; - if (!cs->membufs) + if (!cs->membufs.head) return; - for (t = cs->membufs; t; t = t->next) { + for (m = cs->membufs.head; m; m = m->next) { + t = m->data; if (t->flags.writing) - sleep(5); + sleep(5); /* XXX EEEWWW! */ lseek(cs->fd, t->diskstart, SEEK_SET); end = (t == cs->current_membuf) ? cs->current_offset : t->diskend; write(cs->fd, t->buffer, end - t->diskstart); @@ -435,6 +472,7 @@ storeCossWriteMemBuf(SwapDir * SD, CossMemBuf * t) debug(81, 3) ("storeCossWriteMemBuf: offset %d, len %d\n", t->diskstart, t->diskend - t->diskstart); t->flags.writing = 1; + /* Remember that diskstart/diskend are block offsets! */ file_write(cs->fd, t->diskstart, &t->buffer, t->diskend - t->diskstart, storeCossWriteMemBufDone, t, NULL); } @@ -444,33 +482,16 @@ static void storeCossWriteMemBufDone(int fd, int errflag, size_t len, void *my_data) { CossMemBuf *t = my_data; - CossMemBuf *p, *prev; CossInfo *cs = (CossInfo *) t->SD->fsdata; - debug(81, 3) ("storeCossWriteMemBufDone: len %d\n", len); - if (errflag) { + debug(81, 3) ("storeCossWriteMemBufDone: buf %08X, len %d\n", t, len); + if (errflag) debug(81, 0) ("storeCossMemBufWriteDone: got failure (%d)\n", errflag); - cbdataFree(t); - return; - } - if (t == cs->membufs) { - cs->membufs = t->next; - cbdataFree(t); - return; - } - prev = t; - for (p = cs->membufs; p; p = p->next) { - if (t == p) { - prev->next = t->next; - cbdataFree(t); - return; - } - prev = p; - } + + dlinkDelete(&t->node, &cs->membufs); cbdataFree(t); } -CBDATA_TYPE(CossMemBuf); static CossMemBuf * storeCossCreateMemBuf(SwapDir * SD, size_t start, sfileno curfn, int *collision) @@ -481,20 +502,24 @@ storeCossCreateMemBuf(SwapDir * SD, size_t start, int numreleased = 0; CossInfo *cs = (CossInfo *) SD->fsdata; - CBDATA_INIT_TYPE_FREECB(CossMemBuf, storeCossMembufFree); + CBDATA_INIT_TYPE_FREECB(CossMemBuf, NULL); newmb = cbdataAlloc(CossMemBuf); newmb->diskstart = start; debug(81, 3) ("storeCossCreateMemBuf: creating new membuf at %d\n", newmb->diskstart); + debug(81, 3) ("storeCossCreateMemBuf: at %08X\n", newmb); newmb->diskend = newmb->diskstart + COSS_MEMBUF_SZ - 1; newmb->flags.full = 0; newmb->flags.writing = 0; newmb->lockcount = 0; newmb->SD = SD; /* XXX This should be reversed, with the new buffer last in the chain */ - newmb->next = cs->membufs; - cs->membufs = newmb; - for (t = cs->membufs; t; t = t->next) + dlinkAdd(newmb, &newmb->node, &cs->membufs); + + /* Print out the list of membufs */ + for (m = cs->membufs.head; m; m = m->next) { + t = m->data; debug(81, 3) ("storeCossCreateMemBuf: membuflist %d lockcount %d\n", t->diskstart, t->lockcount); + } /* * Kill objects from the tail to make space for a new chunk @@ -536,14 +561,3 @@ storeCossIOFreeEntry(void *sio) { memPoolFree(coss_state_pool, ((storeIOState *) sio)->fsstate); } - -/* - * We can't pass memFree() as a free function here, since we have to pass it - * an int to memFree(), and we aren't using static memory pool allocation here. - * So we have this hack here .. - */ -static void -storeCossMembufFree(void *mb) -{ - cbdataFree(mb); -}