Esempio n. 1
0
File: ext2.c Progetto: wgwoods/aboot
/*
 * Initialize an ext2 partition starting at offset P_OFFSET; this is
 * sort-of the same idea as "mounting" it.  Read in the relevant
 * control structures and make them available to the user.  Returns 0
 * if successful, -1 on failure.
 */
static int ext2_mount(long cons_dev, long p_offset, long quiet)
{
	long sb_block = 1;
	long sb_offset;
	int i;

	dev = cons_dev;
	partition_offset = p_offset;

	/* initialize the inode table */
	for (i = 0; i < MAX_OPEN_FILES; i++) {
		inode_table[i].free = 1;
		inode_table[i].inumber = 0;
	}
	/* clear the root inode pointer (very important!) */
	root_inode = NULL;
	
	/* read in the first superblock */
	sb_offset = sb_block * EXT2_MIN_BLOCK_SIZE;
	if (cons_read(dev, &sb, sizeof(sb), partition_offset + sb_offset)
	    != sizeof(sb))
	{
		printf("ext2 sb read failed\n");
		return -1;
	}
	
	if (sb.s_magic != EXT2_SUPER_MAGIC) {
		if (!quiet) {
			printf("ext2_init: bad magic 0x%x\n", sb.s_magic);
		}
		return -1;
	}

	ngroups = (sb.s_blocks_count -
		   sb.s_first_data_block +
		   EXT2_BLOCKS_PER_GROUP(&sb) - 1)
		/ EXT2_BLOCKS_PER_GROUP(&sb);

	gds = (struct ext2_group_desc *)
	          malloc((size_t)(ngroups * sizeof(struct ext2_group_desc)));

	ext2fs.blocksize = EXT2_BLOCK_SIZE(&sb);

	/* read in the group descriptors (immediately follows superblock) */
	cons_read(dev, gds, ngroups * sizeof(struct ext2_group_desc),
		  partition_offset +
                  ext2fs.blocksize * (EXT2_MIN_BLOCK_SIZE/ext2fs.blocksize + 1));
	/*
	 * Calculate direct/indirect block limits for this file system
	 * (blocksize dependent):
	 */
	ext2fs.blocksize = EXT2_BLOCK_SIZE(&sb);
	directlim = EXT2_NDIR_BLOCKS - 1;
	ptrs_per_blk = ext2fs.blocksize/sizeof(unsigned int);
	ind1lim = ptrs_per_blk + directlim;
	ind2lim = (ptrs_per_blk * ptrs_per_blk) + directlim;

	return 0;
}
Esempio n. 2
0
int main(void *arg)
{
        int fid = (int)arg;
        int c = cons_read();
        assert(psend(fid, 1) == 0);
        printf(" %d (%c)", 134 - getprio(getpid()), c);
        return 0;
}
Esempio n. 3
0
File: ext2.c Progetto: wgwoods/aboot
/*
 * Read the specified inode from the disk and return it to the user.
 * Returns NULL if the inode can't be read...
 */
static struct ext2_inode *ext2_iget(int ino)
{
	int i;
	struct ext2_inode *ip;
	struct inode_table_entry *itp = 0;
	int group;
	long offset;

	ip = 0;
	for (i = 0; i < MAX_OPEN_FILES; i++) {
#ifdef DEBUG_EXT2
		printf("ext2_iget: looping, entry %d inode %d free %d\n",
		       i, inode_table[i].inumber, inode_table[i].free);
#endif
		if (inode_table[i].free) {
			itp = &inode_table[i];
			ip = &itp->inode;
			break;
		}
	}
	if (!ip) {
		printf("ext2_iget: no free inodes\n");
		return NULL;
	}

	group = (ino-1) / sb.s_inodes_per_group;
#ifdef DEBUG_EXT2
	printf("group is %d\n", group);
#endif
	offset = partition_offset
		+ ((long) gds[group].bg_inode_table * (long)ext2fs.blocksize)
		+ (((ino - 1) % EXT2_INODES_PER_GROUP(&sb))
		   * EXT2_INODE_SIZE(&sb));
#ifdef DEBUG_EXT2
	printf("ext2_iget: reading %ld bytes at offset %ld "
	       "(%ld + (%d * %d) + ((%d) %% %d) * %d) "
	       "(inode %d -> table %d)\n", 
	       sizeof(struct ext2_inode), offset, partition_offset,
	       gds[group].bg_inode_table, ext2fs.blocksize,
	       ino - 1, EXT2_INODES_PER_GROUP(&sb), EXT2_INODE_SIZE(&sb),
	       ino, (int) (itp - inode_table));
#endif
	if (cons_read(dev, ip, sizeof(struct ext2_inode), offset) 
	    != sizeof(struct ext2_inode))
	{
		printf("ext2_iget: read error\n");
		return NULL;
	}

	itp->free = 0;
	itp->inumber = ino;
	itp->old_mode = ip->i_mode;

	return ip;
}
Esempio n. 4
0
File: ext2.c Progetto: wgwoods/aboot
static int ext2_breadi(struct ext2_inode *ip, long blkno, long nblks,
		       char *buffer)
{
	long dev_blkno, ncontig, offset, nbytes, tot_bytes;

	tot_bytes = 0;
	if ((blkno+nblks)*ext2fs.blocksize > ip->i_size)
		nblks = (ip->i_size + ext2fs.blocksize) / ext2fs.blocksize - blkno;

	while (nblks) {
		/*
		 * Contiguous reads are a lot faster, so we try to group
		 * as many blocks as possible:
		 */
		ncontig = 0; nbytes = 0;
		dev_blkno = ext2_blkno(ip, blkno);
		do {
			++blkno; ++ncontig; --nblks;
			nbytes += ext2fs.blocksize;
		} while (nblks &&
			 ext2_blkno(ip, blkno) == dev_blkno + ncontig);

		if (dev_blkno == 0) {
			/* This is a "hole" */
			memset(buffer, 0, nbytes);
		} else {
			/* Read it for real */
			offset = partition_offset + (long) dev_blkno* (long) ext2fs.blocksize;
#ifdef DEBUG_EXT2
			printf("ext2_bread: reading %ld bytes at offset %ld\n",
			       nbytes, offset);
#endif
			if (cons_read(dev, buffer, nbytes, offset)
			    != nbytes)
			{
				printf("ext2_bread: read error\n");
				return -1;
			}
		}
		buffer    += nbytes;
		tot_bytes += nbytes;
	}
	return tot_bytes;
}
Esempio n. 5
0
File: ext2.c Progetto: wgwoods/aboot
/*
 * Map a block offset into a file into an absolute block number.
 * (traverse the indirect blocks if necessary).  Note: Double-indirect
 * blocks allow us to map over 64Mb on a 1k file system.  Therefore, for
 * our purposes, we will NOT bother with triple indirect blocks.
 *
 * The "allocate" argument is set if we want to *allocate* a block
 * and we don't already have one allocated.
 */
static int ext2_blkno(struct ext2_inode *ip, int blkoff)
{
	unsigned int *lp;
	unsigned int *ilp;
	unsigned int *dlp;
	int blkno;
	int iblkno;
	int diblkno;
	unsigned long offset;

	ilp = (unsigned int *)iblkbuf;
	dlp = (unsigned int *)diblkbuf;
	lp = (unsigned int *)blkbuf;

	/* If it's a direct block, it's easy! */
	if (blkoff <= directlim) {
		return ip->i_block[blkoff];
	}

	/* Is it a single-indirect? */
	if (blkoff <= ind1lim) {
		iblkno = ip->i_block[EXT2_IND_BLOCK];

		if (iblkno == 0) {
			return 0;
		}

		/* Read the indirect block */
		if (cached_iblkno != iblkno) {
			offset = partition_offset + (long)iblkno * (long)ext2fs.blocksize;
			if (cons_read(dev, iblkbuf, ext2fs.blocksize, offset)
			    != ext2fs.blocksize)
			{
				printf("ext2_blkno: error on iblk read\n");
				return 0;
			}
			cached_iblkno = iblkno;
		}

		blkno = ilp[blkoff-(directlim+1)];
		return blkno;
	}

	/* Is it a double-indirect? */
	if (blkoff <= ind2lim) {
		/* Find the double-indirect block */
		diblkno = ip->i_block[EXT2_DIND_BLOCK];

		if (diblkno == 0) {
			return 0;
		}

		/* Read in the double-indirect block */
		if (cached_diblkno != diblkno) {
			offset = partition_offset + (long) diblkno * (long) ext2fs.blocksize;
			if (cons_read(dev, diblkbuf, ext2fs.blocksize, offset)
			    != ext2fs.blocksize)
			{
				printf("ext2_blkno: err reading dindr blk\n");
				return 0;
			}
			cached_diblkno = diblkno;
		}

		/* Find the single-indirect block pointer ... */
		iblkno = dlp[(blkoff - (ind1lim+1)) / ptrs_per_blk];

		if (iblkno == 0) {
			return 0;
		}

		/* Read the indirect block */
    
		if (cached_iblkno != iblkno) {
			offset = partition_offset + (long) iblkno * (long) ext2fs.blocksize;
			if (cons_read(dev, iblkbuf, ext2fs.blocksize, offset)
			    != ext2fs.blocksize)
			{
				printf("ext2_blkno: err on iblk read\n");
				return 0;
			}
			cached_iblkno = iblkno;
		}

		/* Find the block itself. */
		blkno = ilp[(blkoff-(ind1lim+1)) % ptrs_per_blk];
		return blkno;
	}

	if (blkoff > ind2lim) {
		printf("ext2_blkno: block number too large: %d\n", blkoff);
		return 0;
	}
	return -1;
}