Beispiel #1
0
int position_filemarks_forw(uint32_t count, uint8_t *sam_stat)
{
	uint32_t residual;
	unsigned int i;

	if (!tape_loaded(sam_stat))
		return -1;

	if (mam.MediumType == MEDIA_TYPE_WORM)
		OK_to_write = 0;

	/* Find the block number of the first filemark greater than our
	   current position.
	*/

	for (i = 0; i < meta.filemark_count; i++)
		if (filemarks[i] >= raw_pos.hdr.blk_number)
			break;

	if (i + count - 1 < meta.filemark_count)
		return position_to_block(filemarks[i + count - 1] + 1, sam_stat);
	else {
		residual = i + count - meta.filemark_count;
		if (read_header(eod_blk_number, sam_stat))
			return -1;

		sam_blank_check(E_END_OF_DATA, sam_stat);
		put_unaligned_be32(residual, &sense[3]);
		return -1;
	}
}
Beispiel #2
0
int position_to_block(uint32_t blk_number, uint8_t *sam_stat)
{
	if (!tape_loaded(sam_stat))
		return -1;

	MHVTL_DBG(2, "Position to block %d", blk_number);

	if (mam.MediumType == MEDIA_TYPE_WORM)
		OK_to_write = 0;

	if (blk_number > eod_blk_number) {
		sam_blank_check(E_END_OF_DATA, sam_stat);
		MHVTL_DBG(1, "End of data detected while positioning");
		return position_to_eod(sam_stat);
	}

	/* Treat a position to block zero specially, as it has different
	   semantics than other blocks when the tape is WORM.
	*/

	if (blk_number == 0)
		return rewind_tape(sam_stat);
	else
		return read_header(blk_number, sam_stat);
}
Beispiel #3
0
static int skip_to_next_header(uint8_t *sam_stat)
{
	MHVTL_DBG(1, "skip_to_next_header");
	if (raw_pos.hdr.blk_type == B_EOD) {
		sam_blank_check(E_END_OF_DATA, sam_stat);
		MHVTL_DBG(1, "End of data detected while forward SPACEing!!");
		return -1;
	}

	if (raw_pos.next_blk != lseek64(datafile, raw_pos.next_blk, SEEK_SET)) {
		sam_medium_error(E_SEQUENTIAL_POSITION_ERR, sam_stat);
		MHVTL_DBG(1, "Unable to seek to next block header");
		return -1;
	}
	if (read_header(&raw_pos, sam_stat)) {
		sam_medium_error(E_SEQUENTIAL_POSITION_ERR, sam_stat);
		MHVTL_DBG(1, "Unable to read next block header");
		return -1;
	}
	/* Position to start of header (rewind over header) */
	if (raw_pos.curr_blk != position_to_curr_header(sam_stat)) {
		sam_medium_error(E_SEQUENTIAL_POSITION_ERR, sam_stat);
		MHVTL_DBG(1, "Error position in datafile. Offset: %" PRId64,
				raw_pos.curr_blk);
		return -1;
	}
	return 0;
}
Beispiel #4
0
int position_blocks_forw(uint32_t count, uint8_t *sam_stat)
{
	uint32_t residual;
	uint32_t blk_target;
	unsigned int i;

	if (!tape_loaded(sam_stat))
		return -1;

	if (mam.MediumType == MEDIA_TYPE_WORM)
		OK_to_write = 0;

	blk_target = raw_pos.hdr.blk_number + count;

	/* Find the first filemark forward from our current position, if any. */

	for (i = 0; i < meta.filemark_count; i++) {
		MHVTL_DBG(3, "filemark at %ld", (unsigned long)filemarks[i]);
		if (filemarks[i] >= raw_pos.hdr.blk_number)
			break;
	}

	/* If there is one, see if it is between our current position and our
	   desired destination.
	*/

	if (i < meta.filemark_count) {
		if (filemarks[i] >= blk_target)
			return position_to_block(blk_target, sam_stat);

		residual = blk_target - raw_pos.hdr.blk_number + 1;
		if (read_header(filemarks[i] + 1, sam_stat))
			return -1;

		MHVTL_DBG(1, "Filemark encountered: block %d", filemarks[i]);
		sam_no_sense(SD_FILEMARK, E_MARK, sam_stat);
		put_unaligned_be32(residual, &sense[3]);
		return -1;
	}

	if (blk_target > eod_blk_number) {
		residual = blk_target - eod_blk_number;
		if (read_header(eod_blk_number, sam_stat))
			return -1;

		MHVTL_DBG(1, "EOD encountered");
		sam_blank_check(E_END_OF_DATA, sam_stat);
		put_unaligned_be32(residual, &sense[3]);
		return -1;
	}

	return position_to_block(blk_target, sam_stat);
}
Beispiel #5
0
uint32_t read_tape_block(uint8_t *buf, uint32_t buf_size, uint8_t *sam_stat)
{
	loff_t nread;
	uint32_t iosize;

	if (!tape_loaded(sam_stat))
		return -1;

	MHVTL_DBG(3, "Reading blk %ld, size: %d",
			(unsigned long)raw_pos.hdr.blk_number, buf_size);

	/* The caller should have already verified that this is a
	   B_DATA block before issuing this read, so we shouldn't have to
	   worry about B_EOD or B_FILEMARK here.
	*/

	if (raw_pos.hdr.blk_type == B_EOD) {
		sam_blank_check(E_END_OF_DATA, sam_stat);
		MHVTL_ERR("End of data detected while reading");
		return -1;
	}

	iosize = raw_pos.hdr.disk_blk_size;
	if (iosize > buf_size)
		iosize = buf_size;

	nread = pread(datafile, buf, iosize, raw_pos.data_offset);
	if (nread != iosize) {
		MHVTL_ERR("Failed to read %d bytes", iosize);
		return -1;
	}

	/* Now position to the following block. */

	if (read_header(raw_pos.hdr.blk_number + 1, sam_stat)) {
		MHVTL_ERR("Failed to read block header %d",
				raw_pos.hdr.blk_number + 1);
		return -1;
	}

	return nread;
}
Beispiel #6
0
static int skip_next_filemark(uint8_t *sam_stat)
{
	MHVTL_DBG(1, "skip_next_filemark");
	/* While blk header is NOT a filemark, keep skipping to next header */
	while (raw_pos.hdr.blk_type != B_FILEMARK) {
		/* END-OF-DATA -> Treat this as an error - return.. */
		if (raw_pos.hdr.blk_type == B_EOD) {
			sam_blank_check(E_END_OF_DATA, sam_stat);
			MHVTL_DBG(2, "%s", "Found end of media");
			if (MediumType == MEDIA_TYPE_WORM)
				OK_to_write = 1;
			return -1;
		}
		if (skip_to_next_header(sam_stat))
			return -1;	/* On error */
	}
	/* Position to header AFTER the FILEMARK.. */
	if (skip_to_next_header(sam_stat))
		return -1;

	return 0;
}