/* advances the slot of the path to the next item * (walking the tree and freeing the path as necessary). * returns 0 for success, * or on failure frees path and returns 1 if no next item or negative errno */ PUBLIC int step_to_next_slot(struct path *p) { struct cache *node; struct header *hdr; blocknr_t b; int slot; int level = 0; /* starting at leaf */ while (TRUE) { node = p->nodes[level]; hdr = &node->u.node.header; slot = ++(p->slots[level]); /* advance the slot */ if (slot < hdr->nritems) { /* found the next slot */ while (level) { /* go back down to the leaf */ b = ptr_for(node, slot); node = get_block(b); if (!node) { free_path_from(p, level); return -errno; } p->nodes[--level] = node; slot = 0; /* get the 0 slot all the way down to the leaf */ hdr = &node->u.node.header; assert(slot < hdr->nritems); } return KEY_FOUND; /* on the next slot */ } assert(slot >= hdr->nritems); /* node is out of slots, */ p->nodes[level] = NULL; /* so take it off the path */ put_block(node); /* and free it from the path */ p->slots[level] = 0; /* this level will use the first slot */ if(is_root_level(level, p)) { /* can't go any higher */ return KEY_NOT_FOUND; /* there is no next item */ } level++; /* look at next level up */ } }
int32_t enter_map(struct map *m,struct aoi_object *o) { struct map_block *block = get_block_by_point(m,&o->current_pos); if(!block) return -1; double_link_push(&block->aoi_objs,&o->block_node); m->all_aoi_objects[o->aoi_object_id] = o; uint32_t radius = STAND_RADIUS; if(o->view_radius > STAND_RADIUS) { radius = o->view_radius; double_link_push(&m->super_aoi_objs,&o->super_node); } uint32_t x1,y1,x2,y2; cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2); uint32_t y = y1; uint32_t x; for( ; y <= y2; ++y) { for(x=x1 ; x <= x2; ++x) { block_process_enter(m,get_block(m,y,x),o); } } o->last_update_tick = GetCurrentMs(); o->is_leave_map = 0; }
void Uploader::request_block(std::shared_ptr<RemoteFolder> origin, const blob& ct_hash, uint32_t offset, uint32_t size) { try { origin->post_block(ct_hash, offset, get_block(ct_hash, offset, size)); }catch(AbstractFolder::no_such_chunk& e){ log_->warn() << log_tag() << "Requested nonexistent block"; } }
int valid_address(void *ptr){ if (base && ptr > base && ptr < sbrk(0)) { return (ptr == get_block(ptr)->raw); } else { return 0; } }
//frees dynamic allocated memory void free(void *p){ t_block block; if(valid_addr(p)){ block = get_block(p); block->block_free = 1; //merge with previous if possible if(block->prev && block->prev->block_free){ block = merge(block->prev); } //merge with next if possible if(block->next){ if(block->next->block_free){ merge(block); } } else { //free the end of the heap if(block->prev){ //block->prev->next = 0x0; } else { // brk(block); // base = 0x0; } } //no more blocks if(!block->next && !block->prev){ brk(block); base = 0x0; } } }
int search(INODE *ip, char *name) { int i; char *cp; DIR *dp; char buf[BLKSIZE]; char temp[256]; // For DIR inodes, assume that (the number of entries is small so that) only has // 12 DIRECT data blocks. Therefore, search only the direct blocks for name[0]. for (i = 0; i < 12; i++) { //printf("iblock[%d] = %d\n", i, ip->i_block[i]); if (ip->i_block[i] == 0) break; get_block(fd, ip->i_block[i], buf); dp = (DIR *)buf; cp = buf; while (cp < buf + BLKSIZE) { strncpy(temp, dp->name, dp->name_len); temp[dp->name_len] = 0; if (strcmp(name, temp) == 0) return dp->inode; cp += dp->rec_len; dp = (DIR *)cp; } } 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; }
struct map *create_map(struct point2D *top_left,struct point2D *bottom_right,callback_ enter_callback,callback_ leave_callback) { //����block����� uint32_t length = abs(top_left->x - bottom_right->x); uint32_t width = abs(top_left->y - bottom_right->y); uint32_t x_count = length % BLOCK_LENGTH == 0 ? length/BLOCK_LENGTH : length/BLOCK_LENGTH + 1; uint32_t y_count = width % BLOCK_LENGTH == 0 ? width/BLOCK_LENGTH : width/BLOCK_LENGTH + 1; struct map *m = calloc(1,x_count*y_count*sizeof(struct map_block)+sizeof(struct map)); m->top_left = *top_left; m->bottom_right = *bottom_right; m->x_count = x_count; m->y_count = y_count; uint32_t x,y; for(y = 0; y < y_count; ++y) for(x = 0; x < x_count; ++x) { struct map_block * b = get_block(m,y,x); double_link_clear(&b->aoi_objs); b->x = x; b->y = y; } double_link_clear(&m->super_aoi_objs); m->enter_callback = enter_callback; m->leave_callback = leave_callback; return m; }
// Return a pointer to an inode given its number. In a real filesystem, this // would require finding the correct block group, rather than assuming it's in // the first. struct ext2_inode * _ref_get_inode(void * fs, __u32 inode_num) { struct ext2_group_desc * bgd = get_block_group(fs, 0); __u32 inode_table_block = bgd->bg_inode_table; struct ext2_inode * inode_table = get_block(fs, inode_table_block); // Since inode 0 doesn't ever exist, the table starts from 1. return inode_table + inode_num - 1; }
// Given the inode for a directory and a filename, return the inode number of // that file inside that directory, or 0 if it doesn't exist. // // name should be a single component - "foo.txt", not "/files/foo.txt". __u32 _ref_get_inode_from_dir(void * fs, struct ext2_inode * dir, char * name) { assert(LINUX_S_ISDIR(dir->i_mode)); // Iterate over each entry of the directory, looking for a match for name. __u32 block_size = get_block_size(fs); void * dir_block = get_block(fs, dir->i_block[0]); struct ext2_dir_entry * entry = (struct ext2_dir_entry *) dir_block; void * limit = ((void *) entry) + block_size; __u32 target_inode = 0; while ((void *) entry < limit) { // Skip unused entries. if (entry->inode == 0) { continue; } if (strlen(name) == (unsigned char) (entry->name_len) && strncmp(name, entry->name, strlen(name)) == 0) { target_inode = entry->inode; } // Advance to the next entry. entry = (struct ext2_dir_entry *) (((void *) entry) + entry->rec_len); } if (target_inode != 0) { return target_inode; } else { return 0; } }
// Return a pointer to the first block group descriptor in a filesystem. Real // ext2 filesystems will have several of these, but, for simplicity, we will // assume there is only one. struct ext2_group_desc * _ref_get_block_group(void * fs, __u32 block_group_num) { // The first block group descriptor is in the first full block after the // superblock. __u32 block_size = get_block_size(fs); __u32 bgd_block = (SUPERBLOCK_OFFSET / block_size) + 1; return (struct ext2_group_desc *) get_block(fs, bgd_block); }
static void fill_indirect_block(u32 *ind_block, int len, struct block_allocation *alloc) { int i; for (i = 0; i < len; i++) { ind_block[i] = get_block(alloc, i); } }
uint8 *csi_get_block(struct csi *csi) { if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0) return NULL; return get_block(csi->vol->fd, _csi_to_block_(csi), csi->vol->bytes_per_sector); }
int search_inode_in_folder(int folder_number, const char *node_name) { int result = -1; if (folder_number >= 0 && node_name != NULL) { inode_t *folder = (inode_t *)get_block(folder_number); if (folder != NULL) { if (folder->status == BLOCK_STATUS_FOLDER) { char name[NODE_NAME_MAX_SIZE]; int *start = (int *)folder->content; int *end = (int *)((void *)folder + size_of_block); while (start < end) { if (*start > 0 && get_inode_name(*start, name) == 0 && strcmp(node_name, name) == 0) { result = *start; break; } start++; } } destroy_block(folder); } } return result; }
/* 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); } }
static inline tick_super_object(struct map *m,struct aoi_object *o) { uint32_t now = GetCurrentMs(); if(now - o->last_update_tick >= UPDATE_INTERVAL) { //remove out of view object first uint32_t i = 0; for( ; i < MAX_BITS; ++i) { if(o->self_view_objs.bits[i] > 0) { uint32_t j = 0; for( ; j < sizeof(uint32_t); ++j) { if(o->self_view_objs.bits[i] & (1 << j)) { uint32_t aoi_object_id = i*sizeof(uint32_t) + j; if(aoi_object_id != o->aoi_object_id) { struct aoi_object *other = m->all_aoi_objects[aoi_object_id]; if(other->is_leave_map) leave_me(m,o,other); else { uint64_t distance = cal_distance_2D(&o->current_pos,&other->current_pos); if(distance > o->view_radius) leave_me(m,o,other); } } } } } } //process enter view uint32_t x1,y1,x2,y2; cal_blocks(m,&o->current_pos,o->view_radius,&x1,&y1,&x2,&y2); uint32_t y = y1; uint32_t x; for( ; y <= y2; ++y) { for( x=x1; x <= x2; ++x) { struct map_block *bl = get_block(m,y,x); struct aoi_object *cur = (struct aoi_object*)bl->aoi_objs.head.next; while(cur != (struct aoi_object*)&bl->aoi_objs.tail) { if(is_set(&o->self_view_objs,cur->aoi_object_id) == 0) { uint64_t distance = cal_distance_2D(&o->current_pos,&cur->current_pos); if(o->view_radius >= distance) enter_me(m,o,cur); } cur = (struct aoi_object *)cur->block_node.next; } } } o->last_update_tick = now; } }
/* 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); }
/* * print_blocks - for each logical block consumed by the file * associated with fd, prints to standard out the tuple * "(logical block, physical block)" */ void print_blocks(int fd) { int nr_blocks, i; nr_blocks = get_nr_blocks(fd); if (nr_blocks < 0) { fprintf(stderr, "get_nr_blocks failed!\n"); return; } if (nr_blocks == 0) { printf("no allocated blocks\n"); return; } else if (nr_blocks == 1) printf("1 block\n\n"); else printf("%d blocks\n\n", nr_blocks); for (i = 0; i < nr_blocks; i++) { int phys_block; phys_block = get_block(fd, i); if (phys_block < 0) { fprintf(stderr, "get_block failed!\n"); return; } if (!phys_block) continue; printf("(%u, %u) ", i, phys_block); } putchar('\n'); }
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; }
/* * ShmemDynAlloc */ void * ShmemDynAlloc(Size size) { void *block = NULL; Size padded_size; size = Max(ALIGN(size), MIN_ALLOC_SIZE); for (padded_size = 1; padded_size < size && padded_size <= 1024; padded_size *= 2); size = Max(size, padded_size); block = get_block(size); if (block == NULL) { /* * Don't request fewer than 1k from ShmemAlloc. * The more contiguous memory we have, the better we * can combat fragmentation. */ Size alloc_size = Max(size, MIN_SHMEM_ALLOC_SIZE); block = ShmemAlloc(BLOCK_SIZE(alloc_size)); memset(block, 0, BLOCK_SIZE(alloc_size)); block = (void *) ((intptr_t) block + sizeof(Header)); init_block(block, alloc_size, true); mark_allocated(block); } if (get_size(block) - size >= MIN_BLOCK_SIZE) split_block(block, size); Assert(is_allocated(block)); return block; }
int32_t leave_map(struct map *m,struct aoi_object *o) { struct map_block *block = get_block_by_point(m,&o->current_pos); if(!block) return -1; dlist_remove(&o->block_node); uint32_t radius = STAND_RADIUS; if(o->view_radius > STAND_RADIUS) { radius = o->view_radius; dlist_remove(&o->super_node); } uint32_t x1,y1,x2,y2; x1 = y1 = x2 = y2 = 0; cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2); uint32_t y = y1; uint32_t x; for( ; y <= y2; ++y) { for( x=x1; x <= x2; ++x) { block_process_leave(m,get_block(m,y,x),o,1); } } o->is_leave_map = 1; //自己离开自己的视野 leave_me(m,o,o); return 0; }
// -------------------------------------------------------------------------- int DecoderPE::run(BlockStore &bs) { while (get_block(bs) == VT_OK) { } return VT_OK; }
int findino(MINODE *mip, int *myino, int *parent) { int device = 0; INODE* ip = NULL; if(!mip) { fprintf(stderr, "findino: null mip\n"); return FAILURE; } device = mip->device; ip = &mip->inode; //Check that mip is a directory if (!S_ISDIR(ip->i_mode)) { fprintf(stderr, "findino: Not a directory\n"); return FAILURE; } u8* block = get_block(device, ip->i_block[0]); u8* cp = block; DIR* dp = (DIR*)block; *myino = dp->inode; cp += dp->rec_len; // advance cp by rec_len BYTEs dp = (DIR*)cp; // pull dp along to the next record *parent = dp->inode; free(block); return SUCCESS; }
/*===========================================================================* * fs_rdlink * *===========================================================================*/ PUBLIC int fs_rdlink() { block_t b; /* block containing link text */ struct buf *bp; /* buffer containing link text */ register struct inode *rip; /* target inode */ register int r; /* return value */ size_t copylen; copylen = min( (size_t) fs_m_in.REQ_MEM_SIZE, UMAX_FILE_POS); /* Temporarily open the file. */ if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); if(!S_ISLNK(rip->i_mode)) r = EACCES; else if ((b = read_map(rip, (off_t) 0)) == NO_BLOCK) r = EIO; else { /* Passed all checks */ /* We can safely cast to unsigned, because copylen is guaranteed to be below max file size */ copylen = min( copylen, (unsigned) rip->i_size); bp = get_block(rip->i_dev, b, NORMAL); r = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, (vir_bytes) 0, (vir_bytes) bp->b_data, (size_t) copylen, D); put_block(bp, DIRECTORY_BLOCK); if (r == OK) fs_m_out.RES_NBYTES = copylen; } put_inode(rip); return(r); }
int sfs_open(char *pathname){ int dNum; int parentINumber; int inumber = parsePathname(pathname, &parentINumber, dNum); char* tmp_buffer[MAX_IO_LENGTH+1]; if (inumber<0){ return -1; } OpenFileTable[inumber][0]+=1; if(fileCount<4){ if(OpenFileTable[inumber][1]==NULL){ OpenFileTable[inumber][1]=fileCount; get_block(inode[inumber][3],RAM[OpenFileTable[inumber][1]]); //edit for file size of 512 here fileCount++; }else{ OpenFileTable[inumber][0]++; } }else if(OpenFileTable[inumber][1]!=NULL){ OpenFileTable[inumber][0]++; }else{ return -1; } return 1; }
void free(void *ptr){ sum_frees++; num_allocated--; block_t current; if (valid_address(ptr)){ current = get_block(ptr); current->free = 1; if(current->prev && current->prev->free){ //merge with prev block if works current = merge_block(current->prev); } if (current->next){ //merge with next merge_block(current); } else { if (current->prev){ current->prev->next = NULL; } else { //no more blocks base = NULL; } brk(current); } } else { perror("invalid ptr at free"); } }
int32_t leave_map(struct map *m,struct aoi_object *o) { struct map_block *block = get_block_by_point(m,&o->current_pos); if(!block) return -1; double_link_remove(&o->block_node); uint32_t radius = STAND_RADIUS; if(o->view_radius > STAND_RADIUS) { radius = o->view_radius; double_link_remove(&o->super_node); } uint32_t x1,y1,x2,y2; cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2); uint32_t y = y1; uint32_t x; for( ; y <= y2; ++y) { for( x=x1; x <= x2; ++x) { block_process_leave(m,get_block(m,y,x),o,1); } } o->is_leave_map = 1; if(--o->watch_me_count == 0) m->all_aoi_objects[o->aoi_object_id] = NULL; }
int remove_node_from_folder(int folder_number, int node_number) { int result = -1; if (folder_number >= 0 && node_number > 0) { inode_t *folder = (inode_t *)get_block(folder_number); if (folder != NULL) { if (folder->status == BLOCK_STATUS_FOLDER) { int *start = (int *)folder->content; int *end = (int *)((void *)folder + size_of_block); while (start < end) { if (*start == node_number) { *start = 0; break; } start++; } if (start < end) { result = write_block(folder_number, folder); } else { result = 0; } } destroy_block(folder); } } return result; }
//mount root file system, establish / and CWDs mount_root(char device_name[64]) { char buf[1024]; //open device for RW dev = open(device_name, O_RDWR); //check if open() worked if(dev < 0) { printf("ERROR: failed cannot open %s\n", device_name); exit(0); } //read super block to verify it's an EXT2 FS get_block(dev, SUPERBLOCK, buf); sp = (SUPER *)buf; //verify if it's an EXT2 FS if(sp->s_magic != 0xEF53) { printf("NOT AN EXT2 FS\n"); exit(1); } //set some vars ninodes = sp->s_inodes_count; nblocks = sp->s_blocks_count; //read group block for info get_block(dev, GDBLOCK, buf); gp = (GD *)buf; imap = gp->bg_inode_bitmap; bmap = gp->bg_block_bitmap; inodeBeginBlock = gp->bg_inode_table; //get root inode root = iget(dev, 2); //let cwd of both p0 and p1 point at the root minode (refCount=3) proc[0].cwd = root; proc[1].cwd = root; root->refCount = 3; printf("%s mounted\n", device_name); }
void do_ls() { int dev; u32 ino; MINODE* mip; char buf[BLOCK_SIZE]; char temp[BLOCK_SIZE]; char* cp; int i; if (0 == pathName[0]) { printf("ls : current working directory"); ino = running->cwd->ino; dev = running->cwd->dev; } else if (0 == strcmp(pathName, "/")) { printf("ls : root directory"); ino = root->ino; dev = root->dev; } else { printf("ls : "); ino = getino(&dev, pathName); } if ((u32)-1 == ino) { err_printf("ls : it is not a directory\n"); return; } printf("\n"); mip = iget(dev, ino); for (i = 0; i < 12 && (mip->INODE).i_block[i]; i++) { get_block(mip->dev, (mip->INODE).i_block[i], buf); cp = buf; dp = (DIR*)buf; //printf("i_block is %i\n", (int) (mip->INODE).i_block[i]); while (cp < buf + BLOCK_SIZE && dp->rec_len) { if (0 == dp->rec_len) break; strncpy(temp, dp->name, dp->name_len); temp[dp->name_len] = 0; file_info(dev, dp->inode); //printf("%3u %s\n", dp->inode, temp); // with inode printf("%s\n", temp); cp += dp->rec_len; dp = (DIR*)cp; } } iput(mip); }