static int minix_dir_empty(struct inode *dir) { struct block *block; struct minix_dentry *de; int entries, i, k, n; /* Assert that @dir is directory inode. */ entries = dir->i_size / MINIX_DENTRY_SIZE; for (i = 0; i < entries; i += n) { n = min(entries - i, MINIX_DENTRIES_PER_BLOCK); block = bmap_block(dir, i / MINIX_DENTRIES_PER_BLOCK, 0); if (!block) continue; de = (struct minix_dentry *)block->b_data; for (k = 0; k < n; k++, de++) { if (de->d_ino == 0) continue; if (de->d_name[0] != '.') goto not_empty; if (de->d_name[1] == '\0') { if (de->d_ino != dir->i_ino) panic("The inode number of . corrupts"); continue; } if (de->d_name[1] != '.' || de->d_name[2] != '\0') goto not_empty; } put_block(block); } return 1; not_empty: put_block(block); return 0; }
struct minix_dentry *minix_lookup_dentry(struct inode *dir, char *base, int len, struct block **b) { struct minix_dentry *de; struct block *block; int entries, i, k, n; if (len > MINIX_NAME_LEN) return NULL; entries = dir->i_size / MINIX_DENTRY_SIZE; for (i = 0; i < entries; i += n) { block = bmap_block(dir, i / MINIX_DENTRIES_PER_BLOCK, 0); de = (struct minix_dentry *)block->b_data; n = min(entries - i, MINIX_DENTRIES_PER_BLOCK); for (k = 0; k < n; k++, de++) { if (de->d_ino == 0) continue; /* strncmp skips deleted entry automatically. */ if (strlen(de->d_name) == len && !strncmp(de->d_name, base, len)) goto found; } put_block(block); } return NULL; found: if (b) *b = block; else put_block(block); return de; }
/** * Looks for entry 'file' in the given directory contents. The inode is * assumed to be of directory type. * * If the file is found it's inode number is returned, otherwise NO_INODE is * returned. */ inode_nr dir_search(struct minix_inode *inode, const char *file) { struct minix_block *blk; /* block belonging to inode */ zone_nr z; int c_pos = 0; /* current position in scan of directory */ int i; /* current position in directory block */ inode_nr retval; debug("dir_search(%d, \"%s\"): searching...", inode->i_num, file); while((z = read_map(inode, c_pos)) != NO_ZONE) { blk = get_block(z, TRUE); /* TODO: fix bug. shouldn't use BLOCK_SIZE */ for(i = 0; i < BLOCK_SIZE; i+= DENTRY_SIZE) { if(strcmp((char *)(blk->blk_data + i + 2), file) == 0) { retval = *((inode_nr *)(blk->blk_data + i)); put_block(blk, DIR_BLOCK); debug("dir_search(): found \"%s\" at ix=%d", file, i); return retval; } } put_block(blk, DIR_BLOCK); c_pos += BLOCK_SIZE; } /* couldn't find directory entry */ debug("dir_search(%d, \"%s\"): couldn't find entry", inode->i_num, file); return NO_INODE; }
void block_test(void) { struct block *block; unsigned char *p; int i; block = get_block(&hd_bdev, 0); if (!block) panic("Cannot get block"); if (block != get_block(&hd_bdev, 0)) panic("Cannot get hash block"); put_block(block); p = (unsigned char *)block->b_data; if (p[510] != 0x55 || p[511] != 0xaa) panic("ERROR 0x55aa"); p[0] = 'h'; p[1] = 'k'; block->b_dirty = 1; put_block(block); block = get_block(&hd_bdev, 0); p = (unsigned char *)block->b_data; if (p[0] != 'h' || p[1] != 'k') panic("block WRITE or READ error"); for (i = 0; i < 512; i++) p[i] = 0xff; block->b_dirty = 1; put_block(block); printk("flush buffer\n"); flush_block_buffer(); block = get_block(&hd_bdev, 0); printk("test block ok\n"); }
int sfs_write(int fd, int start, int length, char *mem_pointer){ int size; int i; /* if(sscanf(fd, "%i", &intvar)!=1) return -1; if(sscanf(start, "%i" , &intvar)!=1) return -1; if(sscanf(length, "%i", &intvar)!=1) return -1; */ if(strlen(mem_pointer)!=length){ printf("too many characters entered!"); return -1; } if(inode[fd][1]==1) return -1; if(OpenFileTable[fd][0]==0) return -1; if(OpenFileTable[fd][0]>1) return -1; printf("%d", strlen(mem_pointer)); char tmp_buffer[MAX_IO_LENGTH+1]; printf("%d", inode[fd][2]); size=inode[fd][2]; memcpy(tmp_buffer, RAM[OpenFileTable[fd][1]], sizeof(RAM[OpenFileTable[fd][1]])); if(!(inode[fd][3]==NULL)){ if(start==-1){ if(size!=0){ strcat(tmp_buffer, mem_pointer); //memcpy(mem_pointer, tmp_buffer, sizeof(tmp_buffer)); } inode[fd][2]=size+length; memcpy(RAM[OpenFileTable[fd][1]], tmp_buffer, sizeof(tmp_buffer)); put_block(inode[fd][3],mem_pointer); return 1; //char tmp_buffer2[size + length+1]; //get_block(inode[fd][3], tmp_buffer); }else if((start + length)> size){ printf("size issue"); return -1; }else{ memcpy(tmp_buffer, RAM[OpenFileTable[fd][1]], sizeof(RAM[OpenFileTable[fd][1]])); for(i=start;i<start+length;i++){ tmp_buffer[i]=mem_pointer[i-start]; } //memcpy(tmp_buffer+start, mem_pointer, sizeof(mem_pointer)); memcpy(RAM[OpenFileTable[fd][1]], tmp_buffer, sizeof(tmp_buffer)); put_block(inode[fd][3],mem_pointer); return 1; } } return -1; }
int decFreeInodes(int fd) { char buf[BLOCK_SIZE]; // dec free inodes count in Super and GroupDesc _get_block(fd, 1, buf); Super * super = (Super *) buf; super->s_free_inodes_count--; put_block(fd, 1, buf); _get_block(fd, 2, buf); GroupDesc * gp = (GroupDesc *) buf; gp->bg_free_inodes_count--; put_block(fd, 2, buf); return 0; }
struct inode *minix_inode_create(struct inode *dir, char *base, int len) { struct minix_dentry *de; struct inode *inode; struct block *block; int entries, i, k, n; if (len > MINIX_NAME_LEN) return NULL; /* exist? */ de = minix_lookup_dentry(dir, base, len, NULL); if (de) return NULL; /* find an empty dir entry */ entries = dir->i_size / MINIX_DENTRY_SIZE; for (i = 0; i < entries; i += n) { block = bmap_block(dir, i / MINIX_DENTRIES_PER_BLOCK, 0); de = (struct minix_dentry *)block->b_data; n = min(entries - i, MINIX_DENTRIES_PER_BLOCK); for (k = 0; k < n; k++, de++) { if (de->d_ino == 0) goto found; } if (i + n < entries || !(entries % MINIX_DENTRIES_PER_BLOCK)) { put_block(block); block = NULL; } } /* create a new data block and get dir entry from it */ if (!block) { block = bmap_block(dir, entries / MINIX_DENTRIES_PER_BLOCK, 1); if (!block) return NULL; if (block->b_refcnt != 1) panic("Not new block(ref:%d)", block->b_refcnt); de = (struct minix_dentry *)block->b_data; } inode_update_size(dir, dir->i_size + MINIX_DENTRY_SIZE); found: inode = minix_new_inode(dir->i_sb); if (!inode) goto out; /* fill dir entry */ strncpy(de->d_name, base, len); de->d_name[len] = '\0'; de->d_ino = inode->i_ino; minix_inode_dirty_block(dir, block); out: put_block(block); return inode; }
int updateFreeInodes(int devId, int delta) { char buf[BLKSIZE]; // dec free inodes count in SUPER and GD get_block(devId, 1, buf); sp = (SUPER *)buf; sp->s_free_inodes_count + delta; put_block(devId, 1, buf); get_block(devId, 2, buf); gp = (GD *)buf; gp->bg_free_inodes_count + delta; put_block(devId, 2, buf); }
//Pass 1 to increase by 1, -1 to decrease by 1, etc int updateFreeBlocks(int devId, int delta) { char buf[BLKSIZE]; // update free block count in SUPER and GD get_block(devId, 1, buf); sp = (SUPER *)buf; sp->s_free_blocks_count + delta; put_block(devId, 1, buf); get_block(devId, 2, buf); gp = (GD *)buf; gp->bg_free_blocks_count + delta; put_block(devId, 2, buf); }
void decFreeInodes(int dev) { char buf[BLKSIZE]; //dec free inodes count in SUPER and gd get_block(dev, 1, buf); sp = (SUPER *)buf; sp->s_free_inodes_count--; put_block(dev, 1, buf); get_block(dev, 2, buf); gp = (GD *)buf; gp->bg_free_inodes_count--; put_block(dev, 2, buf); }
/* 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 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; }
/* 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); }
/* 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); } }
/* 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; }
void ClientUpdate::put_graph(const GraphImpl* graph) { put(graph->uri(), graph->properties(Resource::Graph::INTERNAL), Resource::Graph::INTERNAL); put(graph->uri(), graph->properties(Resource::Graph::EXTERNAL), Resource::Graph::EXTERNAL); // Enqueue blocks for (const auto& b : graph->blocks()) { put_block(&b); } // Enqueue ports for (uint32_t i = 0; i < graph->num_ports_non_rt(); ++i) { put_port(graph->port_impl(i)); } // Enqueue arcs for (const auto& a : graph->arcs()) { const SPtr<const Arc> arc = a.second; const Connect connect = { arc->tail_path(), arc->head_path() }; connects.push_back(connect); } }
struct inode *minix_inode_mkdir(struct inode *dir, char *base, int len) { struct minix_dentry *de; struct inode *inode; struct block *block; if (!(inode = minix_inode_create(dir, base, len))) return NULL; /* update dir inode information */ minix_inc_link(dir); /* update inode information */ i2mdi(inode)->i_mode = 0755 | S_IFDIR; i2mdi(inode)->i_nlinks = 2; inode->i_mode = 0755 | S_IFDIR; inode->i_ops = &minix_dir_iops; inode_update_size(inode, 2 * MINIX_DENTRY_SIZE); /* create dir entry "." and ".." */ block = minix_new_block(dir->i_sb, &i2mdi(inode)->i_zone[0]); if (!block) panic("Cannot alloc new block for minixfs"); /* "." */ de = (struct minix_dentry *)block->b_data; strcpy(de->d_name, "."); de->d_ino = inode->i_ino; /* ".." */ de++; strcpy(de->d_name, ".."); de->d_ino = dir->i_ino; minix_inode_dirty_block(inode, block); put_block(block); return inode; }
int fs_bitmapdamager() { /* m9_s1:dev m9_s2:inodenumber m9_s3:inode/zone flag m9_s4:0 or 1 */ struct super_block* sp = get_super(fs_m_in.m9_s1); int inodezoneflag = fs_m_in.m9_s3 == 0? 0:sp->s_zmap_blocks; int inodenumber = fs_m_in.m9_s2; if(fs_m_in.m9_s3 == 1) { inodenumber -= (sp->s_firstdatazone - 1); } int blockoff = inodenumber / (sp->s_block_size * 8); struct buf* bitmapblock = get_block(fs_m_in.m9_s1,2 + inodezoneflag + blockoff,NORMAL); bitchunk_t* mapchunks = (bitchunk_t*)bitmapblock->data; int chunkindex = inodenumber / (sizeof(bitchunk_t) * 8); int bitindex = inodenumber % (sizeof(bitchunk_t) * 8); if(fs_m_in.m9_s4 == 0) { mapchunks[chunkindex] &= (~((bitchunk_t)1 << (bitindex))); } else { mapchunks[chunkindex] |= ((bitchunk_t)1 << (bitindex)); } printf("blockoff:%d chunkindex:%d bitindex:%d\n",blockoff,chunkindex,bitindex); put_block(bitmapblock,0); return 0; }
//releases a minode[] void iput(MINODE *mip) { int ino = getino(mip, "."); int offset, ipos; char buf[1024]; //decrement refCount by 1 mip->refCount--; //check refcount to see if anyone using it //check dirty to see if it's been changed, dirty == 1 if changed //if refCount > 0 or dirty return if (mip->refCount || !mip->dirty) return; //mail man's to determine disk block and which inode in that block ipos = (ino - 1) / 8 + INODE_START_POS; offset = (ino -1) % 8; //read that block in get_block(dev, ipos, buf); //copy minode's inode into the inode area in that block ip = (INODE*)buf + offset; *ip = mip->INODE; //write block back to disk put_block(dev, ipos, buf); }
int put_super_blk(void) { char *convert; convert = calloc(4, sizeof(int)); char *buf; buf = calloc(128, sizeof(char)); int counter = 0; int decimal = 0; for(int i=0; i < 512; i++) { if (counter == 4) { counter = 0; decimal = binary_decimal(atoi(convert)); super_blk_buf[i/4 - 1] = decimal; buf[i/4 - 1] = (char)(((int)'0')+decimal); } convert[counter] = (char)(((int)'0')+disk_bitmap[i]); ++counter; } // Write to memory int writesb = put_block(0, buf); return decimal; }
int c_bset(w_coord wcoord, b_coord bcoord, block_t block) { server_socket *dst; n_coord ncoord; void *p; lt_packet out_packet; client_func_checks(); ncoord = wcoord_to_ncoord(wcoord); dst = find_neighbor(ncoord); if (!dst) return 0; makepacket(&out_packet, T_BSET); p = &out_packet.payload; if (!put_wx(&p, wcoord.x, &PLength(&out_packet), &PArgc(&out_packet))) return 1; if (!put_wy(&p, wcoord.y, &PLength(&out_packet), &PArgc(&out_packet))) return 1; if (!put_wz(&p, wcoord.z, &PLength(&out_packet), &PArgc(&out_packet))) return 1; if (!put_bx(&p, bcoord.x, &PLength(&out_packet), &PArgc(&out_packet))) return 1; if (!put_by(&p, bcoord.y, &PLength(&out_packet), &PArgc(&out_packet))) return 1; if (!put_bz(&p, bcoord.z, &PLength(&out_packet), &PArgc(&out_packet))) return 1; if (!put_block(&p, *(uint16_t *)&block, &PLength(&out_packet), &PArgc(&out_packet))) return 1; return (sendpacket(dst, &out_packet)); }
/* 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 */ } }
/* * get dir entries from @dir and write them into @ds * Note: it may get no @ds because of empty minix dentry(d_ino == 0), * usermode program should take care of it! */ int minix_inode_getdir(struct inode *dir, int start, int num, struct dir_stat *ds) { struct block *block; struct minix_dentry *de; int r, i, k, n, off; num = min(dir->i_size / MINIX_DENTRY_SIZE, start + num); r = 0; for (i = start; i < num; i += n) { off = i % MINIX_DENTRIES_PER_BLOCK; n = min(num - i, MINIX_DENTRIES_PER_BLOCK - off); block = bmap_block(dir, i / MINIX_DENTRIES_PER_BLOCK, 0); if (!block) continue; de = (struct minix_dentry *)block->b_data + off; for (k = 0; k < n; k++, de++) { /* no dir */ if (de->d_ino == 0) continue; /* real copy */ ds->len = strcpy(ds->name, de->d_name); ds->inode = de->d_ino; ds++; r++; } put_block(block); } return r; }
int minix_inode_write(struct inode *inode, char *buf, size_t size, off_t off) { struct block *block; int onesize; int wsize = 0; void *src = (void *)buf; int blk = MINIX_BLOCKS(off); if (off >= MINIX_MAX_SIZE) return 0; if (off + size > MINIX_MAX_SIZE) size = MINIX_MAX_SIZE - off; off = MINIX_BLOCK_OFF(off); while (wsize < size) { block = bmap_block(inode, blk, 1); if (!block) break; onesize = min(MINIX_BLOCK_SIZE - off, size - wsize); memcpy(block->b_data + off, src, onesize); minix_inode_dirty_block(inode, block); put_block(block); /* for next loop */ src += onesize; wsize += onesize; blk++; off = 0; } return wsize; }
/* unlink can delete the (disk or memory)inode directly. */ int minix_inode_unlink(struct inode *dir, char *base, int len, int (*can_delete)(struct inode *)) { struct block *block; /* dir entry block */ struct minix_dentry *de; struct inode *inode; int r = -1; de = minix_lookup_dentry(dir, base, len, &block); if (!de) return -1; inode = minix_get_inode(dir->i_sb, de->d_ino); if (!inode) goto out_put_block; /* permission check */ if (inode->i_refcnt > 1) goto out_put_inode; if (can_delete && !can_delete(inode)) goto out_put_inode; /* delete it from the data block of dir */ memset(de, 0x0, MINIX_DENTRY_SIZE); minix_inode_dirty_block(dir, block); /* delete inode */ minix_dec_link(inode); minix_put_inode(inode); r = 0; out_put_inode: put_inode(inode); out_put_block: put_block(block); return r; }
/* inode_read has done the sanity checking of @size and @off */ int minix_inode_read(struct inode *inode, char *buf, size_t size, off_t off) { struct block *block; int onesize; int rsize = 0; void *dst = (void *)buf; int blk = MINIX_BLOCKS(off); off = MINIX_BLOCK_OFF(off); while (rsize < size) { block = bmap_block(inode, blk, 0); if (!block) break; onesize = min(MINIX_BLOCK_SIZE - off, size - rsize); if (block == MINIX_ZERO_BLOCK) { /* read lazy written block */ memset(dst, 0x0, onesize); } else { memcpy(dst, block->b_data + off, onesize); put_block(block); } /* for next loop */ dst += onesize; rsize += onesize; blk++; off = 0; } return rsize; }
/*===========================================================================* * fs_rdlink * *===========================================================================*/ 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) b_data(bp), (size_t) copylen); put_block(bp, DIRECTORY_BLOCK); if (r == OK) fs_m_out.RES_NBYTES = copylen; } put_inode(rip); return(r); }
/* * Given an inode and a byte offset in a file this function returns the * zone number on disk of the zone holding data at that offset. */ zone_nr read_map(struct minix_inode *inode, int byte_offset) { int rel_z = byte_offset / BLOCK_SIZE; /* file relative zone we want */ zone_nr z; /* zone number on disk */ struct minix_block *blk; /* may need to store zone mappings */ int excess; if(rel_z < NR_DZONE_NUM) { /* The zone exists in the inodes direct zones */ if((z = inode->i_zone[rel_z]) == NO_ZONE) return NO_ZONE; return z; } excess = rel_z - NR_DZONE_NUM; if(excess < NR_INDIRECTS) { /* The zone exists in the inodes indirect zones. Set z to the * zone containing the indirect mappings. */ z = inode->i_zone[NR_DZONE_NUM]; } else { /* The zone can be located via the double indirect block */ if((z = inode->i_zone[NR_DZONE_NUM+1]) == NO_ZONE) return NO_ZONE; /* no data at byte_offset */ excess -= NR_INDIRECTS; /* get block containing dbl indirect mappings */ blk = get_block(z, TRUE); /* set z to the zone containing the direct mappings */ z = ((u16 *)blk->blk_data)[excess/NR_INDIRECTS]; excess = excess % NR_INDIRECTS; put_block(blk, INDIRECT_BLOCK); } /* z is zone number for single indirect block. excess is an index into * it. */ if(z == NO_ZONE) return NO_ZONE; /* no data at byte_offset */ blk = get_block(z, TRUE); /* load indirect mappings */ z = ((u16 *)blk->blk_data)[excess]; /* z now points to data zone */ put_block(blk, INDIRECT_BLOCK); return z; /* could be NO_ZONE */ }
/*===========================================================================* * lmfs_put_block * *===========================================================================*/ void lmfs_put_block(struct buf *bp) { /* User interface to put_block(). */ if (bp == NULL) return; /* for poorly written file systems */ put_block(bp, 0); }
int clear_disk() { for (int i=0; i<512; i++) { disk_bitmap[i] = 0; char *buf = calloc(128, sizeof(char)); put_block(i, buf); } return 0; }