afs_int32 AllocBlock(struct ubik_trans *at) { afs_int32 code; afs_int32 temp; struct prentry tentry; if (cheader.freePtr) { /* allocate this dude */ temp = ntohl(cheader.freePtr); code = pr_ReadEntry(at, 0, temp, &tentry); if (code) return 0; cheader.freePtr = htonl(tentry.next); code = pr_Write(at, 0, 8, (char *)&cheader.freePtr, sizeof(cheader.freePtr)); if (code != 0) return 0; return temp; } else { /* hosed, nothing on free list, grow file */ temp = ntohl(cheader.eofPtr); /* remember this guy */ cheader.eofPtr = htonl(temp + ENTRYSIZE); code = pr_Write(at, 0, 12, (char *)&cheader.eofPtr, sizeof(cheader.eofPtr)); if (code != 0) return 0; return temp; } }
afs_int32 AllocID(struct ubik_trans *at, afs_int32 flag, afs_int32 *aid) { /* allocs an id from the proper area of address space, based on flag */ afs_int32 code = 1; afs_int32 i = 0; int maxcount = 50; /* to prevent infinite loops */ if (flag & PRGRP) { *aid = ntohl(cheader.maxGroup); /* Check for PRBADID to avoid wrap-around. */ while (code && i < maxcount && *aid != PRBADID) { --(*aid); code = FindByID(at, *aid); i++; } if (code) return PRNOIDS; cheader.maxGroup = htonl(*aid); code = pr_Write(at, 0, 16, (char *)&cheader.maxGroup, sizeof(cheader.maxGroup)); if (code) return PRDBFAIL; return PRSUCCESS; } else if (flag & PRFOREIGN) { *aid = ntohl(cheader.maxForeign); while (code && i < maxcount) { ++(*aid); code = FindByID(at, *aid); i++; } if (code) return PRNOIDS; cheader.maxForeign = htonl(*aid); code = pr_Write(at, 0, 24, (char *)&cheader.maxForeign, sizeof(cheader.maxForeign)); if (code) return PRDBFAIL; return PRSUCCESS; } else { *aid = ntohl(cheader.maxID); while (code && i < maxcount && *aid != 0x7fffffff) { ++(*aid); code = FindByID(at, *aid); i++; } if (code) return PRNOIDS; cheader.maxID = htonl(*aid); code = pr_Write(at, 0, 20, (char *)&cheader.maxID, sizeof(cheader.maxID)); if (code) return PRDBFAIL; return PRSUCCESS; } }
afs_int32 AddToNameHash(struct ubik_trans *tt, char *aname, afs_int32 loc) { /* add to name hash */ afs_int32 code; afs_int32 i; struct prentry tentry; i = NameHash(aname); memset(&tentry, 0, sizeof(tentry)); code = pr_ReadEntry(tt, 0, loc, &tentry); if (code) return PRDBFAIL; tentry.nextName = ntohl(cheader.nameHash[i]); cheader.nameHash[i] = htonl(loc); code = pr_WriteEntry(tt, 0, loc, &tentry); if (code) return PRDBFAIL; code = pr_Write(tt, 0, 72 + i * 4, (char *)&cheader.nameHash[i], sizeof(cheader.nameHash[i])); if (code) return PRDBFAIL; return PRSUCCESS; }
afs_int32 AddToIDHash(struct ubik_trans *tt, afs_int32 aid, afs_int32 loc) { /* add entry at loc designated by aid to id hash table */ afs_int32 code; afs_int32 i; struct prentry tentry; if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT; i = IDHash(aid); memset(&tentry, 0, sizeof(tentry)); code = pr_ReadEntry(tt, 0, loc, &tentry); if (code) return PRDBFAIL; tentry.nextID = ntohl(cheader.idHash[i]); cheader.idHash[i] = htonl(loc); code = pr_WriteEntry(tt, 0, loc, &tentry); if (code) return PRDBFAIL; code = pr_Write(tt, 0, 72 + HASHSIZE * 4 + i * 4, (char *)&cheader.idHash[i], sizeof(cheader.idHash[i])); if (code) return PRDBFAIL; return PRSUCCESS; }
afs_int32 RemoveFromOrphan(struct ubik_trans *at, afs_int32 gid) { /* remove gid from the orphan list */ afs_int32 code; afs_int32 loc; afs_int32 nptr; struct prentry tentry; struct prentry bentry; loc = FindByID(at, gid); if (!loc) return PRNOENT; code = pr_ReadEntry(at, 0, loc, &tentry); if (code != 0) return PRDBFAIL; if (cheader.orphan == htonl(loc)) { cheader.orphan = htonl(tentry.nextOwned); tentry.nextOwned = 0; code = pr_Write(at, 0, 32, (char *)&cheader.orphan, sizeof(cheader.orphan)); if (code != 0) return PRDBFAIL; code = pr_WriteEntry(at, 0, loc, &tentry); if (code != 0) return PRDBFAIL; return PRSUCCESS; } nptr = ntohl(cheader.orphan); memset(&bentry, 0, sizeof(bentry)); loc = 0; while (nptr != 0) { code = pr_ReadEntry(at, 0, nptr, &tentry); if (code != 0) return PRDBFAIL; if (gid == tentry.id) { /* found it */ bentry.nextOwned = tentry.nextOwned; tentry.nextOwned = 0; code = pr_WriteEntry(at, 0, loc, &bentry); if (code != 0) return PRDBFAIL; code = pr_WriteEntry(at, 0, nptr, &tentry); if (code != 0) return PRDBFAIL; return PRSUCCESS; } loc = nptr; nptr = tentry.nextOwned; memcpy(&bentry, &tentry, sizeof(tentry)); } return PRSUCCESS; }
afs_int32 RemoveFromIDHash(struct ubik_trans *tt, afs_int32 aid, afs_int32 *loc) /* ??? in case ID hashed twice ??? */ { /* remove entry designated by aid from id hash table */ afs_int32 code; afs_int32 current, trail, i; struct prentry tentry; struct prentry bentry; if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT; i = IDHash(aid); current = ntohl(cheader.idHash[i]); memset(&tentry, 0, sizeof(tentry)); memset(&bentry, 0, sizeof(bentry)); trail = 0; if (current == 0) return PRSUCCESS; /* already gone */ code = pr_ReadEntry(tt, 0, current, &tentry); if (code) return PRDBFAIL; while (aid != tentry.id) { osi_Assert(trail != current); trail = current; current = tentry.nextID; if (current == 0) break; code = pr_ReadEntry(tt, 0, current, &tentry); if (code) return PRDBFAIL; } if (current == 0) return PRSUCCESS; /* we didn't find him, so he's already gone */ if (trail == 0) { /* it's the first entry! */ cheader.idHash[i] = htonl(tentry.nextID); code = pr_Write(tt, 0, 72 + HASHSIZE * 4 + i * 4, (char *)&cheader.idHash[i], sizeof(cheader.idHash[i])); if (code) return PRDBFAIL; } else { code = pr_ReadEntry(tt, 0, trail, &bentry); if (code) return PRDBFAIL; bentry.nextID = tentry.nextID; code = pr_WriteEntry(tt, 0, trail, &bentry); if (code) return PRDBFAIL; } *loc = current; return PRSUCCESS; }
afs_int32 RemoveFromNameHash(struct ubik_trans *tt, char *aname, afs_int32 *loc) { /* remove from name hash */ afs_int32 code; afs_int32 current, trail, i; struct prentry tentry; struct prentry bentry; i = NameHash(aname); current = ntohl(cheader.nameHash[i]); memset(&tentry, 0, sizeof(tentry)); memset(&bentry, 0, sizeof(bentry)); trail = 0; if (current == 0) return PRSUCCESS; /* already gone */ code = pr_ReadEntry(tt, 0, current, &tentry); if (code) return PRDBFAIL; while (strcmp(aname, tentry.name)) { osi_Assert(trail != current); trail = current; current = tentry.nextName; if (current == 0) break; code = pr_ReadEntry(tt, 0, current, &tentry); if (code) return PRDBFAIL; } if (current == 0) return PRSUCCESS; /* we didn't find him, already gone */ if (trail == 0) { /* it's the first entry! */ cheader.nameHash[i] = htonl(tentry.nextName); code = pr_Write(tt, 0, 72 + i * 4, (char *)&cheader.nameHash[i], sizeof(cheader.nameHash[i])); if (code) return PRDBFAIL; } else { code = pr_ReadEntry(tt, 0, trail, &bentry); if (code) return PRDBFAIL; bentry.nextName = tentry.nextName; code = pr_WriteEntry(tt, 0, trail, &bentry); if (code) return PRDBFAIL; } *loc = current; return PRSUCCESS; }
afs_int32 FreeBlock(struct ubik_trans *at, afs_int32 pos) { /* add a block of storage to the free list */ afs_int32 code; struct prentry tentry; memset(&tentry, 0, sizeof(tentry)); tentry.next = ntohl(cheader.freePtr); tentry.flags |= PRFREE; cheader.freePtr = htonl(pos); code = pr_Write(at, 0, 8, (char *)&cheader.freePtr, sizeof(cheader.freePtr)); if (code != 0) return code; code = pr_WriteEntry(at, 0, pos, &tentry); if (code != 0) return code; return PRSUCCESS; }
int pr_WriteCoEntry(struct ubik_trans *tt, afs_int32 afd, afs_int32 pos, struct contentry *tentry) { afs_int32 code; afs_int32 i; struct contentry nentry; if (ntohl(1) != 1) { /* No need to swap */ memset(&nentry, 0, sizeof(nentry)); /* make reseved fields zero */ nentry.flags = htonl(tentry->flags); nentry.id = htonl(tentry->id); nentry.cellid = htonl(tentry->cellid); nentry.next = htonl(tentry->next); for (i = 0; i < COSIZE; i++) nentry.entries[i] = htonl(tentry->entries[i]); tentry = &nentry; } code = pr_Write(tt, afd, pos, (char *)tentry, sizeof(struct contentry)); return (code); }
int pr_WriteEntry(struct ubik_trans *tt, afs_int32 afd, afs_int32 pos, struct prentry *tentry) { afs_int32 code; afs_int32 i; struct prentry nentry; if (ntohl(1) != 1) { /* Need to swap bytes. */ memset(&nentry, 0, sizeof(nentry)); /* make sure reseved fields are zero */ nentry.flags = htonl(tentry->flags); nentry.id = htonl(tentry->id); nentry.cellid = htonl(tentry->cellid); nentry.next = htonl(tentry->next); nentry.nextID = htonl(tentry->nextID); nentry.nextName = htonl(tentry->nextName); nentry.owner = htonl(tentry->owner); nentry.creator = htonl(tentry->creator); nentry.ngroups = htonl(tentry->ngroups); nentry.nusers = htonl(tentry->nusers); nentry.count = htonl(tentry->count); nentry.instance = htonl(tentry->instance); nentry.owned = htonl(tentry->owned); nentry.nextOwned = htonl(tentry->nextOwned); nentry.parent = htonl(tentry->parent); nentry.sibling = htonl(tentry->sibling); nentry.child = htonl(tentry->child); strncpy(nentry.name, tentry->name, PR_MAXNAMELEN); #ifdef PR_REMEMBER_TIMES nentry.createTime = htonl(tentry->createTime); nentry.addTime = htonl(tentry->addTime); nentry.removeTime = htonl(tentry->removeTime); nentry.changeTime = htonl(tentry->changeTime); #endif for (i = 0; i < PRSIZE; i++) nentry.entries[i] = htonl(tentry->entries[i]); tentry = &nentry; } code = pr_Write(tt, afd, pos, (char *)tentry, sizeof(struct prentry)); return (code); }