]> git.ipfire.org Git - thirdparty/squid.git/blame - src/fs/coss/store_io_coss.cc
Cleanup: zap CVS Id tags
[thirdparty/squid.git] / src / fs / coss / store_io_coss.cc
CommitLineData
cd748f27 1
2/*
262a0e14 3 * $Id$
cd748f27 4 *
17bb3486 5 * DEBUG: section 79 Storage Manager COSS Interface
cd748f27 6 * AUTHOR: Eric Stern
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
cd748f27 9 * ----------------------------------------------------------
10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
cd748f27 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
26ac0430 24 *
cd748f27 25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
26ac0430 29 *
cd748f27 30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 *
34 */
35
36#include "squid.h"
b9ae18aa 37#include "CossSwapDir.h"
e6ccf245 38#include "Store.h"
cd748f27 39#include "store_coss.h"
528b2c61 40#include "MemObject.h"
41#include "fde.h"
d3b3ab85 42#include "SwapDir.h"
b9ae18aa 43#include "StoreFScoss.h"
44#include "DiskIO/DiskIOStrategy.h"
cd748f27 45
c94af0b9 46CBDATA_TYPE(CossMemBuf);
72711e31 47
cd748f27 48/* === PUBLIC =========================================================== */
49
d3b3ab85 50CossState::CossState(CossSwapDir *aCSD):SD (aCSD)
62e76326 51{}
d3b3ab85 52
53
cd748f27 54/*
55 * This routine sucks. I want to rewrite it when possible, and I also think
56 * that we should check after creatmembuf() to see if the object has a
57 * RELEASE_REQUEST set on it (thanks Eric!) rather than this way which seems
58 * to work..
59 * -- Adrian
60 */
b9ae18aa 61sfileno
62CossSwapDir::allocate(const StoreEntry * e, int which)
cd748f27 63{
cd748f27 64 CossMemBuf *newmb;
65 off_t retofs;
47f6e231 66 off_t allocsize;
cd748f27 67 int coll = 0;
68 sfileno checkf;
69
a4b8110e 70 /* Make sure we chcek collisions if reallocating */
62e76326 71
1a224843 72 if (which == COSS_ALLOC_REALLOC) {
62e76326 73 checkf = e->swap_filen;
b9ae18aa 74 StoreFScoss::GetInstance().stats.alloc.realloc++;
1a224843 75 } else {
62e76326 76 checkf = -1;
b9ae18aa 77 StoreFScoss::GetInstance().stats.alloc.alloc++;
1a224843 78 }
cd748f27 79
80 if (e->swap_file_sz > 0)
62e76326 81 allocsize = e->swap_file_sz;
cd748f27 82 else
6056fb29 83 allocsize = e->objectLen() + e->mem_obj->swap_hdr_sz;
cd748f27 84
c94af0b9 85 /* Check if we have overflowed the disk .. */
b9ae18aa 86 /* max_size is int, so cast to (off_t) *before* bit-shifting */
47f6e231 87 if ((current_offset + allocsize) > ((off_t)max_size << 10)) {
62e76326 88 /*
89 * tried to allocate past the end of the disk, so wrap
90 * back to the beginning
91 */
b9ae18aa 92 StoreFScoss::GetInstance().stats.disk_overflows++;
93 current_membuf->flags.full = 1;
94 current_membuf->diskend = current_offset;
95 current_membuf->maybeWrite(this);
96 current_offset = 0; /* wrap back to beginning */
bf8fe701 97 debugs(79, 2, "CossSwapDir::allocate: wrap to 0");
62e76326 98
b9ae18aa 99 newmb = createMemBuf(0, checkf, &coll);
100 current_membuf = newmb;
62e76326 101
102 /* Check if we have overflowed the MemBuf */
b9ae18aa 103 } else if ((current_offset + allocsize) >= current_membuf->diskend) {
62e76326 104 /*
105 * Skip the blank space at the end of the stripe. start over.
106 */
b9ae18aa 107 StoreFScoss::GetInstance().stats.stripe_overflows++;
108 current_membuf->flags.full = 1;
109 current_offset = current_membuf->diskend;
110 current_membuf->maybeWrite(this);
4a7a3d56 111 debugs(79, 2, "CossSwapDir::allocate: New offset - " << current_offset);
b9ae18aa 112 newmb = createMemBuf(current_offset, checkf, &coll);
113 current_membuf = newmb;
cd748f27 114 }
62e76326 115
1a224843 116 /*
117 * If we didn't get a collision, then update the current offset
118 * and return it
119 */
cd748f27 120 if (coll == 0) {
b9ae18aa 121 retofs = current_offset;
122 current_offset = retofs + allocsize;
1a224843 123 /* round up to our blocksize */
b9ae18aa 124 current_offset = ((current_offset + blksz_mask) >> blksz_bits ) << blksz_bits;
125 return storeCossDiskOffsetToFileno(retofs);
cd748f27 126 } else {
b9ae18aa 127 StoreFScoss::GetInstance().stats.alloc.collisions++;
bf8fe701 128 debugs(79, 3, "CossSwapDir::allocate: Collision");
62e76326 129 return -1;
cd748f27 130 }
131}
132
133void
d3b3ab85 134CossSwapDir::unlink(StoreEntry & e)
cd748f27 135{
bf8fe701 136 debugs(79, 3, "storeCossUnlink: offset " << e.swap_filen);
b9ae18aa 137 StoreFScoss::GetInstance().stats.unlink.ops++;
138 StoreFScoss::GetInstance().stats.unlink.success++;
d3b3ab85 139 storeCossRemove(this, &e);
cd748f27 140}
141
d3b3ab85 142StoreIOState::Pointer
c6ee6676 143CossSwapDir::createStoreIO(StoreEntry &e, StoreIOState::STFNCB * file_callback, StoreIOState::STIOCB * callback, void *callback_data)
cd748f27 144{
145 CossState *cstate;
d3b3ab85 146 StoreIOState::Pointer sio = new CossState(this);
147 cstate = dynamic_cast<CossState *>(sio.getRaw());
148 sio->offset_ = 0;
5d1a7121 149 sio->mode = O_WRONLY | O_BINARY;
cd748f27 150
c94af0b9 151 /*
152 * If we get handed an object with a size of -1,
153 * the squid code is broken
154 */
d3b3ab85 155 assert(e.mem_obj->object_sz != -1);
b9ae18aa 156 StoreFScoss::GetInstance().stats.create.ops++;
c94af0b9 157
cd748f27 158 /*
b9ae18aa 159 * this one is kinda strange - Eric called allocate(), then
cd748f27 160 * storeCossOpen(O_RDONLY) .. weird. Anyway, I'm allocating this now.
161 */
6056fb29 162 cstate->st_size = e.objectLen() + e.mem_obj->swap_hdr_sz;
d3b3ab85 163 sio->swap_dirn = index;
b9ae18aa 164 sio->swap_filen = allocate(&e, COSS_ALLOC_ALLOCATE);
bf8fe701 165 debugs(79, 3, "storeCossCreate: offset " <<
47f6e231 166 storeCossFilenoToDiskOffset(sio->swap_filen) <<
bf8fe701 167 ", size " << (long int) cstate->st_size << ", end " <<
47f6e231 168 (sio->swap_filen + cstate->st_size));
bf8fe701 169
b9ae18aa 170 /* assume allocate() always succeeds */
1a224843 171 assert(-1 != sio->swap_filen);
cd748f27 172
173 sio->callback = callback;
c94af0b9 174 sio->file_callback = file_callback;
fa80a8ef 175 sio->callback_data = cbdataReference(callback_data);
d3b3ab85 176 sio->e = &e;
cd748f27 177
178 cstate->flags.writing = 0;
179 cstate->flags.reading = 0;
180 cstate->readbuffer = NULL;
181 cstate->reqdiskoffset = -1;
182
6a566b9c 183 /* Now add it into the index list */
d3b3ab85 184 storeCossAdd(this, &e);
cd748f27 185
b9ae18aa 186 cstate->lockMemBuf();
187 StoreFScoss::GetInstance().stats.create.success++;
cd748f27 188 return sio;
189}
190
d3b3ab85 191StoreIOState::Pointer
c6ee6676 192CossSwapDir::openStoreIO(StoreEntry & e, StoreIOState::STFNCB * file_callback,
193 StoreIOState::STIOCB * callback, void *callback_data)
cd748f27 194{
cd748f27 195 char *p;
196 CossState *cstate;
d3b3ab85 197 sfileno f = e.swap_filen;
cd748f27 198
bf8fe701 199 debugs(79, 3, "storeCossOpen: offset " << f);
b9ae18aa 200 StoreFScoss::GetInstance().stats.open.ops++;
cd748f27 201
d3b3ab85 202 StoreIOState::Pointer sio = new CossState (this);
203 cstate = dynamic_cast<CossState *>(sio.getRaw());
cd748f27 204
cd748f27 205 sio->swap_filen = f;
d3b3ab85 206 sio->swap_dirn = index;
207 sio->offset_ = 0;
5d1a7121 208 sio->mode = O_RDONLY | O_BINARY;
cd748f27 209 sio->callback = callback;
210 sio->file_callback = file_callback;
fa80a8ef 211 sio->callback_data = cbdataReference(callback_data);
d3b3ab85 212 cstate->st_size = e.swap_file_sz;
213 sio->e = &e;
cd748f27 214
215 cstate->flags.writing = 0;
216 cstate->flags.reading = 0;
217 cstate->readbuffer = NULL;
218 cstate->reqdiskoffset = -1;
b9ae18aa 219 p = storeCossMemPointerFromDiskOffset(storeCossFilenoToDiskOffset(f), NULL);
a4b8110e 220 /* make local copy so we don't have to lock membuf */
62e76326 221
cd748f27 222 if (p) {
62e76326 223 cstate->readbuffer = (char *)xmalloc(cstate->st_size);
224 xmemcpy(cstate->readbuffer, p, cstate->st_size);
b9ae18aa 225 StoreFScoss::GetInstance().stats.open_mem_hits++;
cd748f27 226 } else {
62e76326 227 /* Do the allocation */
228 /* this is the first time we've been called on a new sio
26ac0430 229 * read the whole object into memory, then return the
62e76326 230 * requested amount
231 */
b9ae18aa 232 StoreFScoss::GetInstance().stats.open_mem_misses++;
62e76326 233 /*
234 * This bit of code actually does the LRU disk thing - we realloc
235 * a place for the object here, and the file_read() reads the object
236 * into the cossmembuf for later writing ..
237 */
1a224843 238 cstate->reqdiskoffset = storeCossFilenoToDiskOffset(sio->swap_filen);
62e76326 239 sio->swap_filen = -1;
b9ae18aa 240 sio->swap_filen = allocate(&e, COSS_ALLOC_REALLOC);
62e76326 241
242 if (sio->swap_filen == -1) {
243 /* We have to clean up neatly .. */
b9ae18aa 244 StoreFScoss::GetInstance().stats.open.fail++;
62e76326 245 numcollisions++;
bf8fe701 246 debugs(79, 2, "storeCossOpen: Reallocation of " << e.swap_dirn << "/" << e.swap_filen << " failed");
62e76326 247 /* XXX XXX XXX Will squid call storeUnlink for this object? */
248 return NULL;
249 }
250
251 /* Notify the upper levels that we've changed file number */
c6ee6676 252 sio->file_callback(sio->callback_data, 0, sio);
62e76326 253
254 /*
255 * lock the buffer so it doesn't get swapped out on us
1a224843 256 * this will get unlocked in storeCossClose
62e76326 257 */
b9ae18aa 258 cstate->lockMemBuf();
62e76326 259
260 /*
261 * Do the index magic to keep the disk and memory LRUs identical
262 */
263 storeCossRemove(this, &e);
264
265 storeCossAdd(this, &e);
266
267 /*
1a224843 268 * NOTE cstate->readbuffer is NULL. We'll actually read
269 * the disk data into the MemBuf in storeCossRead() and
270 * return that pointer back to the caller
271 */
cd748f27 272 }
62e76326 273
b9ae18aa 274 StoreFScoss::GetInstance().stats.open.success++;
cd748f27 275 return sio;
276}
277
278void
d3b3ab85 279CossState::close()
cd748f27 280{
bf8fe701 281 debugs(79, 3, "storeCossClose: offset " << swap_filen);
62e76326 282
b9ae18aa 283 StoreFScoss::GetInstance().stats.close.ops++;
284 StoreFScoss::GetInstance().stats.close.success++;
285 SD->storeCossMemBufUnlock(this);
286 doCallback(0);
cd748f27 287}
288
289void
d3b3ab85 290CossState::read_(char *buf, size_t size, off_t offset, STRCB * callback, void *callback_data)
cd748f27 291{
292 char *p;
d3b3ab85 293 CossSwapDir *SD = (CossSwapDir *)INDEXSD(swap_dirn);
cd748f27 294
b9ae18aa 295 StoreFScoss::GetInstance().stats.read.ops++;
d3b3ab85 296 assert(read.callback == NULL);
297 assert(read.callback_data == NULL);
298 read.callback = callback;
299 read.callback_data = cbdataReference(callback_data);
4a7a3d56 300 debugs(79, 3, "storeCossRead: offset " << offset);
d3b3ab85 301 offset_ = offset;
302 flags.reading = 1;
62e76326 303
47f6e231 304 if ((offset + (off_t)size) > st_size)
62e76326 305 size = st_size - offset;
306
d3b3ab85 307 requestlen = size;
62e76326 308
d3b3ab85 309 requestbuf = buf;
62e76326 310
d3b3ab85 311 requestoffset = offset;
62e76326 312
d3b3ab85 313 if (readbuffer == NULL) {
b9ae18aa 314 p = SD->storeCossMemPointerFromDiskOffset(SD->storeCossFilenoToDiskOffset(swap_filen), NULL);
315 sfileno tempReqdiskoffset = reqdiskoffset;
62e76326 316 reqdiskoffset = 0; /* XXX */
b9ae18aa 317 SD->theFile->read(new CossRead(ReadRequest(p, st_size, tempReqdiskoffset), this));
cd748f27 318 } else {
1a224843 319 /*
320 * It was copied from memory in storeCossOpen()
321 */
b9ae18aa 322 ReadRequest::Pointer readRequest = new CossRead(ReadRequest(
26ac0430 323 (char *)readbuffer,st_size, 0), this);
b9ae18aa 324 SD->readCompleted(readbuffer, st_size, 0, readRequest);
a4b8110e 325 }
cd748f27 326}
327
328void
528b2c61 329CossState::write(char const *buf, size_t size, off_t offset, FREE * free_func)
cd748f27 330{
331 char *dest;
332 CossMemBuf *membuf;
333 off_t diskoffset;
a4b8110e 334
c94af0b9 335 /*
336 * If we get handed an object with a size of -1,
337 * the squid code is broken
338 */
d3b3ab85 339 assert(e->mem_obj->object_sz != -1);
b9ae18aa 340 StoreFScoss::GetInstance().stats.write.ops++;
c94af0b9 341
4a7a3d56 342 debugs(79, 3, "storeCossWrite: offset " << offset_ << ", len " << (unsigned long int) size);
1a224843 343 diskoffset = SD->storeCossFilenoToDiskOffset(swap_filen) + offset_;
d3b3ab85 344 CossSwapDir *SD = (CossSwapDir *)INDEXSD(swap_dirn);
b9ae18aa 345 dest = SD->storeCossMemPointerFromDiskOffset(diskoffset, &membuf);
cd748f27 346 assert(dest != NULL);
cac03dd2 347 xmemcpy(dest, buf, size);
d3b3ab85 348 offset_ += size;
62e76326 349
cd748f27 350 if (free_func)
62e76326 351 (free_func) ((char *)buf);
1a224843 352
b9ae18aa 353 StoreFScoss::GetInstance().stats.write.success++;
cd748f27 354}
355
1a224843 356off_t
357CossSwapDir::storeCossFilenoToDiskOffset(sfileno f)
358{
359 return (off_t) f << blksz_bits;
360}
361
362sfileno
363CossSwapDir::storeCossDiskOffsetToFileno(off_t o)
364{
365 assert(0 == (o & blksz_mask));
366 return o >> blksz_bits;
367}
368
369CossMemBuf *
370CossSwapDir::storeCossFilenoToMembuf(sfileno f)
371{
372 CossMemBuf *t = NULL;
373 dlink_node *m;
374 off_t o = storeCossFilenoToDiskOffset(f);
375
376 for (m = membufs.head; m; m = m->next) {
377 t = (CossMemBuf *)m->data;
378
4989878c 379 if ((o >= (off_t)t->diskstart) && (o < (off_t)t->diskend))
1a224843 380 break;
381 }
382
383 assert(t);
384 return t;
385}
cd748f27 386
387/* === STATIC =========================================================== */
388
b9ae18aa 389CBDATA_CLASS_INIT(CossRead);
390void *
391CossRead::operator new (size_t)
cd748f27 392{
b9ae18aa 393 CBDATA_INIT_TYPE(CossRead);
394 CossRead *result = cbdataAlloc(CossRead);
395 return result;
396}
62e76326 397
b9ae18aa 398void
399CossRead::operator delete (void *address)
400{
401 cbdataFree(address);
402}
62e76326 403
b9ae18aa 404CBDATA_CLASS_INIT(CossWrite);
405void *
406CossWrite::operator new (size_t)
407{
408 CBDATA_INIT_TYPE(CossWrite);
409 CossWrite *result = cbdataAlloc(CossWrite);
410 return result;
411}
62e76326 412
b9ae18aa 413void
414CossWrite::operator delete (void *address)
415{
416 cbdataFree(address);
cd748f27 417}
418
b9ae18aa 419void
420CossState::doCallback(int errflag)
cd748f27 421{
b9ae18aa 422 STIOCB *callback = this->callback;
fa80a8ef 423 void *cbdata;
bf8fe701 424 debugs(79, 3, "CossState::doCallback: errflag=" << errflag);
b9ae18aa 425 assert(NULL == locked_membuf);
426 xfree(readbuffer);
427 this->callback = NULL;
62e76326 428
b9ae18aa 429 if (cbdataReferenceValidDone(callback_data, &cbdata))
c6ee6676 430 callback(cbdata, errflag, this);
cd748f27 431}
432
b9ae18aa 433char *
47f6e231 434CossSwapDir::storeCossMemPointerFromDiskOffset(off_t offset, CossMemBuf ** mb)
cd748f27 435{
436 CossMemBuf *t;
c94af0b9 437 dlink_node *m;
a4b8110e 438
b9ae18aa 439 for (m = membufs.head; m; m = m->next) {
62e76326 440 t = (CossMemBuf *)m->data;
441
1a224843 442 if ((offset >= t->diskstart) && (offset < t->diskend)) {
62e76326 443 if (mb)
444 *mb = t;
445
446 return &t->buffer[offset - t->diskstart];
447 }
c94af0b9 448 }
449
cd748f27 450 if (mb)
62e76326 451 *mb = NULL;
452
cd748f27 453 return NULL;
454}
455
b9ae18aa 456void
457CossState::lockMemBuf()
cd748f27 458{
b9ae18aa 459 CossMemBuf *t = SD->storeCossFilenoToMembuf(swap_filen);
bf8fe701 460 debugs(79, 3, "CossState::lockMemBuf: locking " << t << ", lockcount " << t->lockcount);
b9ae18aa 461 locked_membuf = t;
462 ++t->lockcount;
cd748f27 463}
464
b9ae18aa 465void
ea75a4c8 466CossSwapDir::storeCossMemBufUnlock(StoreIOState::Pointer sio)
cd748f27 467{
b9ae18aa 468 CossMemBuf *t = storeCossFilenoToMembuf(sio->swap_filen);
ea75a4c8 469 CossState *cstate = dynamic_cast<CossState *>(sio.getRaw());
cd748f27 470
1a224843 471 if (NULL == t)
472 return;
62e76326 473
bf8fe701 474 debugs(79, 3, "storeCossMemBufUnlock: unlocking " << t << ", lockcount " << t->lockcount);
62e76326 475
1a224843 476 t->lockcount--;
477
478 cstate->locked_membuf = NULL;
479
b9ae18aa 480 t->maybeWrite(this);
cd748f27 481}
482
6a566b9c 483void
d3b3ab85 484CossSwapDir::sync()
6a566b9c 485{
6a566b9c 486 CossMemBuf *t;
c94af0b9 487 dlink_node *m;
47f6e231 488 off_t end;
0b30d52d 489
490 /* First, flush pending IO ops */
b9ae18aa 491 io->sync();
0b30d52d 492
493 /* Then, flush any in-memory partial membufs */
62e76326 494
d3b3ab85 495 if (!membufs.head)
62e76326 496 return;
497
d3b3ab85 498 for (m = membufs.head; m; m = m->next) {
62e76326 499 t = (CossMemBuf *)m->data;
500
1a224843 501 if (t->flags.writing) {
bf8fe701 502 debugs(79, 1, "WARNING: sleeping for 5 seconds in storeCossSync()");
62e76326 503 sleep(5); /* XXX EEEWWW! */
1a224843 504 }
62e76326 505
62e76326 506 end = (t == current_membuf) ? current_offset : t->diskend;
507
47f6e231 508 if (end > t->diskstart)
b9ae18aa 509 theFile->write(new CossWrite(WriteRequest((char const *)&t->buffer, t->diskstart, end - t->diskstart, NULL), t));
510
511 /* and flush */
512 io->sync();
6a566b9c 513 }
514}
cd748f27 515
b9ae18aa 516void
517CossMemBuf::maybeWrite(CossSwapDir * SD)
1a224843 518{
b9ae18aa 519 describe(3, __LINE__);
520
521 if (!flags.full)
bf8fe701 522 debugs(79, 3, "membuf " << this << " not full");
b9ae18aa 523 else if (flags.writing)
bf8fe701 524 debugs(79, 3, "membuf " << this << " writing");
b9ae18aa 525 else if (lockcount)
bf8fe701 526 debugs(79, 3, "membuf " << this << " lockcount=" << lockcount);
1a224843 527 else
b9ae18aa 528 write(SD);
cd748f27 529}
530
b9ae18aa 531void
532CossMemBuf::write(CossSwapDir * SD)
cd748f27 533{
b9ae18aa 534 StoreFScoss::GetInstance().stats.stripe_write.ops++;
4a7a3d56 535 debugs(79, 3, "CossMemBuf::write: offset " << diskstart << ", len " << (diskend - diskstart));
b9ae18aa 536 flags.writing = 1;
537 /* XXX Remember that diskstart/diskend are block offsets! */
538 SD->theFile->write(new CossWrite(WriteRequest((char const *)&buffer, diskstart, diskend - diskstart, NULL), this));
cd748f27 539}
540
b9ae18aa 541CossMemBuf *
47f6e231 542CossSwapDir::createMemBuf(off_t start, sfileno curfn, int *collision)
cd748f27 543{
1a224843 544 CossMemBuf *newmb;
545 CossMemBuf *t;
cd748f27 546 StoreEntry *e;
a4b8110e 547 dlink_node *m, *prev;
548 int numreleased = 0;
cd748f27 549
c94af0b9 550 CBDATA_INIT_TYPE_FREECB(CossMemBuf, NULL);
72711e31 551 newmb = cbdataAlloc(CossMemBuf);
cd748f27 552 newmb->diskstart = start;
4a7a3d56 553 debugs(79, 3, "CossSwapDir::createMemBuf: creating new membuf at " << newmb->diskstart);
bf8fe701 554 debugs(79, 3, "CossSwapDir::createMemBuf: at " << newmb);
1a224843 555 newmb->diskend = newmb->diskstart + COSS_MEMBUF_SZ;
cd748f27 556 newmb->flags.full = 0;
557 newmb->flags.writing = 0;
558 newmb->lockcount = 0;
b9ae18aa 559 newmb->SD = this;
6a566b9c 560 /* XXX This should be reversed, with the new buffer last in the chain */
b9ae18aa 561 dlinkAdd(newmb, &newmb->node, &membufs);
c94af0b9 562
563 /* Print out the list of membufs */
62e76326 564
bf8fe701 565 debugs(79, 3, "CossSwapDir::createMemBuf: membuflist:");
1a224843 566
b9ae18aa 567 for (m = membufs.head; m; m = m->next) {
62e76326 568 t = (CossMemBuf *)m->data;
b9ae18aa 569 t->describe(3, __LINE__);
c94af0b9 570 }
cd748f27 571
572 /*
6a566b9c 573 * Kill objects from the tail to make space for a new chunk
cd748f27 574 */
b9ae18aa 575 for (m = cossindex.tail; m; m = prev) {
1a224843 576 off_t o;
62e76326 577 prev = m->prev;
578 e = (StoreEntry *)m->data;
b9ae18aa 579 o = storeCossFilenoToDiskOffset(e->swap_filen);
62e76326 580
581 if (curfn == e->swap_filen)
582 *collision = 1; /* Mark an object alloc collision */
583
4989878c 584 if ((o >= (off_t)newmb->diskstart) && (o < (off_t)newmb->diskend)) {
5f33b71d 585 e->release();
62e76326 586 numreleased++;
587 } else
588 break;
cd748f27 589 }
62e76326 590
cd748f27 591 if (numreleased > 0)
bf8fe701 592 debugs(79, 3, "CossSwapDir::createMemBuf: this allocation released " << numreleased << " storeEntries");
62e76326 593
b9ae18aa 594 StoreFScoss::GetInstance().stats.stripes++;
1a224843 595
a4b8110e 596 return newmb;
cd748f27 597}
598
6a566b9c 599/*
600 * Creates the initial membuf after rebuild
601 */
602void
b9ae18aa 603CossSwapDir::startMembuf()
6a566b9c 604{
1a224843 605 CossMemBuf *newmb;
b9ae18aa 606 newmb = createMemBuf(current_offset, -1, NULL);
607 assert(!current_membuf);
608 current_membuf = newmb;
6a566b9c 609}
610
cd748f27 611/*
34fdf670 612 * Clean up any references from the SIO before it get's released.
cd748f27 613 */
d3b3ab85 614CossState::~CossState()
62e76326 615{}
1a224843 616
b9ae18aa 617void
618CossMemBuf::describe(int level, int line)
1a224843 619{
26ac0430
AJ
620 debugs(79, level, "membuf " << this << ", LC:" << std::setfill('0') <<
621 std::setw(2) << lockcount << ", ST:" <<
622 std::setw(10) << (unsigned long) diskstart << ", FL:" <<
623 (flags.full ? 'F' : '.') << (flags.writing ? 'W' : '.'));
1a224843 624}
625