예제 #1
0
static struct ext2_group_desc * get_group_desc (struct super_block * sb,
						unsigned int block_group,
						struct buffer_head ** bh)
{
	unsigned long group_desc;
	unsigned long desc;
	struct ext2_group_desc * gdp;

	if (block_group >= sb->u.ext2_sb.s_groups_count)
		ext2_panic (sb, "get_group_desc",
			    "block_group >= groups_count - "
			    "block_group = %d, groups_count = %lu",
			    block_group, sb->u.ext2_sb.s_groups_count);

	group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
	desc = block_group % EXT2_DESC_PER_BLOCK(sb);
	if (!sb->u.ext2_sb.s_group_desc[group_desc])
		ext2_panic (sb, "get_group_desc",
			    "Group descriptor not loaded - "
			    "block_group = %d, group_desc = %lu, desc = %lu",
			     block_group, group_desc, desc);
	gdp = (struct ext2_group_desc *) 
		sb->u.ext2_sb.s_group_desc[group_desc]->b_data;
	if (bh)
		*bh = sb->u.ext2_sb.s_group_desc[group_desc];
	return gdp + desc;
}
예제 #2
0
/*
 * load_inode_bitmap loads the inode bitmap for a blocks group
 *
 * It maintains a cache for the last bitmaps loaded.  This cache is managed
 * with a LRU algorithm.
 *
 * Notes:
 * 1/ There is one cache per mounted file system.
 * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
 *    this function reads the bitmap without maintaining a LRU cache.
 * 
 * Return the buffer_head of the bitmap or the ERR_PTR(error)
 */
static struct buffer_head *load_inode_bitmap (struct super_block * sb,
					      unsigned int block_group)
{
	int i, slot = 0;
	struct ext2_sb_info *sbi = &sb->u.ext2_sb;
	struct buffer_head *bh = sbi->s_inode_bitmap[0];

	if (block_group >= sbi->s_groups_count)
		ext2_panic (sb, "load_inode_bitmap",
			    "block_group >= groups_count - "
			    "block_group = %d, groups_count = %lu",
			     block_group, sbi->s_groups_count);

	if (sbi->s_loaded_inode_bitmaps > 0 &&
	    sbi->s_inode_bitmap_number[0] == block_group && bh)
		goto found;

	if (sbi->s_groups_count <= EXT2_MAX_GROUP_LOADED) {
		slot = block_group;
		bh = sbi->s_inode_bitmap[slot];
		if (!bh)
			goto read_it;
		if (sbi->s_inode_bitmap_number[slot] == slot)
			goto found;
		ext2_panic (sb, "load_inode_bitmap",
			    "block_group != inode_bitmap_number");
	}

	bh = NULL;
	for (i = 0; i < sbi->s_loaded_inode_bitmaps &&
		    sbi->s_inode_bitmap_number[i] != block_group;
	     i++)
		;
	if (i < sbi->s_loaded_inode_bitmaps)
		bh = sbi->s_inode_bitmap[i];
	else if (sbi->s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED)
		sbi->s_loaded_inode_bitmaps++;
	else
		brelse (sbi->s_inode_bitmap[--i]);

	while (i--) {
		sbi->s_inode_bitmap_number[i+1] = sbi->s_inode_bitmap_number[i];
		sbi->s_inode_bitmap[i+1] = sbi->s_inode_bitmap[i];
	}

read_it:
	if (!bh)
		bh = read_inode_bitmap (sb, block_group);
	sbi->s_inode_bitmap_number[slot] = block_group;
	sbi->s_inode_bitmap[slot] = bh;
	if (!bh)
		return ERR_PTR(-EIO);
found:
	return bh;
}
예제 #3
0
파일: ext2fs.c 프로젝트: GNUHurdTR/hurd
int
main (int argc, char **argv)
{
  error_t err;
  mach_port_t bootstrap;

  /* Initialize the diskfs library, parse arguments, and open the store.
     This starts the first diskfs thread for us.  */
  store = diskfs_init_main (&startup_argp, argc, argv,
			    &store_parsed, &bootstrap);

  if (store->size < SBLOCK_OFFS + SBLOCK_SIZE)
    ext2_panic ("device too small for superblock (%Ld bytes)", store->size);
  if (store->log2_blocks_per_page < 0)
    ext2_panic ("device block size (%zu) greater than page size (%zd)",
		store->block_size, vm_page_size);

  /* Map the entire disk. */
  create_disk_pager ();

  pokel_init (&global_pokel, diskfs_disk_pager, disk_cache);

  map_hypermetadata ();

  /* Set diskfs_root_node to the root inode. */
  err = diskfs_cached_lookup (EXT2_ROOT_INO, &diskfs_root_node);
  if (err)
    ext2_panic ("can't get root: %s", strerror (err));
  else if ((diskfs_root_node->dn_stat.st_mode & S_IFMT) == 0)
    ext2_panic ("no root node!");
  pthread_mutex_unlock (&diskfs_root_node->lock);

  /* Now that we are all set up to handle requests, and diskfs_root_node is
     set properly, it is safe to export our fsys control port to the
     outside world.  */
  diskfs_startup_diskfs (bootstrap, 0);

  /* and so we die, leaving others to do the real work.  */
  pthread_exit (NULL);
  /* NOTREACHED */
  return 0;
}
예제 #4
0
/*
 * load_inode_bitmap loads the inode bitmap for a blocks group
 *
 * It maintains a cache for the last bitmaps loaded.  This cache is managed
 * with a LRU algorithm.
 *
 * Notes:
 * 1/ There is one cache per mounted file system.
 * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
 *    this function reads the bitmap without maintaining a LRU cache.
 * 
 * Return the slot used to store the bitmap, or a -ve error code.
 */
static int load_inode_bitmap (struct super_block * sb,
			      unsigned int block_group)
{
	int i, j, retval = 0;
	unsigned long inode_bitmap_number;
	struct buffer_head * inode_bitmap;

	if (block_group >= sb->u.ext2_sb.s_groups_count)
		ext2_panic (sb, "load_inode_bitmap",
			    "block_group >= groups_count - "
			    "block_group = %d, groups_count = %lu",
			     block_group, sb->u.ext2_sb.s_groups_count);
	if (sb->u.ext2_sb.s_loaded_inode_bitmaps > 0 &&
	    sb->u.ext2_sb.s_inode_bitmap_number[0] == block_group &&
	    sb->u.ext2_sb.s_inode_bitmap[0] != NULL)
		return 0;
	if (sb->u.ext2_sb.s_groups_count <= EXT2_MAX_GROUP_LOADED) {
		if (sb->u.ext2_sb.s_inode_bitmap[block_group]) {
			if (sb->u.ext2_sb.s_inode_bitmap_number[block_group] != block_group)
				ext2_panic (sb, "load_inode_bitmap",
					    "block_group != inode_bitmap_number");
			else
				return block_group;
		} else {
			retval = read_inode_bitmap (sb, block_group,
						    block_group);
			if (retval < 0)
				return retval;
			return block_group;
		}
	}

	for (i = 0; i < sb->u.ext2_sb.s_loaded_inode_bitmaps &&
		    sb->u.ext2_sb.s_inode_bitmap_number[i] != block_group;
	     i++)
		;
	if (i < sb->u.ext2_sb.s_loaded_inode_bitmaps &&
  	    sb->u.ext2_sb.s_inode_bitmap_number[i] == block_group) {
		inode_bitmap_number = sb->u.ext2_sb.s_inode_bitmap_number[i];
		inode_bitmap = sb->u.ext2_sb.s_inode_bitmap[i];
		for (j = i; j > 0; j--) {
			sb->u.ext2_sb.s_inode_bitmap_number[j] =
				sb->u.ext2_sb.s_inode_bitmap_number[j - 1];
			sb->u.ext2_sb.s_inode_bitmap[j] =
				sb->u.ext2_sb.s_inode_bitmap[j - 1];
		}
		sb->u.ext2_sb.s_inode_bitmap_number[0] = inode_bitmap_number;
		sb->u.ext2_sb.s_inode_bitmap[0] = inode_bitmap;

		/*
		 * There's still one special case here --- if inode_bitmap == 0
		 * then our last attempt to read the bitmap failed and we have
		 * just ended up caching that failure.  Try again to read it.
		 */
		if (!inode_bitmap)
			retval = read_inode_bitmap (sb, block_group, 0);
		
	} else {
		if (sb->u.ext2_sb.s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED)
			sb->u.ext2_sb.s_loaded_inode_bitmaps++;
		else
			brelse (sb->u.ext2_sb.s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1]);
		for (j = sb->u.ext2_sb.s_loaded_inode_bitmaps - 1; j > 0; j--) {
			sb->u.ext2_sb.s_inode_bitmap_number[j] =
				sb->u.ext2_sb.s_inode_bitmap_number[j - 1];
			sb->u.ext2_sb.s_inode_bitmap[j] =
				sb->u.ext2_sb.s_inode_bitmap[j - 1];
		}
		retval = read_inode_bitmap (sb, block_group, 0);
	}
	return retval;
}