Exemplo n.º 1
0
/*
 * blk_alloc()
 *	Request an existing file have its allocation increased
 *
 * Returns 0 on success, 1 on failure.
 */
int
blk_alloc(struct inode *i, uint newsize)
{
	/*
	 * If the start is 0, it's "truncated" or new, so we update
	 * it to the current place our free blocks start, and put it into
	 * the block allocation list.
	 */
	if (i->i_start == 0) {
		ASSERT_DEBUG(i->i_fsize == 0, "blk_alloc: trunc with length");
		i->i_start = spc_inode->i_start 
				+ BLOCKS(spc_inode->i_fsize);
		ino_addblklist(i);
	}

	/*
	 * We now decide what alterations need to be made to the block
	 * allocations within the inode.  First we check that we have enough
	 * space available to allocate the required data
	 */
	if (BLOCKS(newsize) > i->i_blocks) {
		/*
		 * We really ought to be far more intelligent about what
		 * we do here - my ideas so far are to first try and
		 * grab some space from a near neighbour - if one has some.
		 * Next we try moving the file (or if a neighbour's smaller
		 * and freeing the space will be enough we move the
		 * neighbour) to the largest free slot available (if that's
		 * big enough) and finally if all else fails we'll compact
		 * the whole fs down!
		 */
		return 1;
	}

	/*
	 * OK, so there's enough space to allocate the required blocks.
	 * Now we juggle the block details within the inode to reflect the
	 * changes
	 */
	i->i_fsize = newsize;

	/*
	 * Mark the inode dirty.  Superblock probably also dirty; mark it so.
	 */
	ino_dirty(i);
	bdirty(shandle);

	return 0;
}
Exemplo n.º 2
0
void block_free(byte *block, size_t size)
{
  unsigned int space_nr = SPACE(block);
  unsigned int block_nr = BLOCK_NR(block);
  size_t blocks = BLOCKS(size);
  byte *block_map = SPACE_MAP(space_nr);
  int i;
  int ok = 1;

  for(i=0; i<blocks; ++i)
    block_map[block_nr+i] = TYPE_FREE;
  /* See if we can free the entire space */
  for (i=0; i<BLOCKS_PER_SPACE; i++) {
    if (block_map[i] != TYPE_FREE) {
      ok = 0;
      break;
    }
  }

  unmap(block, GRAINROUND(page_size, size));
  if (ok) {
    /* Free the entire space */
    release_arena_space(space_nr);
  }
}
Exemplo n.º 3
0
int memory_read(stream_t* stream, void* m, size_t n)
{
    int i = 0;
    for(; i < BLOCKS(stream, n); i++)
        block_read(stream, MEMORY_BLOCK(stream, m, i));
    return 0;
}
Exemplo n.º 4
0
int memory_write(stream_t* stream, void* m, size_t n)
{
    int i = 0;
    printf("Memory: 0x%X\n", (unsigned int)m);
    for(; i < BLOCKS(stream, n); i++)
        block_write(stream, MEMORY_BLOCK(stream, m, i));
    return 0;
}
Exemplo n.º 5
0
byte *block_alloc(byte type, size_t size)
{
  int s, b, found = 0, blocks = BLOCKS(size);
  byte *block_map;
  byte *space;

  if (arena_state != INITIALIZED)
    arena_init();

  if (blocks > BLOCKS_PER_SPACE)
    error("Trying to allocate too many contiguous blocks.");

  for(s=0; s<SPACES_IN_ARENA; ++s) {
    if (space_type[s] == TYPE_BLOCKS) {
      block_map = SPACE_MAP(s);
      for (b=0; b<BLOCKS_PER_SPACE; b++) {
	if (block_map[b] == TYPE_FREE) {
	  found ++;
	  if(found >= blocks) {
	    int start = b+1-found, k;

	    for(k=start; k<=b; ++k)
	      block_map[k] = type;
	    map(BLOCK_BASE(s,start), GRAINROUND(page_size, size));
	    return(BLOCK_BASE(s,start));
	  }
	}
	else
	  found = 0;
      }
      found = 0;
    }
  }

  /* None of the existing block spaces have room; let's make a new one */

  space = space_alloc(TYPE_BLOCKS,0);    /* allocate the new space */
  s = SPACE(space);
  block_map = SPACE_MAP(s) = block_maps + s*BLOCKS_PER_SPACE;
  /* This is where the map is */

  for(b=0; b< blocks; ++b)
    block_map[b] = type;
  for (b=blocks; b < BLOCKS_PER_SPACE; b++)
    block_map[b] = TYPE_FREE;		 /* ... and initialize it */

  map(space, GRAINROUND(page_size, size));
  return(space);
}
Exemplo n.º 6
0
static secno hpfs_bmap(struct inode *inode, unsigned file_secno)
{
	struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
	unsigned n, disk_secno;
	struct fnode *fnode;
	struct buffer_head *bh;
	if (BLOCKS(hpfs_i(inode)->mmu_private) <= file_secno) return 0;
	n = file_secno - hpfs_inode->i_file_sec;
	if (n < hpfs_inode->i_n_secs) return hpfs_inode->i_disk_sec + n;
	if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0;
	disk_secno = hpfs_bplus_lookup(inode->i_sb, inode, &fnode->btree, file_secno, bh);
	if (disk_secno == -1) return 0;
	if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0;
	return disk_secno;
}
Exemplo n.º 7
0
/*
 * blk_trunc()
 *	Remove the blocks from under the named file
 *
 * The freed blocks are allocated back onto the previous inode's managed
 * list.  Note that we don't mark the inode dirty.  This is because the
 * caller will often *further* dirty the inode, so no need to do it twice.
 */
void
blk_trunc(struct inode *i)
{
	int blocks;

	/*
	 * Add blocks worth of storage back onto free count
	 */
	blocks = BLOCKS(i->i_fsize);
	sblock->s_free += blocks;

	/*
	 * Flag start/len as 0.  blk_alloc() will notice this
	 * and update where the free blocks start.
	 */
	i->i_start = i->i_fsize = 0;
	bdirty(shandle);

	/*
	 * Sort out all references to our former block neighbours
	 */
	if (i->i_prev != I_FREE) {
		ilist[i->i_prev]->i_next = i->i_next;
		ilist[i->i_prev]->i_blocks += i->i_blocks;
		if (i == spc_inode) {
			spc_inode = ilist[i->i_prev];
		}
	}
	if (i->i_next != I_FREE ) {
		ilist[i->i_next]->i_prev = i->i_prev;
	}

	/*
	 * Finally remove references to our former neighbours
	 */
	i->i_next = I_FREE;
	i->i_prev = I_FREE;
}
Exemplo n.º 8
0
int LinnCreate::create(Size blockSize, Size blockNum, Size inodeNum)
{
    LinnGroup *group;
    BitArray map(128);

    assert(image != ZERO);
    assert(prog  != ZERO);
    assert(blockNum >= 2);
    assert(inodeNum > 0);

    /* Allocate blocks. */
    blocks = new u8[blockSize * blockNum];
    memset(blocks, 0, blockSize * blockNum);

    /* Create a superblock. */
    super = (LinnSuperBlock *) (blocks + LINN_SUPER_OFFSET);
    super->magic0 = LINN_SUPER_MAGIC0;
    super->magic1 = LINN_SUPER_MAGIC1;
    super->majorRevision    = LINN_SUPER_MAJOR;
    super->minorRevision    = LINN_SUPER_MINOR;
    super->state            = LINN_SUPER_VALID;
    super->blockSize        = blockSize;
    super->blocksPerGroup   = LINN_CREATE_BLOCKS_PER_GROUP;
    super->inodesCount      = inodeNum;
    super->blocksCount	    = blockNum;
    super->inodesPerGroup   = super->inodesCount / LINN_GROUP_COUNT(super);
    super->freeInodesCount  = super->inodesCount;
    super->freeBlocksCount  = blockNum - 3;
    super->creationTime     = time(ZERO);
    super->mountTime	    = ZERO;
    super->mountCount	    = ZERO;
    super->lastCheck	    = ZERO;
    super->groupsTable	    = 2;

    /* Allocate LinnGroups. */
    for (Size i = 0; i < LINN_GROUP_COUNT(super); i++)
    {
	/* Point to the correct LinnGroup. */
	group = BLOCKPTR(LinnGroup, 2) + i;

	/* Fill the group. */
	group->freeBlocksCount = super->blocksPerGroup;
	group->freeInodesCount = super->inodesPerGroup;
	group->blockMap        = BLOCKS(super, LINN_GROUP_NUM_BLOCKMAP(super));
	group->inodeMap        = BLOCKS(super, LINN_GROUP_NUM_INODEMAP(super));
	group->inodeTable      = BLOCKS(super, LINN_GROUP_NUM_INODETAB(super));
    }
    /* Create special inodes. */
    createInode(LINN_INODE_ROOT, DirectoryFile,
		OwnerRWX | GroupRX | OtherRX);
    createInode(LINN_INODE_LOADER, RegularFile,
		OwnerRWX | GroupRX | OtherRX);
    createInode(LINN_INODE_BAD, RegularFile,
		OwnerRW | GroupR | OtherR);
    createInode(LINN_INODE_JOURNAL, RegularFile,
		OwnerRW | GroupR | OtherR);

    /* Insert into directory contents, if set. */
    if (input)
    {
	insertDirectory(input, LINN_INODE_ROOT,
			       LINN_INODE_ROOT);
    }
    /* Mark blocks used. */
    for (le32 block = 0; block < super->freeBlocksCount; block++)
    {
	/* Point to group. */
	group = BLOCKPTR(LinnGroup, super->groupsTable) +
			(block / super->blocksPerGroup);
	group->freeBlocksCount--;
	
	/* Mark the block used. */
	map.setArray(BLOCKPTR(u8, group->blockMap),
		   super->blocksPerGroup);
	map.set(block % super->blocksPerGroup);
    }
    /* Write the final image. */
    return writeImage();
}