Example #1
0
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;
}
Example #2
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;
}
Example #3
0
/**
 * 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;
}
Example #4
0
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");
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
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);
}
Example #11
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;
}
Example #12
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;
}
Example #13
0
/* 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);
}
Example #14
0
/* 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);
  }
}
Example #15
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;
}
Example #16
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);
    }
}
Example #17
0
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;
}
Example #18
0
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);
}
Example #20
0
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;
}
Example #21
0
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));

}
Example #22
0
/* 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 */
	}
}
Example #23
0
/*
 * 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;
}
Example #24
0
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;
}
Example #25
0
/* 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;
}
Example #26
0
/* 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;
}
Example #27
0
/*===========================================================================*
 *                             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);
}
Example #28
0
/*
 * 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);
}
Example #30
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;
}