Exemple #1
0
/* Delete a record. */
int gdbm_delete(GDBM_FILE dbf, datum key){
  assert(dbf);
  if(!key.dptr || key.dsize < 0){
    gdbm_errno = GDBM_ILLEGAL_DATA;
    return -1;
  }
  if(dbf->depot){
    if(!dpwritable(dbf->depot)){
      gdbm_errno = GDBM_READER_CANT_DELETE;
      return -1;
    }
    if(!dpout(dbf->depot, key.dptr, key.dsize)){
      gdbm_errno = gdbm_geterrno(dpecode);
      return -1;
    }
    if(dbf->syncmode && !dpsync(dbf->depot)){
      gdbm_errno = gdbm_geterrno(dpecode);
      return -1;
    }
  } else {
    if(!crwritable(dbf->curia)){
      gdbm_errno = GDBM_READER_CANT_DELETE;
      return -1;
    }
    if(!crout(dbf->curia, key.dptr, key.dsize)){
      gdbm_errno = gdbm_geterrno(dpecode);
      return -1;
    }
    if(dbf->syncmode && !crsync(dbf->curia)){
      gdbm_errno = gdbm_geterrno(dpecode);
      return -1;
    }
  }
  return 0;
}
Exemple #2
0
Fichier : fl.c Projet : sng7ca/ygg
/* 
 * free file table entry:
 * -- puts it into free list head, O(1);
 * -- sets references to 0;
 */
void fput(struct fl *fp)
{
	struct ind *in;
	
	if (--fp->rc)
		/* other fd's remain */
		return;
	/* no fd's remain */
	/* -> free list head */
	crin();
	fp->nxt = ftb.fhd;
	ftb.fhd = fp;
	crout();
	/* determine type */
	switch(fp->t) {	/* normally faster then if */
	case FPP:
		rmpp(fp);
		break;
	case FIND:
		in = fp->in;
		ilck(in);
		/* close device if needed */
		if (in->t == FCHR)
			devtb[in->mj].close(in->mn);
		iput(in);	/* unlck */
		break;
	default:
		kpanic("fput: fp->t == ?\n");
	}
}
Exemple #3
0
Fichier : bch.c Projet : sng7ca/ygg
/* release buffer */
void brelse(struct bf *b)
{
	crin();
	/* add to free list tail (MRU) */
	b->fprv = bch.ftl;
	b->fnxt = 0;
	if (bch.ftl)
		bch.ftl->fnxt = b;
	else
		bch.fhd = b;
	bch.ftl = b;
	/* unlock */
	b->flg &= ~LCKB;
	/* wake waiting for this/any buffer */
	wakeup(b);
	wakeup(&bch);
	crout();
}
Exemple #4
0
Fichier : bch.c Projet : sng7ca/ygg
/* 
 * get block, 4 scenarios:
 * -- buf is in cache & busy -- sleep until released,
 *    then goto start (to avoid 2 processes with same block get it);
 * -- buf is in cache & free -- remove from free list, return buf;
 * -- buf isn't in cache & free list is empty -- sleep until first
 *    buf released, then goto start (to avoid 2 processes with same
 *    block make 2 buffers for one block);
 * -- buf isn't in cache & free buf available -- get it, remove
 *    from free list, move from old to new hash queue, return buf;
 */
static struct bf *getblk(unsigned blk)
{
	register struct bf *b, **hq;

	hq = &bch.ht[blk % NBFHT];	/* calc once */
lp:	/* is in cache? */
	crin();
	for (b = *hq; b; b = b->hnxt)
		if (b->blk == blk) {
			if (b->flg & LCKB) {
				/* scenario 0 */
				crout();
				sleep(b);
				goto lp;
			}
			/* scenario 1 */
			/* rm from free list */
			if (b->fprv)
				b->fprv->fnxt = b->fnxt;
			else
				bch.fhd = b->fnxt;
			if (b->fnxt)
				b->fnxt->fprv = b->fprv;
			else
				bch.ftl = b->fprv;
			/* lock */
			b->flg |= LCKB;
			crout();
			return b;
		}
	/* not in cache, try alloc free buf from head */
	b = bch.fhd;
	if (!b) {
		/* scenario 2 */
		crout();
		sleep(&bch);
		goto lp;
	}
	/* scenario 3 */
	/* rm from free list head (LRU) */
	if (b->fnxt)
		b->fnxt->fprv = 0;
	else
		bch.ftl = 0;
	bch.fhd = b->fnxt;
	/* 
	 * move between queues; I don't check if it's needed:
	 * -- for most cases it's needed;
	 * -- when no, buf will move to head according MRU;
	 */
	/* rm from old */
	if (b->hprv)
		b->hprv->hnxt = b->hnxt;
	else
		bch.ht[b->blk % NBFHT] = b->hnxt;
	if (b->hnxt)
		b->hnxt->hprv = b->hprv;
	/* add to head of new */
	b->hprv = 0;
	b->hnxt = *hq;
	if (*hq)
		(*hq)->hprv = b;
	*hq = b;
	/* lock */
	b->blk = blk;
	b->flg |= LCKB;
	b->flg &= ~(DRTB | VLDB);
	crout();
	return b;
}