⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftape-write.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		TRACE(1, "wrong header signature found, aborting");		result = -EIO;	}	if (result >= 0) {		result = _write_segment(segment, buffer, 0);		if (result >= 0 && runner_status == idle) {			/*  Force flush for single segment instead of relying on			 *  flush in read_segment for multiple segments.			 */			result = start_writing(WRITE_SINGLE);			if (result >= 0 && ftape_state == writing) {				result = loop_until_writes_done();				prevent_flush();			}		}#ifdef VERIFY_HEADERS		if (result >= 0) {	/* read back and verify */			result = read_segment(segment, scratch_buffer, &status, 0);			/*  Should retry if soft error during read !			 *  TO BE IMPLEMENTED			 */			if (result >= 0) {				if (memcmp(buffer, scratch_buffer, sizeof(buffer)) == 0) {					result = 0;	/* verified */					TRACE(5, "verified");				} else {					result = -EIO;	/* verify failed */					TRACE(5, "verify failed");				}			}		}#endif	}	TRACE_EXIT;	return result;}int ftape_write_header_segments(byte * buffer){	TRACE_FUN(5, "ftape_write_header_segments");	int result = 0;	int retry = 0;	int header_1_ok = 0;	int header_2_ok = 0;	do {		if (!header_1_ok) {			result = update_header_segment(header_segment_1, buffer);			if (result < 0) {				continue;			}			header_1_ok = 1;		}		if (!header_2_ok) {			result = update_header_segment(header_segment_2, buffer);			if (result < 0) {				continue;			}			header_2_ok = 1;		}	} while (result < 0 && retry++ < 3);	if (result < 0) {		if (!header_1_ok) {			TRACE(1, "update of first header segment failed");		}		if (!header_2_ok) {			TRACE(1, "update of second header segment failed");		}		result = -EIO;	}	TRACE_EXIT;	return result;}int ftape_update_header_segments(byte * buffer, int update){	TRACE_FUN(5, "ftape_update_header_segments");	int result = 0;	int dummy;	int header_changed = 1;	if (ftape_state == writing) {		result = loop_until_writes_done();	}	if (read_only) {		result = 0;	/* exit and fake success */		TRACE(4, "Tape set read-only: no update");	} else if (result >= 0) {		result = ftape_abort_operation();		if (result >= 0) {			if (buffer == NULL) {				if (bad_sector_map_changed || failed_sector_log_changed) {					ftape_seek_to_bot();	/* prevents extra rewind */					buffer = deblock_buffer;					result = read_segment(used_header_segment, buffer, &dummy, 0);					if (result < 0) {						TRACE_EXIT;						return result;					}				}				header_changed = 0;			}			if (update) {				if (bad_sector_map_changed) {					store_bad_sector_map(buffer);					header_changed = 1;				}				if (failed_sector_log_changed) {					update_failed_sector_log(buffer);					header_changed = 1;				}			}			if (header_changed) {				ftape_seek_to_bot();	/* prevents extra rewind */				result = ftape_write_header_segments(buffer);			}		}	}	TRACE_EXIT;	return result;}int ftape_flush_buffers(void){	TRACE_FUN(5, "ftape_flush_buffers");	int result;	int pad_count;	int data_remaining;	static int active = 0;	if (active) {		TRACE(5, "nested call, abort");		TRACE_EXIT;		return 0;	}	active = 1;	TRACEi(5, "entered, ftape_state =", ftape_state);	if (ftape_state != writing && !need_flush) {		active = 0;		TRACE(5, "no need for flush");		TRACE_EXIT;		return 0;	}	data_remaining = buf_pos_wr;	buf_pos_wr = 0;		/* prevent further writes if this fails */	TRACE(5, "flushing write buffers");	if (last_write_failed) {		ftape_zap_write_buffers();		active = 0;		TRACE_EXIT;		return write_protected ? -EROFS : -EIO;	}	/*	 *    If there is any data not written to tape yet, append zero's	 *    up to the end of the sector. Then write the segment(s) to tape.	 */	if (data_remaining > 0) {		int written;		do {			TRACEi(4, "remaining in buffer:", data_remaining);			pad_count = sizeof(deblock_buffer) - data_remaining;			TRACEi(7, "flush, padding count:", pad_count);			memset(deblock_buffer + data_remaining, 0, pad_count);	/* pad buffer */			result = _write_segment(ftape_seg_pos, deblock_buffer, 1);			if (result < 0) {				if (result != -ENOSPC) {					last_write_failed = 1;				}				active = 0;				TRACE_EXIT;				return result;			}			written = result;			clear_eof_mark_if_set(ftape_seg_pos, written);			TRACEi(7, "flush, moved out buffer:", written);			if (written > 0) {				data_remaining -= written;				if (data_remaining > 0) {					/*  Need another segment for remaining data, move the remainder					 *  to the beginning of the buffer					 */					memmove(deblock_buffer, deblock_buffer + written, data_remaining);				}			}			++ftape_seg_pos;		} while (data_remaining > 0);		/*  Data written to last segment == data_remaining + written		 *  value is in range [1..29K].		 */		TRACEx2(4, "last write: %d, netto pad-count: %d",			data_remaining + written, -data_remaining);		if (-1024 < data_remaining && data_remaining <= 0) {			/*  Last sector of segment was used for data, so put eof mark			 *  in next segment and position at second file mark.			 */			if (ftape_weof(2, ftape_seg_pos, 1) >= 0) {				++ftape_seg_pos;	/* position between file marks */			}		} else {			/*  Put eof mark in previous segment after data and position			 *  at second file mark.			 */			ftape_weof(2, ftape_seg_pos - 1, 1 +				   ((SECTOR_SIZE - 1 + result + data_remaining) / SECTOR_SIZE));		}	} else {		TRACE(7, "deblock_buffer empty");		if (ftape_weof(2, ftape_seg_pos, 1) >= 0) {			++ftape_seg_pos;	/* position between file marks */		}		start_writing(WRITE_MULTI);	}	TRACE(7, "waiting");	result = loop_until_writes_done();	if (result < 0) {		TRACE(1, "flush buffers failed");	}	ftape_state = idle;	last_write_failed = 0;	need_flush = 0;	active = 0;	TRACE_EXIT;	return result;}int _ftape_write(const char *buff, int req_len){	TRACE_FUN(5, "_ftape_write");	int result = 0;	int cnt;	int written = 0;	if (write_protected) {		TRACE(1, "error: cartridge write protected");		last_write_failed = 1;		result = -EROFS;	} else if (ftape_offline || !formatted || no_tape) {		result = -EIO;	} else if (first_data_segment == -1) {		/*		 *    If we haven't read the header segment yet, do it now.		 *    This will verify the configuration, get the eof markers		 *    and the bad sector table.		 *    We'll use the deblock buffer for scratch.		 */		result = read_header_segment(deblock_buffer);		if (result >= 0 && ftape_seg_pos > ftape_last_segment.id) {			result = -ENOSPC;	/* full is full */		}	}	if (result < 0) {		TRACE_EXIT;		return result;	}	/*	 *    This part writes data blocks to tape until the	 *    requested amount is written.	 *    The data will go in a buffer until it's enough	 *    for a segment without bad sectors. Then we'll write	 *    that segment to tape.	 *    The bytes written will be removed from the buffer	 *    and the process is repeated until there is less	 *    than one segment to write left in the buffer.	 */	while (req_len > 0) {		int space_left = sizeof(deblock_buffer) - buf_pos_wr;		TRACEi(7, "remaining req_len:", req_len);		TRACEi(7, "          buf_pos:", buf_pos_wr);		cnt = (req_len < space_left) ? req_len : space_left;		if (cnt > 0) {			result = verify_area(VERIFY_READ, buff, cnt);			if (result) {				TRACE(1, "verify_area failed");				last_write_failed = 1;				TRACE_EXIT;				return result;			}			memcpy_fromfs(deblock_buffer + buf_pos_wr, buff, cnt);			buff += cnt;			req_len -= cnt;			buf_pos_wr += cnt;		}		TRACEi(7, "moved into blocking buffer:", cnt);		while (buf_pos_wr >= sizeof(deblock_buffer)) {			/*  If this is the last buffer to be written, let flush handle it.			 */			if (ftape_seg_pos >= ftape_last_segment.id) {				TRACEi(7, "remaining in blocking buffer:", buf_pos_wr);				TRACEi(7, "just written bytes:", written + cnt);				TRACE_EXIT;				return written + cnt;			}			/* Got one full buffer, write it to disk			 */			result = _write_segment(ftape_seg_pos, deblock_buffer, 0);			TRACEi(5, "_write_segment result =", result);			if (result < 0) {				if (result == -EAGAIN) {					TRACE(5, "retry...");					continue;	/* failed, retry same segment */				}				last_write_failed = 1;				TRACE_EXIT;				return result;			} else {				clear_eof_mark_if_set(ftape_seg_pos, result);			}			if (result > 0 && result < buf_pos_wr) {				/* Partial write: move remainder in lower part of buffer				 */				memmove(deblock_buffer, deblock_buffer + result, buf_pos_wr - result);			}			TRACEi(7, "moved out of blocking buffer:", result);			buf_pos_wr -= result;	/* remainder */			++ftape_seg_pos;			/* Allow us to escape from this loop with a signal !			 */			if (current->signal & _DONT_BLOCK) {				TRACE(2, "interrupted by signal");				last_write_failed = 1;				TRACE_EXIT;				return -EINTR;	/* is this the right return value ? */			}		}		written += cnt;	}	TRACEi(7, "remaining in blocking buffer:", buf_pos_wr);	TRACEi(7, "just written bytes:", written);	last_write_failed = 0;	if (!need_flush && written > 0) {		need_flush = 1;	}	TRACE_EXIT;	return written;		/* bytes written */}int ftape_fix(void){	TRACE_FUN(5, "ftape_fix");	int result = 0;	int dummy;	int status;	if (write_protected) {		result = -EROFS;	} else {		/*  This will copy header segment 2 to header segment 1		 *  Spares us a tape format operation if header 2 is still good.		 */		header_segment_1 = 0;		header_segment_2 = 1;		first_data_segment = 2;		result = read_segment(header_segment_2, scratch_buffer, &dummy, 0);		result = ftape_ready_wait(timeout.pause, &status);		result = ftape_write_header_segments(scratch_buffer);	}	TRACE_EXIT;	return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -