/*! * \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; }
/*! * \brief Same as DRead(), only do not even try to read the page. */ static char * DNew(struct ubik_trans *atrans, afs_int32 fid, int page) { struct buffer *tb; struct ubik_dbase *dbase = atrans->dbase; if ((tb = newslot(dbase, fid, page)) == 0) return NULL; tb->lockers++; memset(tb->data, 0, UBIK_PAGESIZE); return tb->data; }
/*! * \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; }
void * DNew(afs_int32 *fid, int page) { /* Same as read, only do *not* even try to read the page, * since it probably doesn't exist. */ struct buffer *tb; ObtainWriteLock(&afs_bufferLock); if ((tb = newslot(fid, page, 0)) == 0) { ReleaseWriteLock(&afs_bufferLock); return 0; } ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); ReleaseWriteLock(&tb->lock); return tb->data; }
/* Same as read, only do *not* even try to read the page, * since it probably doesn't exist. */ int DNew(dir_file_t dir, int page, struct DirBuffer *entry) { struct buffer *tb; memset(entry,0, sizeof(struct DirBuffer)); ObtainWriteLock(&afs_bufferLock); if ((tb = newslot(dir, page, 0)) == 0) { ReleaseWriteLock(&afs_bufferLock); return EIO; } ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); ReleaseWriteLock(&tb->lock); entry->buffer = tb; entry->data = tb->data; return 0; }
/* -------------------------------------------------------------------- */ int newlog(void) { int ourSlot, i, v; /* ulong newpointer; */ /* * get a new slot for this user */ thisSlot = newslot(); if (thisSlot == ERROR) { thisSlot = 0; return(ERROR); } ourSlot = logTab[thisSlot].ltlogSlot; /* * Fill in the account. */ v = logBuf.VERIFIED; getLog(&logBuf, ourSlot); memset(&logBuf, 0, sizeof(logBuf)); setlogconfig(); #ifdef GOODBYE /* Moved to new user */ strcpy(logBuf.lbname, fullnm); strcpy(logBuf.lbin, in); strcpy(logBuf.lbpw, pw); #endif logBuf.surname[0] = '\0'; /* no starting surname */ logBuf.title [0] = '\0'; /* no starting title */ logBuf.forward[0] = '\0'; /* no starting forwarding */ logBuf.lbflags.L_INUSE = TRUE; logBuf.lbflags.PROBLEM = cfg.user[D_PROBLEM]; logBuf.lbflags.PERMANENT = cfg.user[D_PERMANENT]; logBuf.lbflags.NOACCOUNT = cfg.user[D_NOACCOUNT]; logBuf.lbflags.NETUSER = cfg.user[D_NETWORK]; logBuf.lbflags.NOMAIL = cfg.user[D_NOMAIL]; logBuf.lbflags.AIDE = cfg.user[D_AIDE]; /* aide = cfg.user[D_AIDE]; */ logBuf.lbflags.SYSOP = cfg.user[D_SYSOP]; /* sysop = cfg.user[D_SYSOP]; */ logBuf.BOARDERS = cfg.user[D_BOARDER]; logBuf.VERIFIED = v; /* logBuf.IBMGRAPH = FALSE; */ logBuf.DISPLAYTS = TRUE; logBuf.SUBJECTS = TRUE; logBuf.SIGNATURES = TRUE; logBuf.TWIRLY = FALSE; logBuf.VERBOSE = FALSE; logBuf.MSGPAUSE = FALSE; logBuf.MSGCLS = FALSE; /* should this be a cfg.user thing? */ logBuf.MINIBIN = TRUE; logBuf.ROOMINFO = TRUE; logBuf.HALLTELL = TRUE; /* elegia */ strcpy(logBuf.prompt, cfg.prompt); strcpy(logBuf.dstamp, cfg.datestamp); strcpy(logBuf.vdstamp, cfg.vdatestamp); strcpy(logBuf.netPrefix, cfg.netPrefix); strcpy(logBuf.msg_header, cfg.msg_header); strcpy(logBuf.vmsg_header, cfg.vmsg_header); #ifdef GOODBYE for (i = 1; i < MAXVISIT; i++) { logBuf.lbvisit[i] = cfg.oldest; } logBuf.lbvisit[ 0 ]= cfg.newest; logBuf.lbvisit[ (MAXVISIT-1) ]= cfg.oldest; #endif for (i = 0; i < MAXROOMS; i++) { logBuf.newpointer[i] = cfg.oldest; } initroomgen(); /**********************************************************************/ /* Icky Hack designed to make #oldcount functional */ /**********************************************************************/ #ifdef GOODBYE if (cfg.oldcount) { newpointer = (cfg.newest - cfg.oldcount); if (newpointer < cfg.oldest) newpointer = cfg.oldest; logBuf.lbvisit[0] = newpointer; /* pushed down later by setlbvisit() */ for (i = 0; i < MAXROOMS; i++) { logBuf.lbroom[i].lvisit = 0; /* becomes==1 later by setlbvisit() */ } } #endif /**********************************************************************/ /* ^^^ Disgusting? Wasn't it? ^^^ Hope it works! */ /**********************************************************************/ cleargroupgen(); /* * put user into group NULL */ logBuf.groups[0] = grpBuf.group[0].groupgen; /* * put user into auto-add groups */ for (i=0; i<MAXGROUPS; i++) { if (grpBuf.group[i].autoAdd) { logBuf.groups[i] = grpBuf.group[i].groupgen; } } /* * accurate read-userlog for first time call */ logBuf.callno = cfg.callno + 1; logBuf.credits = (float)0; #ifdef GOODBYE /* This stuff moved to newUser() time(&logBuf.calltime); setsysconfig(); /* * trap it */ sprintf( msgBuf->mbtext, "New user %s", logBuf.lbname); trap(msgBuf->mbtext, T_LOGIN); loggedIn = TRUE; slideLTab(thisSlot); storeLog(); #endif /* End of stuff moved to newUser() */ return(TRUE); }
/** * read a page out of a directory object. * * @param[in] fid directory object fid * @param[in] page page in hash table to be read * * @return pointer to requested page in directory cache * @retval NULL read failed */ void * DRead(afs_int32 *fid, int page) { /* Read a page from the disk. */ struct buffer *tb, *tb2, **bufhead; ObtainWriteLock(&afs_bufferLock); calls++; #define bufmatch(tb) (tb->page == page && FidEq(tb->fid, fid)) #define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);} /* this apparently-complicated-looking code is simply an example of * a little bit of loop unrolling, and is a standard linked-list * traversal trick. It saves a few assignments at the the expense * of larger code size. This could be simplified by better use of * macros. With the use of these LRU queues, the old one-cache is * probably obsolete. */ if ((tb = phTable[pHash(fid)])) { /* ASSMT HERE */ if (bufmatch(tb)) { ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = ++timecounter; ReleaseWriteLock(&tb->lock); return tb->data; } else { bufhead = &(phTable[pHash(fid)]); while ((tb2 = tb->hashNext)) { if (bufmatch(tb2)) { buf_Front(bufhead, tb, tb2); ObtainWriteLock(&tb2->lock); tb2->lockers++; ReleaseWriteLock(&afs_bufferLock); tb2->accesstime = ++timecounter; ReleaseWriteLock(&tb2->lock); return tb2->data; } if ((tb = tb2->hashNext)) { /* ASSIGNMENT HERE! */ if (bufmatch(tb)) { buf_Front(bufhead, tb2, tb); ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); tb->accesstime = ++timecounter; ReleaseWriteLock(&tb->lock); return tb->data; } } else break; } } } else tb2 = NULL; /* can't find it */ /* The last thing we looked at was either tb or tb2 (or nothing). That * is at least the oldest buffer on one particular hash chain, so it's * a pretty good place to start looking for the truly oldest buffer. */ tb = newslot(fid, page, (tb ? tb : tb2)); ios++; ObtainWriteLock(&tb->lock); tb->lockers++; ReleaseWriteLock(&afs_bufferLock); if (ReallyRead(tb->fid, tb->page, tb->data)) { tb->lockers--; FidZap(tb->fid); /* disaster */ ReleaseWriteLock(&tb->lock); return 0; } /* Note that findslot sets the page field in the buffer equal to * what it is searching for. */ ReleaseWriteLock(&tb->lock); return tb->data; }