Example #1
0
/*!
 * \brief Get a pointer to a particular buffer.
 */
static char *
DRead(struct ubik_trans *atrans, afs_int32 fid, int page)
{
    /* Read a page from the disk. */
    struct buffer *tb, *lastbuffer, *found_tb = NULL;
    afs_int32 code;
    struct ubik_dbase *dbase = atrans->dbase;

    calls++;
    lastbuffer = LruBuffer->lru_prev;

    /* Skip for write transactions for a clean page - this may not be the right page to use */
    if (MatchBuffer(lastbuffer, page, fid, atrans)
		&& (atrans->type == UBIK_READTRANS || lastbuffer->dirty)) {
	tb = lastbuffer;
	tb->lockers++;
	lastb++;
	return tb->data;
    }
    for (tb = phTable[pHash(page)]; tb; tb = tb->hashNext) {
	if (MatchBuffer(tb, page, fid, atrans)) {
	    if (tb->dirty || atrans->type == UBIK_READTRANS) {
		found_tb = tb;
		break;
	    }
	    /* Remember this clean page - we might use it */
	    found_tb = tb;
	}
    }
    /* For a write transaction, use a matching clean page if no dirty one was found */
    if (found_tb) {
	Dmru(found_tb);
	found_tb->lockers++;
	return found_tb->data;
    }

    /* can't find it */
    tb = newslot(dbase, fid, page);
    if (!tb)
	return 0;
    memset(tb->data, 0, UBIK_PAGESIZE);

    tb->lockers++;
    code =
	(*dbase->read) (dbase, fid, tb->data, page * UBIK_PAGESIZE,
			UBIK_PAGESIZE);
    if (code < 0) {
	tb->file = BADFID;
	Dlru(tb);
	tb->lockers--;
	ubik_print("Ubik: Error reading database file: errno=%d\n", errno);
	return 0;
    }
    ios++;

    /* Note that findslot sets the page field in the buffer equal to
     * what it is searching for.
     */
    return tb->data;
}
Example #2
0
/**
 * Invalidate any buffers that are duplicates of abuf. Duplicate buffers
 * can appear if a read transaction reads a page that is dirty, then that
 * dirty page is synced. The read transaction will skip over the dirty page,
 * and create a new buffer, and when the dirty page is synced, it will be
 * identical (except for contents) to the read-transaction buffer.
 */
static void
DedupBuffer(struct buffer *abuf)
{
    struct buffer *tb;
    for (tb = phTable[pHash(abuf->page)]; tb; tb = tb->hashNext) {
	if (tb->page == abuf->page && tb != abuf && tb->file == abuf->file
	    && tb->dbase == abuf->dbase) {

	    tb->file = BADFID;
	    Dlru(tb);
	}
    }
}
Example #3
0
/*!
 * \brief Mark an \p fid as invalid.
 */
int
udisk_Invalidate(struct ubik_dbase *adbase, afs_int32 afid)
{
    struct buffer *tb;
    int i;

    for (i = 0, tb = Buffers; i < nbuffers; i++, tb++) {
	if (tb->file == afid) {
	    tb->file = BADFID;
	    Dlru(tb);
	}
    }
    return 0;
}
Example #4
0
/*!
 * \brief Get a pointer to a particular buffer.
 */
static char *
DRead(struct ubik_trans *atrans, afs_int32 fid, int page)
{
    /* Read a page from the disk. */
    struct buffer *tb, *lastbuffer;
    afs_int32 code;
    struct ubik_dbase *dbase = atrans->dbase;

    calls++;
    lastbuffer = LruBuffer->lru_prev;

    if (MatchBuffer(lastbuffer, page, fid, atrans)) {
	tb = lastbuffer;
	tb->lockers++;
	lastb++;
	return tb->data;
    }
    for (tb = phTable[pHash(page)]; tb; tb = tb->hashNext) {
	if (MatchBuffer(tb, page, fid, atrans)) {
	    Dmru(tb);
	    tb->lockers++;
	    return tb->data;
	}
    }
    /* can't find it */
    tb = newslot(dbase, fid, page);
    if (!tb)
	return 0;
    memset(tb->data, 0, UBIK_PAGESIZE);

    tb->lockers++;
    code =
	(*dbase->read) (dbase, fid, tb->data, page * UBIK_PAGESIZE,
			UBIK_PAGESIZE);
    if (code < 0) {
	tb->file = BADFID;
	Dlru(tb);
	tb->lockers--;
	ubik_print("Ubik: Error reading database file: errno=%d\n", errno);
	return 0;
    }
    ios++;

    /* Note that findslot sets the page field in the buffer equal to
     * what it is searching for.
     */
    return tb->data;
}
Example #5
0
/*!
 * \brief Flush all modified buffers.
 */
static int
DAbort(struct ubik_trans *atrans)
{
    int i;
    struct buffer *tb;

    tb = Buffers;
    for (i = 0; i < nbuffers; i++, tb++) {
	if (tb->dirty) {
	    tb->dirty = 0;
	    tb->file = BADFID;
	    Dlru(tb);
	}
    }
    return 0;
}
Example #6
0
/*!
 * \brief Zap truncated pages.
 */
static int
DTrunc(struct ubik_trans *atrans, afs_int32 fid, afs_int32 length)
{
    afs_int32 maxPage;
    struct buffer *tb;
    int i;
    struct ubik_dbase *dbase = atrans->dbase;

    maxPage = (length + UBIK_PAGESIZE - 1) >> UBIK_LOGPAGESIZE;	/* first invalid page now in file */
    for (i = 0, tb = Buffers; i < nbuffers; i++, tb++) {
	if (tb->page >= maxPage && tb->file == fid && tb->dbase == dbase) {
	    tb->file = BADFID;
	    Dlru(tb);
	}
    }
    return 0;
}