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

📄 zftape-vtbl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	} #endif	/* the end of the vtbl is indicated by an invalid signature 	 */	while (vtbl_signature_valid(&entry[VTBL_SIG]) &&	       (entry - buffer) < FT_SEGMENT_SIZE) {		zft_new_vtbl_entry();		if (ft_format_code == fmt_big) {			/* SCSI like vtbl, stores only the number of			 * segments used 			 */			unsigned int num_segments= GET4(entry, VTBL_SCSI_SEGS);			zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;			zft_last_vtbl->end_seg = 				zft_last_vtbl->start_seg + num_segments - 1;		} else {			/* `normal', QIC-80 like vtbl 			 */			zft_last_vtbl->start_seg = GET2(entry, VTBL_START);			zft_last_vtbl->end_seg   = GET2(entry, VTBL_END);		}		zft_eom_vtbl->start_seg  = zft_last_vtbl->end_seg + 1;		/* check if we created this volume and get the		 * blk_sz 		 */		zft_last_vtbl->zft_volume = check_volume(entry, zft_last_vtbl);		if (zft_last_vtbl->zft_volume == 0) {			extract_alien_volume(entry, zft_last_vtbl);		} else {			extract_zft_volume(entry, zft_last_vtbl);		}		DUMP_VOLINFO(ft_t_noise, &entry[VTBL_DESC], zft_last_vtbl);		entry +=VTBL_SIZE;	}#if 0/* *  undefine to test end of tape handling */	zft_new_vtbl_entry();	zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;	zft_last_vtbl->end_seg   = ft_last_data_segment - 10;	zft_last_vtbl->blk_sz          = zft_blk_sz;	zft_last_vtbl->zft_volume      = 1;	zft_last_vtbl->qic113          = zft_qic113;	zft_last_vtbl->size = (zft_calc_tape_pos(zft_last_vtbl->end_seg+1)			       - zft_calc_tape_pos(zft_last_vtbl->start_seg));#endif	TRACE_EXIT 0;}/* this functions translates the failed_sector_log, misused as * EOF-marker list, into a virtual volume table. The table mustn't be * written to tape, because this would occupy the first data segment, * which should be the volume table, but is actually the first segment * that is filled with data (when using standard ftape).  We assume, * that we get a non-empty failed_sector_log. */int zft_fake_volume_headers (eof_mark_union *eof_map, int num_failed_sectors){	unsigned int segment, sector;	int have_eom = 0;	int vol_no;	TRACE_FUN(ft_t_flow);	if ((num_failed_sectors >= 2) &&	    (GET2(&eof_map[num_failed_sectors - 1].mark.segment, 0) 	     == 	     GET2(&eof_map[num_failed_sectors - 2].mark.segment, 0) + 1) &&	    (GET2(&eof_map[num_failed_sectors - 1].mark.date, 0) == 1)) {		/* this should be eom. We keep the remainder of the		 * tape as another volume.		 */		have_eom = 1;	}	zft_init_vtbl();	zft_eom_vtbl->start_seg = ft_first_data_segment;	for(vol_no = 0; vol_no < num_failed_sectors - have_eom; vol_no ++) {		zft_new_vtbl_entry();		segment = GET2(&eof_map[vol_no].mark.segment, 0);		sector  = GET2(&eof_map[vol_no].mark.date, 0);		zft_last_vtbl->start_seg  = zft_eom_vtbl->start_seg;		zft_last_vtbl->end_seg    = segment;		zft_eom_vtbl->start_seg  = segment + 1;		zft_last_vtbl->blk_sz     = 1;		zft_last_vtbl->size       = 			(zft_calc_tape_pos(zft_last_vtbl->end_seg)			 - zft_calc_tape_pos(zft_last_vtbl->start_seg)			 + (sector-1) * FT_SECTOR_SIZE);		TRACE(ft_t_noise, 		      "failed sector log: segment: %d, sector: %d", 		      segment, sector);		DUMP_VOLINFO(ft_t_noise, "Faked volume", zft_last_vtbl);	}	if (!have_eom) {		zft_new_vtbl_entry();		zft_last_vtbl->start_seg = zft_eom_vtbl->start_seg;		zft_last_vtbl->end_seg   = ft_last_data_segment;		zft_eom_vtbl->start_seg  = ft_last_data_segment + 1;		zft_last_vtbl->size      = zft_capacity;		zft_last_vtbl->size     -= zft_calc_tape_pos(zft_last_vtbl->start_seg);		zft_last_vtbl->blk_sz    = 1;		DUMP_VOLINFO(ft_t_noise, "Faked volume",zft_last_vtbl);	}	TRACE_EXIT 0;}/* update the internal volume table * * if before start of last volume: erase all following volumes if * inside a volume: set end of volume to infinity * * this function is intended to be called every time _ftape_write() is * called * * return: 0 if no new volume was created, 1 if a new volume was * created * * NOTE: we don't need to check for zft_mode as ftape_write() does * that already. This function gets never called without accessing * zftape via the *qft* devices  */int zft_open_volume(zft_position *pos, int blk_sz, int use_compression){ 	TRACE_FUN(ft_t_flow);		if (!zft_qic_mode) {		TRACE_EXIT 0;	}	if (zft_tape_at_lbot(pos)) {		zft_init_vtbl();		if(zft_old_ftape) {			/* clear old ftape's eof marks */			zft_clear_ftape_file_marks();			zft_old_ftape = 0; /* no longer old ftape */		}		zft_reset_position(pos);	}	if (pos->seg_pos != zft_last_vtbl->end_seg + 1) {		TRACE_ABORT(-EIO, ft_t_bug, 		      "BUG: seg_pos: %d, zft_last_vtbl->end_seg: %d", 		      pos->seg_pos, zft_last_vtbl->end_seg);	}                            	TRACE(ft_t_noise, "create new volume");	if (zft_eom_vtbl->count >= ZFT_MAX_VOLUMES) {		TRACE_ABORT(-ENOSPC, ft_t_err,			    "Error: maxmimal number of volumes exhausted "			    "(maxmimum is %d)", ZFT_MAX_VOLUMES);	}	zft_new_vtbl_entry();	pos->volume_pos = pos->seg_byte_pos = 0;	zft_last_vtbl->start_seg       = pos->seg_pos;	zft_last_vtbl->end_seg         = ft_last_data_segment; /* infinity */	zft_last_vtbl->blk_sz          = blk_sz;	zft_last_vtbl->size            = zft_capacity;	zft_last_vtbl->zft_volume      = 1;	zft_last_vtbl->use_compression = use_compression;	zft_last_vtbl->qic113          = zft_qic113;	zft_last_vtbl->new_volume      = 1;	zft_last_vtbl->open            = 1;	zft_volume_table_changed = 1;	zft_eom_vtbl->start_seg  = ft_last_data_segment + 1;	TRACE_EXIT 0;}/*  perform mtfsf, mtbsf, not allowed without zft_qic_mode */int zft_skip_volumes(int count, zft_position *pos){ 	const zft_volinfo *vtbl;	TRACE_FUN(ft_t_flow);		TRACE(ft_t_noise, "count: %d", count);		vtbl= zft_find_volume(pos->seg_pos);	while (count > 0 && vtbl != zft_eom_vtbl) {		vtbl = list_entry(vtbl->node.next, zft_volinfo, node);		count --;	}	while (count < 0 && vtbl != zft_first_vtbl) {		vtbl = list_entry(vtbl->node.prev, zft_volinfo, node);		count ++;	}	pos->seg_pos        = vtbl->start_seg;	pos->seg_byte_pos   = 0;	pos->volume_pos     = 0;	pos->tape_pos       = zft_calc_tape_pos(pos->seg_pos);	zft_just_before_eof = vtbl->size == 0;	if (zft_cmpr_ops) {		(*zft_cmpr_ops->reset)();	}	zft_deblock_segment = -1; /* no need to keep cache */	TRACE(ft_t_noise, "repositioning to:\n"	      KERN_INFO "zft_seg_pos        : %d\n"	      KERN_INFO "zft_seg_byte_pos   : %d\n"	      KERN_INFO "zft_tape_pos       : " LL_X "\n"	      KERN_INFO "zft_volume_pos     : " LL_X "\n"	      KERN_INFO "file number        : %d",	      pos->seg_pos, pos->seg_byte_pos, 	      LL(pos->tape_pos), LL(pos->volume_pos), vtbl->count);	zft_resid = count < 0 ? -count : count;	TRACE_EXIT zft_resid ? -EINVAL : 0;}/* the following simply returns the raw data position of the EOM * marker, MTIOCSIZE ioctl  */__s64 zft_get_eom_pos(void){	if (zft_qic_mode) {		return zft_calc_tape_pos(zft_eom_vtbl->start_seg);	} else {		/* there is only one volume in raw mode */		return zft_capacity;	}}/* skip to eom, used for MTEOM */void zft_skip_to_eom(zft_position *pos){	TRACE_FUN(ft_t_flow);	pos->seg_pos      = zft_eom_vtbl->start_seg;	pos->seg_byte_pos = 		pos->volume_pos     = 		zft_just_before_eof = 0;	pos->tape_pos = zft_calc_tape_pos(pos->seg_pos);	TRACE(ft_t_noise, "ftape positioned to segment %d, data pos " LL_X, 	      pos->seg_pos, LL(pos->tape_pos));	TRACE_EXIT;}/*  write an EOF-marker by setting zft_last_vtbl->end_seg to seg_pos. *  NOTE: this function assumes that zft_last_vtbl points to a valid *  vtbl entry * *  NOTE: this routine always positions before the EOF marker */int zft_close_volume(zft_position *pos){	TRACE_FUN(ft_t_any);	if (zft_vtbl_empty || !zft_last_vtbl->open) { /* should not happen */		TRACE(ft_t_noise, "There are no volumes to finish");		TRACE_EXIT -EIO;	}	if (pos->seg_byte_pos == 0 && 	    pos->seg_pos != zft_last_vtbl->start_seg) {		pos->seg_pos --;		pos->seg_byte_pos      = zft_get_seg_sz(pos->seg_pos);	}	zft_last_vtbl->end_seg   = pos->seg_pos;	zft_last_vtbl->size      = pos->volume_pos;	zft_volume_table_changed = 1;	zft_just_before_eof      = 1;	zft_eom_vtbl->start_seg  = zft_last_vtbl->end_seg + 1;	zft_last_vtbl->open      = 0; /* closed */	TRACE_EXIT 0;}/* write count file-marks at current position.  * *  The tape is positioned after the eof-marker, that is at byte 0 of *  the segment following the eof-marker * *  this function is only allowed in zft_qic_mode * *  Only allowed when tape is at BOT or EOD. */int zft_weof(unsigned int count, zft_position *pos){		TRACE_FUN(ft_t_flow);	if (!count) { /* write zero EOF marks should be a real no-op */		TRACE_EXIT 0;	}	zft_volume_table_changed = 1;	if (zft_tape_at_lbot(pos)) {		zft_init_vtbl();		if(zft_old_ftape) {			/* clear old ftape's eof marks */			zft_clear_ftape_file_marks();			zft_old_ftape = 0;    /* no longer old ftape */		}	}	if (zft_last_vtbl->open) {		zft_close_volume(pos);		zft_move_past_eof(pos);		count --;	}	/* now it's easy, just append eof-marks, that is empty	 * volumes, to the end of the already recorded media.	 */	while (count > 0 && 	       pos->seg_pos <= ft_last_data_segment && 	       zft_eom_vtbl->count < ZFT_MAX_VOLUMES) {		TRACE(ft_t_noise,		      "Writing zero sized file at segment %d", pos->seg_pos);		zft_new_vtbl_entry();		zft_last_vtbl->start_seg       = pos->seg_pos;		zft_last_vtbl->end_seg         = pos->seg_pos;		zft_last_vtbl->size            = 0;		zft_last_vtbl->blk_sz          = zft_blk_sz;		zft_last_vtbl->zft_volume      = 1;		zft_last_vtbl->use_compression = 0;		pos->tape_pos += zft_get_seg_sz(pos->seg_pos);		zft_eom_vtbl->start_seg = ++ pos->seg_pos;		count --;	} 	if (count > 0) {		/*  there are two possibilities: end of tape, or the		 *  maximum number of files is exhausted.		 */		zft_resid = count;		TRACE(ft_t_noise,"Number of marks NOT written: %d", zft_resid);		if (zft_eom_vtbl->count == ZFT_MAX_VOLUMES) {			TRACE_ABORT(-EINVAL, ft_t_warn,				    "maximum allowed number of files "				    "exhausted: %d", ZFT_MAX_VOLUMES);		} else {			TRACE_ABORT(-ENOSPC,				    ft_t_noise, "reached end of tape");		}	}	TRACE_EXIT 0;}const zft_volinfo *zft_find_volume(unsigned int seg_pos){	TRACE_FUN(ft_t_flow);		TRACE(ft_t_any, "called with seg_pos %d",seg_pos);	if (!zft_qic_mode) {		if (seg_pos > ft_last_data_segment) {			TRACE_EXIT &eot_vtbl;		}		tape_vtbl.blk_sz =  zft_blk_sz;		TRACE_EXIT &tape_vtbl;	}	if (seg_pos < zft_first_vtbl->start_seg) {		TRACE_EXIT (cur_vtbl = zft_first_vtbl);	}	while (seg_pos > cur_vtbl->end_seg) {		cur_vtbl = list_entry(cur_vtbl->node.next, zft_volinfo, node);		TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg);	}	while (seg_pos < cur_vtbl->start_seg) {		cur_vtbl = list_entry(cur_vtbl->node.prev, zft_volinfo, node);		TRACE(ft_t_noise, "%d - %d", cur_vtbl->start_seg, cur_vtbl->end_seg);	}	if (seg_pos > cur_vtbl->end_seg || seg_pos < cur_vtbl->start_seg) {		TRACE(ft_t_bug, "This cannot happen");	}	DUMP_VOLINFO(ft_t_noise, "", cur_vtbl);	TRACE_EXIT cur_vtbl;}/* this function really assumes that we are just before eof */void zft_move_past_eof(zft_position *pos){ 	TRACE_FUN(ft_t_flow);	TRACE(ft_t_noise, "old seg. pos: %d", pos->seg_pos);	pos->tape_pos += zft_get_seg_sz(pos->seg_pos++) - pos->seg_byte_pos;	pos->seg_byte_pos = 0;	pos->volume_pos   = 0;	if (zft_cmpr_ops) {		(*zft_cmpr_ops->reset)();	}	zft_just_before_eof =  0;	zft_deblock_segment = -1; /* no need to cache it anymore */	TRACE(ft_t_noise, "new seg. pos: %d", pos->seg_pos);	TRACE_EXIT;}

⌨️ 快捷键说明

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