int main() { struct mallinfo status; void *p1, *p2; status = mallinfo(); // malloc_status(status); /* Allocate small block */ printf("\nAllocating 1000 bytes\n"); p1 = alloc_block(1000); status = mallinfo(); malloc_status(status); getchar(); printf("\nFree 1000 bytes\n"); free(p1); status = mallinfo(); malloc_status(status); getchar(); /* Allocate huge block */ printf("\nAllocating 128KB\n"); p2 = alloc_block(140*1024); /* 140 KB */ status = mallinfo(); malloc_status(status); getchar(); printf("\nFree 140KB\n"); free(p2); status = mallinfo(); malloc_status(status); }
//get an empty dir_entry under a dir struct dir_entry *empty_dir(int direct_inum) { inode_cache *dir = read_inode(direct_inum); if (dir->data.type!=INODE_DIRECTORY) return NULL; int i,block_num; //check direct blocks for (i=0; i<NUM_DIRECT; i++) { if (dir->data.direct[i]<=0) break; block_num = dir->data.direct[i]; block_cache *b = read_block(block_num); struct dir_entry *d = (struct dir_entry*)(b->data); int j; for (j=0; j<DIRS_PER_BLOCK; j++) { if (d[j].inum==0) { b->dirty = 1; return &d[j]; } } } if (i<NUM_DIRECT) { dir->data.direct[i] = alloc_block(); block_num = dir->data.direct[i]; block_cache *b = read_block(block_num); b->dirty = 1; return (struct dir_entry*)(b->data); } //check indirect bloc if (dir->data.indirect==0) { dir->data.indirect = alloc_block(); } block_num = dir->data.indirect; block_cache *b = read_block(block_num); int j; block_cache *tmp; for (j=0; j<BLOCKSIZE; j+=4) { block_num = *(int*)(b->data+j); if (block_num!=0) { tmp = read_block(block_num); struct dir_entry *d = (struct dir_entry*)(tmp->data); int k; for (k=0; k<DIRS_PER_BLOCK; k++) { if (d[j].inum==0) { tmp->dirty = 1; return d; } } } else break; } if (j==BLOCKSIZE) return NULL; block_num = alloc_block(); *(int*)(b->data+j) = block_num; b->dirty = 1; tmp = read_block(block_num); tmp->dirty = 1; return (struct dir_entry*)(tmp->data); }
int main(int argc,char *argv[]){ int i; FILE * disk=fopen("data.disk","wb"); memset(bitmap_d.mask,0,sizeof(bitmap_d.mask)); memset(directory_d.entries,0,sizeof(directory_d.entries)); for(i=0;i<257;i++) SET_BIT(i); for(i=1;i<argc;i++){ FILE *fp=fopen(argv[i],"rb"); //printf("argv[%d]=%s\n",i,argv[i]); /*if(!fp) { system("pwd"); perror("failed:"); }*/ assert(fp); fseek(fp,0,SEEK_END); unsigned int filesz=ftell(fp); rewind(fp); strcpy(directory_d.entries[i-1].filename,argv[i]); directory_d.entries[i-1].file_size=filesz; unsigned int inode_index=alloc_block(); directory_d.entries[i-1].inode_offset=inode_index; //write in file data struct inode node; char buf[512]; int count=0; while(fread(buf,1,512,fp)){ unsigned int bias=alloc_block(); node.data_block_offsets[count]=bias; fseek(disk,bias*512,SEEK_SET); fwrite(buf,1,512,disk); rewind(disk); count++; } //write in inode fseek(disk,inode_index*512,SEEK_SET); fwrite(&node,1,512,disk); rewind(disk); fclose(fp); } fseek(disk,512*256,SEEK_SET); fwrite(directory_d.entries,1,512,disk); rewind(disk); fseek(disk,0,SEEK_SET); fwrite(bitmap_d.mask,1,512*256,disk); rewind(disk); fclose(disk); return 0; }
static int hash_add_entry (uint8_t *string, HASH_TABLE *htbl, void *data) { hash_bucket_t *hentry = NULL; int bucket = -1; if (!htbl) return NULL; if (!(hentry = find_hash_entry (string, htbl))) { bucket = htbl->hash_index_gen (string); if (bucket > htbl->nbuckets) { return -1; } hentry = htbl->bucket_array[bucket]; while (hentry && hentry->next) hentry = hentry->next; if (hentry) { hentry->next = alloc_block (htbl->hmem_pool_id); if (!hentry->next) { return -1; } hentry = hentry->next; } else { htbl->bucket_array[bucket] = alloc_block (htbl->hmem_pool_id); hentry = htbl->bucket_array[bucket]; if (!hentry) return -1; } hentry->data = data; hentry->next = NULL; hentry->key = malloc (htbl->key_len); { int i = 0; for (; i < htbl->key_len; i++) hentry->key[i] = string[i]; } htbl->nentries++; } return 0; }
/* splits the index node at the given level of the given path */ PRIVATE int split_index_node(struct root *r, struct path *p, int level) { int slot = p->slots[level]; struct cache *left = p->nodes[level]; int nritems = left->u.node.header.nritems; int nrstaying = nritems/2; /* smaller half stays on the left */ int nrmoving = nritems - nrstaying; /* larger half moves to the right */ struct cache *right; blocknr_t rightnr; assert(left->will_write); /* was ensured on tree descent */ rightnr = alloc_block(r->fs_info, left, left->u.node.header.type); if (!rightnr) return -ENOSPC; right = init_node(rightnr, left->u.node.header.type, level); if (!right) return -errno; if(is_root_level(level, p)) { /* no node above, so need to grow tree */ blocknr_t new_rootnr; struct cache *c; assert(level < MAX_LEVEL - 1); /* has room to add another level */ new_rootnr = alloc_block(r->fs_info, right, right->u.node.header.type); if (!new_rootnr) return -ENOSPC; c = init_node(new_rootnr, right->u.node.header.type, level + 1); if (!c) return -errno; p->nodes[level + 1] = c; p->slots[level + 1] = 0; /* path on the left node */ insert_key_ptr(r, p, level + 1, key_for(left, 0), left->write_blocknr); r->blocknr = new_rootnr; } memmove(&right->u.node.u.key_ptrs[0], /* move larger half to right node */ &left->u.node.u.key_ptrs[nrstaying], nrmoving * sizeof(struct key_ptr)); right->u.node.header.nritems = nrmoving; memset(&left->u.node.u.key_ptrs[nrstaying], 0, /* clear moved in left */ nrmoving * sizeof(struct key_ptr)); left->u.node.header.nritems = nrstaying; p->slots[level + 1]++; /* temporarily, for inserting in parent node */ insert_key_ptr(r, p, level + 1, key_for(right, 0), rightnr); if (slot >= nrstaying) { /* need to change path to the right */ p->nodes[level] = right; p->slots[level] = slot - nrstaying; put_block(left); /* free left since it's now off the path */ } else { p->slots[level + 1]--; /* path back to left node in parent node */ put_block(right); /* free right since it's not on the path */ } return SUCCESS; }
int file_get_block(struct File *f, uint32_t file_blockno, int *pblk) { if(file_blockno >= NDIRECT * ENTRY) { printf("\nFile Size Exceeded\n"); return -1; } if(file_blockno%ENTRY == 0) { f->f_direct[file_blockno/ENTRY] = super->tail_db; super->tail_db = super->tail_db + BLKSIZE; if(file_blockno/ENTRY > 0) { int addr = f->f_direct[(file_blockno/ENTRY) - 1]; fseek(fp,addr,SEEK_SET); fwrite(block_entries, BLKSIZE, 1, fp); memset(block_entries, 0, ENTRY); } } int offset = file_blockno%ENTRY; block_entries[offset] = super->tail_db; if(alloc_block(pblk) < 0) { printf("\n error in block allocation for write"); return -1; } return 0; }
static void place(void *bp, size_t asize) { //dbg_printf("place%p\n",bp); size_t csize = GET_SIZE(HDRP(bp)); // void *remain_blk; size_t remain_size=csize-asize; if ((remain_size) >= 16) { void *remain_blk; delete_free_block(bp); // size_t predoff=get_pred_offset(bp); // size_t succoff=get_succ_offset(bp); alloc_block(bp,asize); remain_blk= NEXT_BLKP(bp); PUT(HDRP(remain_blk), PACK(remain_size, 0)); PUT(FTRP(remain_blk), PACK(remain_size, 0)); add_free_block(remain_blk,remain_size); /*size_t re_off=get_offset(remain_blk); set_succ(remain_blk,succoff); set_pred(remain_blk,predoff); // if (predoff){ set_succ(get_addr(predoff),re_off); // } // else free_list=remain_blk; if (succoff){ set_pred(get_addr(succoff),re_off); }*/ } else { delete_free_block(bp); PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); } }
/************************************************* * Allocation * *************************************************/ void* Pooling_Allocator::allocate(u32bit n) { const u32bit BITMAP_SIZE = Memory_Block::bitmap_size(); const u32bit BLOCK_SIZE = Memory_Block::block_size(); Mutex_Holder lock(mutex); if(n <= BITMAP_SIZE * BLOCK_SIZE) { const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE; byte* mem = allocate_blocks(block_no); if(mem) return mem; get_more_core(PREF_SIZE); mem = allocate_blocks(block_no); if(mem) return mem; throw Memory_Exhaustion(); } void* new_buf = alloc_block(n); if(new_buf) return new_buf; throw Memory_Exhaustion(); }
/* Create a series of blocks, and optionally the single-, double-, and/or triple-indirect blocks that refer to them. level specifies how many steps away from data blocks we are (between 0 and 3), map is an array into which the logical/physical associations of data blocks should be stored, next refers to the next logical block number, and nblocks is the number of logical blocks that are to be created. */ static int create_blocks(ext2_filesystem *fs, int level, uint32_t *map, int *next, int nblocks) { if (*next >= nblocks) return 0; /* Allocate the next block */ int blockno = alloc_block(fs); if (0 == level) { /* If this is a data block (as opposed to an indirect block), record the logical->physical mapping, and increment the next logical block number */ if (map) map[*next] = blockno; (*next)++; } if (0 < level) { /* Create a series of data or indirect blocks one level down, and store references to them in the current indirect block */ buffer *indirect_buf; try(bufcache_get(fs->bc,blockno,&indirect_buf)); int i; uint32_t *table = (uint32_t*)indirect_buf->data; for (i = 0; i < RPB; i++) table[i] = create_blocks(fs,level-1,map,next,nblocks); bufcache_release(fs->bc,indirect_buf,1); } return blockno; }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT). // // Analogy: This is like pgdir_walk for files. // Hint: Don't forget to clear any block you allocate. static int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { // LAB 5: Your code here. int r; void *addr = NULL; if (filebno >= NDIRECT + NINDIRECT){ return -E_INVAL; } if (filebno < NDIRECT){ *ppdiskbno = &f->f_direct[filebno]; return 0; } if (f->f_indirect == 0){ if (!alloc){ return -E_NOT_FOUND; } if((r = alloc_block()) == -E_NO_DISK){ return -E_NO_DISK; } f->f_indirect = r; // Clear this indirect block memset(diskaddr(r), 0, BLKSIZE); flush_block(diskaddr(r)); } // Remember fileno - NDIRECT addr = diskaddr(f->f_indirect); *ppdiskbno = ((uint32_t *)addr + filebno - NDIRECT); return 0; }
int dir_try_enter(zone_t z, ino_t child, char const *name) { struct direct *dir_entry = alloc_block(); int r = 0; block_t b; int i, l; b = z << zone_shift; for (l = 0; l < zone_per_block; l++, b++) { get_block(b, dir_entry); for (i = 0; i < NR_DIR_ENTRIES(block_size); i++) if (!dir_entry[i].d_ino) break; if(i < NR_DIR_ENTRIES(block_size)) { r = 1; dir_entry[i].d_ino = child; assert(sizeof(dir_entry[i].d_name) == MFS_DIRSIZ); if (verbose && strlen(name) > MFS_DIRSIZ) fprintf(stderr, "File name %s is too long, truncated\n", name); strncpy(dir_entry[i].d_name, name, MFS_DIRSIZ); put_block(b, dir_entry); break; } } free(dir_entry); return r; }
/* Increment the file-size in inode n */ void incr_size(ino_t n, size_t count) { block_t b; int off; b = ((n - 1) / inodes_per_block) + inode_offset; off = (n - 1) % inodes_per_block; { struct inode *inodes; assert(inodes_per_block * sizeof(*inodes) == block_size); if(!(inodes = alloc_block())) err(1, "couldn't allocate a block of inodes"); get_block(b, inodes); /* Check overflow; avoid compiler spurious warnings */ if (inodes[off].i_size+(int)count < inodes[off].i_size || inodes[off].i_size > MAX_MAX_SIZE-(int)count) pexit("File has become too big to be handled by MFS"); inodes[off].i_size += count; put_block(b, inodes); free(inodes); } }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT). // // Analogy: This is like pgdir_walk for files. // Hint: Don't forget to clear any block you allocate. static int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { // LAB 5: Your code here. int blkno; uint32_t *vindirect; if (NDIRECT + NINDIRECT <= filebno) return -E_INVAL; if (NDIRECT > filebno) { if (NULL != ppdiskbno) *ppdiskbno = &(f->f_direct[filebno]); return 0; } if (0 == f->f_indirect) { if (!alloc) return -E_NOT_FOUND; blkno = alloc_block(); if (0 > blkno) return -E_NO_DISK; f->f_indirect = blkno; vindirect = (uint32_t *)(DISKMAP + BLKSIZE * f->f_indirect); memset((void *)vindirect, 0, PGSIZE); } else vindirect = (uint32_t *)(DISKMAP + BLKSIZE * f->f_indirect); if (NULL != ppdiskbno) *ppdiskbno = &vindirect[filebno-NDIRECT]; return 0; }
void* kma_malloc(kma_size_t size) { if(buffer_entry == NULL) init_buffer_list(); return alloc_block(size); }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_NO_MEM if there's no space in memory for an indirect block. // -E_INVAL if filebno is out of range (it's >= NINDIRECT). // // Analogy: This is like pgdir_walk for files. int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { int r; uint32_t *ptr; char *blk; if (filebno < NDIRECT) ptr = &f->f_direct[filebno]; else if (filebno < NINDIRECT) { if (f->f_indirect == 0) { if (alloc == 0) return -E_NOT_FOUND; if ((r = alloc_block()) < 0) return r; f->f_indirect = r; } else alloc = 0; // we did not allocate a block if ((r = read_block(f->f_indirect, &blk)) < 0) return r; assert(blk != 0); if (alloc) // must clear any block we allocated memset(blk, 0, BLKSIZE); ptr = (uint32_t*)blk + filebno; } else return -E_INVAL; *ppdiskbno = ptr; return 0; }
// Set *blk to the address in memory where the filebno'th // block of file 'f' would be mapped. // // Returns 0 on success, < 0 on error. Errors are: // -E_NO_DISK if a block needed to be allocated but the disk is full. // -E_INVAL if filebno is out of range. // // Hint: Use file_block_walk and alloc_block. int file_get_block(struct File *f, uint32_t filebno, char **blk) { // code for lab 5- M.G // panic("file_get_block not implemented"); uint32_t *ppdiskbno; uint32_t new_block_no; int return_value; if ((return_value = file_block_walk(f, filebno, &ppdiskbno,true)) < 0) { return return_value; } if (!*ppdiskbno) { if ((new_block_no = alloc_block()) < 0) { return -E_NO_DISK; } *ppdiskbno = new_block_no; } *blk = diskaddr(*ppdiskbno); return 0; }
/* Increment the link count to inode n */ void incr_link(ino_t n) { int off; static int enter = 0; static struct inode *inodes = NULL; block_t b; if (enter++) pexit("internal error: recursive call to incr_link()"); b = ((n - 1) / inodes_per_block) + inode_offset; off = (n - 1) % inodes_per_block; { assert(sizeof(*inodes) * inodes_per_block == block_size); if(!inodes && !(inodes = alloc_block())) err(1, "couldn't allocate a block of inodes"); get_block(b, inodes); inodes[off].i_nlinks++; /* Check overflow (particularly on V1)... */ if (inodes[off].i_nlinks <= 0) pexit("Too many links to a directory"); put_block(b, inodes); } enter = 0; }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Note, for the read-only file system (lab 5 without the challenge), // alloc will always be false. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT). // // Analogy: This is like pgdir_walk for files. // Hint: Don't forget to clear any block you allocate. static int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { // LAB 5: Your code here. if (filebno < NDIRECT) { // Block can be found directly. *ppdiskbno = &f->f_direct[filebno]; return 0; } else if (filebno < NDIRECT + NINDIRECT) { // Block must be found indirectly. if (!f->f_indirect) { if (!alloc) return -E_NOT_FOUND; // Allocate indirect block. f->f_indirect = alloc_block(); if (!f->f_indirect) return -E_NO_DISK; // Clear block. memset(diskaddr(f->f_indirect), 0, BLKSIZE); } uint32_t *ind_blk = (uint32_t *)diskaddr(f->f_indirect); *ppdiskbno = &ind_blk[filebno - NDIRECT]; return 0; } else { // There is no so many blocks. return -E_INVAL; } // panic("file_block_walk not implemented"); }
/* Insert one bit into the bitmap */ void insert_bit(block_t map, bit_t bit) { int boff, w, s; unsigned int bits_per_block; block_t map_block; bitchunk_t *buf; buf = alloc_block(); bits_per_block = FS_BITS_PER_BLOCK(block_size); map_block = map + bit / bits_per_block; if (map_block >= inode_offset) pexit("insertbit invades inodes area - this cannot happen"); boff = bit % bits_per_block; assert(boff >=0); assert(boff < FS_BITS_PER_BLOCK(block_size)); get_block(map_block, buf); w = boff / FS_BITCHUNK_BITS; s = boff % FS_BITCHUNK_BITS; buf[w] |= (1 << s); put_block(map_block, buf); free(buf); }
static void alloc_and_assign_internal_structures(struct s_net **original_net, struct s_block **original_block, int *original_num_nets, int *original_num_blocks) { /*allocate new data structures to hold net, and block info */ *original_net = clb_net; *original_num_nets = num_nets; num_nets = NET_COUNT; alloc_net(); *original_block = block; *original_num_blocks = num_blocks; num_blocks = BLOCK_COUNT; alloc_block(); /* [0..num_nets-1][1..num_pins-1] */ net_delay = (float **)alloc_matrix(0, NET_COUNT - 1, 1, BLOCK_COUNT - 1, sizeof(float)); net_slack = (float **)alloc_matrix(0, NET_COUNT - 1, 1, BLOCK_COUNT - 1, sizeof(float)); reset_placement(); }
void Profiler::init(int max_block_num) { blocks_ = COMMON_ALLOC(ProfilerBlock, max_block_num); memset(blocks_, 0x00, sizeof(ProfilerBlock) * max_block_num); root_ = alloc_block("Root"); current_ = root_; }
IndexSet::IndexSet (IndexSet *set) { #ifdef ASSERT _serial_number = _serial_count++; set->check_watch("copied", _serial_number); check_watch("initialized by copy", set->_serial_number); _max_elements = set->_max_elements; #endif _count = set->_count; _max_blocks = set->_max_blocks; if (_max_blocks <= preallocated_block_list_size) { _blocks = _preallocated_block_list; } else { _blocks = (IndexSet::BitBlock**) arena()->Amalloc_4(sizeof(IndexSet::BitBlock**) * _max_blocks); } for (uint i = 0; i < _max_blocks; i++) { BitBlock *block = set->_blocks[i]; if (block == &_empty_block) { set_block(i, &_empty_block); } else { BitBlock *new_block = alloc_block(); memcpy(new_block->words(), block->words(), sizeof(uint32) * words_per_block); set_block(i, new_block); } } }
// Set *blk to point at the filebno'th block in file 'f'. // Allocate the block if it doesn't yet exist. // // Returns 0 on success, < 0 on error. Errors are: // -E_NO_DISK if a block needed to be allocated but the disk is full. // -E_INVAL if filebno is out of range. // // Hint: Use file_block_walk and alloc_block. int file_get_block(struct File *f, uint32_t filebno, char **blk) { // LAB 5: Your code here. int r; uint32_t *pblkno; if ((r = file_block_walk(f, filebno, &pblkno, 1)) < 0){ return r; } // if not exist if (*pblkno == 0){ if ((r = alloc_block()) < 0){ return -E_NO_DISK; } *pblkno = r; // Clear this block memset(diskaddr(r), 0, BLKSIZE); // flush this empty block into disk flush_block(diskaddr(r)); } *blk = diskaddr(*pblkno); return 0; }
int i915_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_mem_alloc_t *alloc = data; struct mem_block *block, **heap; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } heap = get_heap(dev_priv, alloc->region); if (!heap || !*heap) return -EFAULT; if (alloc->alignment < 12) alloc->alignment = 12; block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); if (!block) return -ENOMEM; mark_block(dev, block, 1); if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, sizeof(int))) { DRM_ERROR("copy_to_user\n"); return -EFAULT; } return 0; }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT). // // Analogy: This is like pgdir_walk for files. // Hint: Don't forget to clear any block you allocate. static int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { // LAB 5: Your code here. int r; if (filebno >= NDIRECT + NINDIRECT) return -E_INVAL; if (filebno <= NDIRECT) { *ppdiskbno = &(f->f_direct[filebno]); } else { if (f->f_indirect != 0) { *ppdiskbno = &((uint32_t *) diskaddr(f->f_indirect))[filebno - NDIRECT]; } else if (alloc) { if((r = f->f_indirect = alloc_block()) < 0) return r; // -E_NO_DISK memset(diskaddr(f->f_indirect), 0, BLKSIZE); *ppdiskbno = &((uint32_t *) diskaddr(f->f_indirect))[filebno - NDIRECT]; } else return -E_NOT_FOUND; } return 0; }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT). // // Analogy: This is like pgdir_walk for files. // Hint: Don't forget to clear any block you allocate. static int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { // LAB 5: Your code here. // panic("file_block_walk not implemented"); if (filebno < NDIRECT) { *ppdiskbno = &f->f_direct[filebno]; } else if (filebno < NDIRECT + NINDIRECT) { if (!f->f_indirect) { if (!alloc) { return -E_NOT_FOUND; } f->f_indirect = alloc_block(); if (f->f_indirect < 0) return -E_NO_DISK; memset(diskaddr(f->f_indirect), 0, BLKSIZE); } uint32_t *ptr = (uint32_t *)diskaddr(f->f_indirect); *ppdiskbno = &ptr[filebno - NDIRECT]; } else { return -E_INVAL; } return 0; }
/************************************************* * Allocate more memory for the pool * *************************************************/ void Pooling_Allocator::get_more_core(u32bit in_bytes) { const u32bit BITMAP_SIZE = Memory_Block::bitmap_size(); const u32bit BLOCK_SIZE = Memory_Block::block_size(); const u32bit TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE; const u32bit in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE; const u32bit to_allocate = in_blocks * TOTAL_BLOCK_SIZE; void* ptr = alloc_block(to_allocate); if(ptr == 0) throw Memory_Exhaustion(); allocated.push_back(std::make_pair(ptr, to_allocate)); for(u32bit j = 0; j != in_blocks; ++j) { byte* byte_ptr = static_cast<byte*>(ptr); blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE)); } std::sort(blocks.begin(), blocks.end()); last_used = std::lower_bound(blocks.begin(), blocks.end(), Memory_Block(ptr)); }
// Set *blk to point at the filebno'th block in file 'f'. // Allocate the block if it doesn't yet exist. // // Returns 0 on success, < 0 on error. Errors are: // -E_NO_DISK if a block needed to be allocated but the disk is full. // -E_INVAL if filebno is out of range. // // Hint: Use file_block_walk and alloc_block. int file_get_block(struct File *f, uint32_t filebno, char **blk) { // LAB 5: Your code here. //panic("file_get_block not implemented"); uint32_t *pdiskbno; int result; if((result=file_block_walk(f, filebno, &pdiskbno, 1)) < 0) { return result; } if(*pdiskbno == 0) { if((result=alloc_block()) < 0) { return -E_NO_DISK; } else { *pdiskbno=result; memset(diskaddr(result), 0, BLKSIZE); flush_block(diskaddr (result)); } } *blk=diskaddr(*pdiskbno); return 0; }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT). // // Analogy: This is like pgdir_walk for files. // Hint: Don't forget to clear any block you allocate. static int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { // LAB 5: Your code here. if(filebno >= NDIRECT + NINDIRECT) return -E_INVAL; if(filebno < NDIRECT) { *ppdiskbno = &(f->f_direct[filebno]); return 0; } if(f->f_indirect == 0 && !alloc) return -E_NOT_FOUND; if(f->f_indirect == 0) { int status = 0; if((status = alloc_block()) < 0) { return status; } f->f_indirect = status; memset((int*)diskaddr(f->f_indirect), 0, BLKSIZE); } uint32_t* baddr = (uint32_t*)diskaddr(f->f_indirect); *ppdiskbno = (uint32_t*)(baddr + filebno - NDIRECT); return 0; //panic("file_block_walk not implemented"); }
// Find the disk block number slot for the 'filebno'th block in file 'f'. // Set '*ppdiskbno' to point to that slot. // The slot will be one of the f->f_direct[] entries, // or an entry in the indirect block. // When 'alloc' is set, this function will allocate an indirect block // if necessary. // // Returns: // 0 on success (but note that *ppdiskbno might equal 0). // -E_NOT_FOUND if the function needed to allocate an indirect block, but // alloc was 0. // -E_NO_DISK if there's no space on the disk for an indirect block. // -E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT). // // Analogy: This is like pgdir_walk for files. // Hint: Don't forget to clear any block you allocate. static int file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc) { // LAB 5: Your code here. int r; if (filebno >= NDIRECT + NINDIRECT) return -E_INVAL; if (filebno < NDIRECT) { *ppdiskbno = &f->f_direct[filebno]; } else { if (!f->f_indirect){ if (!alloc) return -E_NOT_FOUND; else { if ((r = alloc_block()) < 0) return r; f->f_indirect = r; memset(diskaddr(f->f_indirect), 0, BLKSIZE); } } *ppdiskbno = (uint32_t*)diskaddr(f->f_indirect) + filebno - NDIRECT; } return 0; }