/** * @fn void incore(int dev, bc_daddr_t blkno) * Test si le bloc demandé est associé à un buffer * * See if the block is associated with some buffer * (mainly to avoid getting hung up on a wait in breada) * @param dev : device (major+minor) * @param blkno : numéro de bloc * @return 1 si le bloc est associé à un buffer, sinon 0 */ int incore(int dev, bc_daddr_t blkno) { struct buf *bp; struct buf *dp; dp = bhash(dev, blkno); for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) if (bp->b_blkno==blkno && bp->b_dev==dev) return(1); return(0); }
/** * @fn struct buf *getblk(int dev, bc_daddr_t blkno) * Permet de récuperer un buffer en fonction d'un device et d'un numéro de bloc. * S'il n'existe pas dans la table de hachage des buffers précédemment alloués, un buffer est * retiré de la liste des buffers disponibles et alloué au device et au bloc correspondant * * Assign a buffer for the given block. If the appropriate * block is already associated, return it; otherwise search * for the oldest non-busy buffer and reassign it. * @param dev : device (major+minor) * @param blkno : numéro de bloc * @return le buffer associé au device dev et de numéro de bloc blkno */ struct buf *getblk(int dev, bc_daddr_t blkno) { struct buf *bp; struct buf *dp; loop: dp = bhash(dev, blkno); // Error if (dp == NULL) { } for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) { if (bp->b_blkno != blkno || bp->b_dev != dev) { continue; } spl(BDINHB); if (bp->b_flags & B_BUSY) { bp->b_flags |= B_WANTED; tsleep(PRIBIO + 1, (caddr_t) bp); goto loop; } spl(NORMAL); notavail(bp); return bp; } spl(BDINHB); if (bfreelist.av_forw == &bfreelist) { bfreelist.b_flags |= B_WANTED; tsleep(PRIBIO + 1, (caddr_t) &bfreelist); goto loop; } spl(NORMAL); bp = bfreelist.av_forw; notavail(bp); if (bp->b_flags & B_DELWRI) { bp->b_flags |= B_ASYNC; bwrite(bp); goto loop; } bp->b_flags = B_BUSY; bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; bp->b_back = dp; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; bp->b_blkno = blkno; return bp; }
building *new_building(const struct building_type * btype, region * r, const struct locale * lang) { building **bptr = &r->buildings; building *b = (building *)calloc(1, sizeof(building)); static bool init_lighthouse = false; static const struct building_type *bt_lighthouse = 0; const char *bname = 0; char buffer[32]; if (!init_lighthouse) { bt_lighthouse = bt_find("lighthouse"); init_lighthouse = true; } b->no = newcontainerid(); bhash(b); b->type = btype; b->region = r; while (*bptr) bptr = &(*bptr)->next; *bptr = b; if (b->type == bt_lighthouse) { r->flags |= RF_LIGHTHOUSE; } if (b->type->name) { bname = LOC(lang, buildingtype(btype, b, 0)); } if (!bname) { bname = LOC(lang, btype->_name); } if (!bname) { bname = LOC(lang, parameters[P_GEBAEUDE]); } if (!bname) { bname = parameters[P_GEBAEUDE]; } assert(bname); slprintf(buffer, sizeof(buffer), "%s %s", bname, buildingid(b)); b->name = _strdup(bname); return b; }
/* * del_root() * * Description: * Delete the current root bnode. * Input Variable(s): * struct hfs_bnode_ref *root: reference to the root bnode * Output Variable(s): * NONE * Returns: * int: 0 on success, error code on failure * Preconditions: * 'root' refers to the root bnode with HFS_LOCK_WRITE access. * None of 'root's children are held with HFS_LOCK_WRITE access. * Postconditions: * The current 'root' node is removed from the tree and the depth * of the tree is reduced by one. * If 'root' is an index node with exactly one child, then that * child becomes the new root of the tree. * If 'root' is an empty leaf node the tree becomes empty. * Upon return access to 'root' is relinquished. */ static int del_root(struct hfs_bnode_ref *root) { struct hfs_btree *tree = root->bn->tree; struct hfs_bnode_ref child; hfs_u32 node; if (root->bn->ndNRecs > 1) { return 0; } else if (root->bn->ndNRecs == 0) { /* tree is empty */ tree->bthRoot = 0; tree->root = NULL; tree->bthRoot = 0; tree->bthFNode = 0; tree->bthLNode = 0; --tree->bthDepth; tree->dirt = 1; if (tree->bthDepth) { hfs_warn("hfs_bdelete: empty tree with bthDepth=%d\n", tree->bthDepth); goto bail; } return hfs_bnode_free(root); } else if (root->bn->ndType == ndIndxNode) { /* tree is non-empty */ node = hfs_get_hl(bkey_record(bnode_datastart(root->bn))); child = hfs_bnode_find(tree, node, HFS_LOCK_READ); if (!child.bn) { hfs_warn("hfs_bdelete: can't read child node.\n"); goto bail; } child.bn->sticky = HFS_STICKY; if (child.bn->next) { child.bn->next->prev = child.bn->prev; } if (child.bn->prev) { child.bn->prev->next = child.bn->next; } if (bhash(tree, child.bn->node) == child.bn) { bhash(tree, child.bn->node) = child.bn->next; } child.bn->next = NULL; child.bn->prev = NULL; tree->bthRoot = child.bn->node; tree->root = child.bn; /* re-assign bthFNode and bthLNode if the new root is a leaf node. */ if (child.bn->ndType == ndLeafNode) { tree->bthFNode = node; tree->bthLNode = node; } hfs_bnode_relse(&child); tree->bthRoot = node; --tree->bthDepth; tree->dirt = 1; if (!tree->bthDepth) { hfs_warn("hfs_bdelete: non-empty tree with " "bthDepth == 0\n"); goto bail; } return hfs_bnode_free(root); /* marks tree dirty */ } hfs_bnode_relse(root); return 0; bail: hfs_bnode_relse(root); return -EIO; }