Ejemplo n.º 1
0
static struct buf* fetch_inode(struct dir_extent *extent, size_t *offset)
{
	struct iso9660_dir_record *dir_rec;
	struct buf *bp;

	/*
	 * Directory entries aren't allowed to cross a logical block boundary in
	 * ISO 9660, so we keep searching until we find something or reach the
	 * end of the extent.
	 */
	bp = read_extent_block(extent, *offset / v_pri.logical_block_size_l);
	while (bp != NULL) {
		dir_rec = (struct iso9660_dir_record*)(b_data(bp) + *offset %
		          v_pri.logical_block_size_l);
		if (dir_rec->length == 0) {
			*offset -= *offset % v_pri.logical_block_size_l;
			*offset += v_pri.logical_block_size_l;
		}
		else {
			break;
		}

		lmfs_put_block(bp, FULL_DATA_BLOCK);
		bp = read_extent_block(extent, *offset /
		    v_pri.logical_block_size_l);
	}

	return bp;
}
Ejemplo n.º 2
0
Archivo: read.c Proyecto: Hooman3/minix
ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
	off_t pos, int __unused call)
{
	size_t off, chunk, block_size, cum_io;
	off_t f_size;
	struct inode *i_node;
	struct buf *bp;
	int r;

	/* Try to get inode according to its index. */
	if ((i_node = find_inode(ino_nr)) == NULL)
		return EINVAL; /* No inode found. */

	f_size = i_node->i_stat.st_size;
	if (pos >= f_size)
		return 0; /* EOF */

	/* Limit the request to the remainder of the file size. */
	if ((off_t)bytes > f_size - pos)
		bytes = (size_t)(f_size - pos);

	block_size = v_pri.logical_block_size_l;
	cum_io = 0;

	lmfs_reset_rdwt_err();
	r = OK;

	/* Split the transfer into chunks that don't span two blocks. */
	while (bytes > 0) {
		off = pos % block_size;

		chunk = block_size - off;
		if (chunk > bytes)
			chunk = bytes;

		/* Read 'chunk' bytes. */
		bp = read_extent_block(i_node->extent, pos / block_size);
		if (bp == NULL)
			panic("bp not valid in rw_chunk; this can't happen");

		r = fsdriver_copyout(data, cum_io, b_data(bp)+off, chunk);

		lmfs_put_block(bp, FULL_DATA_BLOCK);

		if (r != OK)
			break;  /* EOF reached. */
		if (lmfs_rdwt_err() < 0)
			break;

		/* Update counters and pointers. */
		bytes -= chunk;		/* Bytes yet to be read. */
		cum_io += chunk;	/* Bytes read so far. */
		pos += chunk;		/* Position within the file. */
	}

	if (lmfs_rdwt_err() != OK)
		r = lmfs_rdwt_err();	/* Check for disk error. */
	if (lmfs_rdwt_err() == END_OF_FILE)
		r = OK;

	return (r == OK) ? cum_io : r;
}
Ejemplo n.º 3
0
static int ext2_read_file1(int fd, void *read_start,
		size_t size, size_t pos, struct ext2_inode *inode)
{
	struct ext4_extent_hdr *extent_hdr;

	long long blk;
	size_t off;
	int i;
	__u32 blk_start = pos / sb_block_size;
	__u32 blk_end = (pos + size + sb_block_size - 1) / sb_block_size;
	off = 0;
#ifdef DEBUG_IDE
	printf("size:%d, pos:%d flags:0x%x\n", size, pos, inode->i_flags);
#endif

	extent_hdr = (struct ext4_extent_hdr *)(inode->i_block);

	for(i = blk_start; i < blk_end; i++) {
		int skip;
		int len;
		int ret;

		blk = read_extent_block(fd, extent_hdr, i);
#ifdef DEBUG_IDE
		printf("blk:%d, file_block:%d\n", blk, i);
#endif
		if(blk < 0)
			return -1;

		if(i == pos / sb_block_size) {
			skip = pos % sb_block_size;
			len = (size <= (sb_block_size - skip) ?
					size : sb_block_size - skip);
		} else {
			skip = 0;
			len = (size <= sb_block_size ?
					size : sb_block_size);

		}

		if(!len)
			break;

		if(size / sb_block_size)
			len = sb_block_size - skip;
		else
			len = size % sb_block_size;
		if(!len)
			len = sb_block_size;

		/*blk = blk * sb_block_size + START_PARTION + skip * sb_block_size;*/
		blk = blk * sb_block_size + START_PARTION + skip;
		devio_lseek(fd, blk, 0);
		ret = devio_read(fd, read_start + off, len);
#ifdef DEBUG_IDE
		printf("ret:%d, size:%d, off:%d, skip:%d, len:%d \n",
				ret, size, off, skip, len);
#endif
		if(ret < 0)
			return -1;
		if(ret != len)
			return ret + off;

		size -= len;
		off += len;
	}

#ifdef DEBUG_IDE
	printf("size:%d, off:%d\n", size, off);
#endif
	return off;
}
Ejemplo n.º 4
0
void read_inode_extents(struct inode *i,
	const struct iso9660_dir_record *dir_rec,
	struct dir_extent *extent, size_t *offset)
{
	struct buf *bp;
	struct iso9660_dir_record *extent_rec;
	struct dir_extent *cur_extent = i->extent;
	int done = FALSE;

	/*
	 * No need to search extents if file is empty or has final directory
	 * record flag set.
	 */
	if (cur_extent == NULL ||
	    ((dir_rec->file_flags & D_NOT_LAST_EXTENT) == 0))
		return;

	while (!done) {
		bp = fetch_inode(extent, offset);
		if (bp == NULL)
			return;

		bp = read_extent_block(extent,
		    *offset / v_pri.logical_block_size_l);
		extent_rec = (struct iso9660_dir_record*)(b_data(bp) +
		    *offset % v_pri.logical_block_size_l);

		if (check_dir_record(dir_rec,
		    *offset % v_pri.logical_block_size_l) != OK) {
			lmfs_put_block(bp, FULL_DATA_BLOCK);
			return;
		}

		/* Extent entries should share the same name. */
		if ((dir_rec->length_file_id == extent_rec->length_file_id) &&
		    (memcmp(dir_rec->file_id, extent_rec->file_id,
		    dir_rec->length_file_id) == 0)) {
			/* Add the extent at the end of the linked list. */
			assert(cur_extent->next == NULL);
			cur_extent->next = alloc_extent();
			cur_extent->next->location = dir_rec->loc_extent_l +
			    dir_rec->ext_attr_rec_length;
			cur_extent->next->length = dir_rec->data_length_l /
			    v_pri.logical_block_size_l;
			if (dir_rec->data_length_l % v_pri.logical_block_size_l)
				cur_extent->next->length++;

			i->i_stat.st_size += dir_rec->data_length_l;
			i->i_stat.st_blocks += cur_extent->next->length;

			cur_extent = cur_extent->next;
			*offset += extent_rec->length;
		}
		else
			done = TRUE;

		/* Check if not last extent bit is not set. */
		if ((dir_rec->file_flags & D_NOT_LAST_EXTENT) == 0)
			done = TRUE;

		lmfs_put_block(bp, FULL_DATA_BLOCK);
	}
}