int fdir_creat (fbuf *dir, const char *name, AFSFid fid) { int ret; int i; unsigned npages; DirPage0 *page0; DirPage1 *page; int ind = 0; unsigned hash_value, next; assert (dir->len != 0); page0 = (DirPage0 *)fbuf_buf(dir); assert (page0); npages = ntohs(page0->header.pg_pgcount); if (npages < fbuf_len(dir) / AFSDIR_PAGESIZE) npages = fbuf_len(dir) / AFSDIR_PAGESIZE; if (find_entry (page0, name)) return EEXIST; hash_value = hashentry (name); next = page0->dheader.hash[hash_value]; for (i = 0; i < npages; ++i) { page = getpage (page0, i); ind = add_to_page (page0, page, i, name, fid, next); if (ind >= 0) break; } if (i == npages) { ret = create_new_page (&page, dir); if (ret) return ret; page0 = (DirPage0 *)fbuf_buf(dir); page0->header.pg_pgcount = htons(npages + 1); if (i < MAXPAGES) page0->dheader.map[i] = ENTRIESPERPAGE - 1; ind = add_to_page (page0, page, i, name, fid, next); assert (ind >= 0); } ind += i * ENTRIESPERPAGE; page0->dheader.hash[hash_value] = htons(ind + 1); return 0; }
int fdir_mkdir (fbuf *the_fbuf, AFSFid dot, AFSFid dot_dot) { DirPage0 *page0; DirPage1 *page; int ind; int i; int tmp; int ret; ret = create_new_page (&page, the_fbuf); if (ret) return ret; page0 = (DirPage0 *)fbuf_buf(the_fbuf); memset (&page0->dheader, 0, sizeof(page0->dheader)); tmp = ENTRIESPERPAGE - (sizeof(PageHeader) + sizeof(DirHeader)) / sizeof(DirEntry); page0->header.pg_freecount = tmp; page0->dheader.map[0] = tmp; page0->header.pg_pgcount = htons(1); for (i = 0; i < 13; ++i) set_used (page, i); assert (page0->dheader.hash[hashentry(".")] == 0); ind = add_to_page (page0, page, 0, ".", dot, 0); assert (ind >= 0); page0->dheader.hash[hashentry(".")] = htons(ind + 1); assert (page0->dheader.hash[hashentry("..")] == 0); ind = add_to_page (page0, page, 0, "..", dot_dot, 0); assert (ind >= 0); page0->dheader.hash[hashentry("..")] = htons(ind + 1); return 0; }
void* LinkerBlockAllocator::alloc() { if (free_block_list_ == nullptr) { create_new_page(); } FreeBlockInfo* block_info = reinterpret_cast<FreeBlockInfo*>(free_block_list_); if (block_info->num_free_blocks > 1) { FreeBlockInfo* next_block_info = reinterpret_cast<FreeBlockInfo*>( reinterpret_cast<char*>(free_block_list_) + block_size_); next_block_info->next_block = block_info->next_block; next_block_info->num_free_blocks = block_info->num_free_blocks - 1; free_block_list_ = next_block_info; } else { free_block_list_ = block_info->next_block; } memset(block_info, 0, block_size_); return block_info; }