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

📄 zftape-compress.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
			if (seg_dist < 0) {				TRACE(ft_t_bug, "BUG: distance %d > 0, "				      "segment difference %d < 0",				      distance, seg_dist);				result = -EIO;				break;			}			new_seg = pos->seg_pos + seg_dist;			if (new_seg > volume->end_seg) {				new_seg = volume->end_seg;			}			if (old_seg == new_seg || /* loop */			    seg_dist <= ZFT_SLOW_SEEK_THRESHOLD ||			    fast_seek_trials >= ZFT_FAST_SEEK_MAX_TRIALS) {				TRACE(ft_t_noise, "starting slow seek:\n"				   KERN_INFO "fast seek failed too often: %s\n"				   KERN_INFO "near target position      : %s\n"				   KERN_INFO "looping between two segs  : %s",				      (fast_seek_trials >= 				       ZFT_FAST_SEEK_MAX_TRIALS)				      ? "yes" : "no",				      (seg_dist <= ZFT_SLOW_SEEK_THRESHOLD) 				      ? "yes" : "no",				      (old_seg == new_seg)				      ? "yes" : "no");				result = slow_seek_forward(dest, &cseg, 							   pos, volume, buf);				break;			}			old_seg = new_seg;			limit = volume->end_seg;			fast_seek_trials ++;			for (;;) {				result = search_valid_segment(new_seg, limit,							      volume->size,							      pos, &cseg,							      volume, buf);				if (result == 0 || result == -EINTR) {					break;				}				if (new_seg == volume->start_seg) {					result = -EIO; /* set errror 							* condition							*/					break;				}				limit    = new_seg;				new_seg -= ZFT_FAST_SEEK_BACKUP;				if (new_seg < volume->start_seg) {					new_seg = volume->start_seg;				}			}			if (result < 0) {				TRACE(ft_t_warn,				      "Couldn't find a readable segment");				break;			}		} else /* if (distance < 0) */ {			if (seg_dist > 0) {				TRACE(ft_t_bug, "BUG: distance %d < 0, "				      "segment difference %d >0",				      distance, seg_dist);				result = -EIO;				break;			}			new_seg = pos->seg_pos + seg_dist;			if (fast_seek_trials > 0 && seg_dist == 0) {				/* this avoids sticking to the same				 * segment all the time. On the other hand:				 * if we got here for the first time, and the				 * deblock_buffer still contains a valid				 * segment, then there is no need to skip to 				 * the previous segment if the desired position				 * is inside this segment.				 */				new_seg --;			}			if (new_seg < volume->start_seg) {				new_seg = volume->start_seg;			}			limit   = pos->seg_pos;			fast_seek_trials ++;			for (;;) {				result = search_valid_segment(new_seg, limit,							      pos->volume_pos,							      pos, &cseg,							      volume, buf);				if (result == 0 || result == -EINTR) {					break;				}				if (new_seg == volume->start_seg) {					result = -EIO; /* set errror 							* condition							*/					break;				}				limit    = new_seg;				new_seg -= ZFT_FAST_SEEK_BACKUP;				if (new_seg < volume->start_seg) {					new_seg = volume->start_seg;				}			}			if (result < 0) {				TRACE(ft_t_warn,				      "Couldn't find a readable segment");				break;			}		}		distance = dest - (pos->volume_pos >> 10);	}	TRACE_EXIT result;}/*  advance inside the given segment at most to_do bytes. *  of kilobytes moved */static int seek_in_segment(const unsigned int to_do,			   cmpr_info  *c_info,			   const char *src_buf, 			   const int seg_sz, 			   const int seg_pos,			   const zft_volinfo *volume){	int result = 0;	int blk_sz = volume->blk_sz >> 10;	int remaining = to_do;	TRACE_FUN(ft_t_flow);	if (c_info->offset == 0) {		/* new segment just read		 */		TRACE_CATCH(get_cseg(c_info, src_buf, seg_sz, volume),);		c_info->cmpr_pos += c_info->count;		DUMP_CMPR_INFO(ft_t_noise, "", c_info);	}	/* loop and uncompress until user buffer full or	 * deblock-buffer empty 	 */	TRACE(ft_t_noise, "compressed_sz: %d, compos : %d",	      c_info->cmpr_sz, c_info->cmpr_pos);	while (c_info->spans == 0 && remaining > 0) {		if (c_info->cmpr_pos  != 0) { /* cmpr buf is not empty */			result       += blk_sz;			remaining    -= blk_sz;			c_info->cmpr_pos = 0;		}		if (remaining > 0) {			get_next_cluster(c_info, src_buf, seg_sz, 					 volume->end_seg == seg_pos);			if (c_info->count != 0) {				c_info->cmpr_pos = c_info->count;				c_info->offset  += c_info->count;			} else {				break;			}		}		/*  Allow escape from this loop on signal!		 */		FT_SIGNAL_EXIT(_DONT_BLOCK);		DUMP_CMPR_INFO(ft_t_noise, "", c_info);		TRACE(ft_t_noise, "to_do: %d", remaining);	}	if (seg_sz - c_info->offset <= 18) {		c_info->offset = seg_sz;	}	TRACE(ft_t_noise, "\n"	      KERN_INFO "segment size   : %d\n"	      KERN_INFO "buf_pos_read   : %d\n"	      KERN_INFO "remaining      : %d",	      seg_sz, c_info->offset,	      seg_sz - c_info->offset);	TRACE_EXIT result;}                static int slow_seek_forward_until_error(const unsigned int distance,					 cmpr_info *c_info,					 zft_position *pos, 					 const zft_volinfo *volume,					 __u8 *buf){	unsigned int remaining = distance;	int seg_sz;	int seg_pos;	int result;	TRACE_FUN(ft_t_flow);		seg_pos = pos->seg_pos;	do {		TRACE_CATCH(seg_sz = zft_fetch_segment(seg_pos, buf, 						       FT_RD_AHEAD),);		/* now we have the contents of the actual segment in		 * the deblock buffer		 */		TRACE_CATCH(result = seek_in_segment(remaining, c_info, buf,						     seg_sz, seg_pos,volume),);		remaining        -= result;		pos->volume_pos  += result<<10;		pos->seg_pos      = seg_pos;		pos->seg_byte_pos = c_info->offset;		seg_pos ++;		if (seg_pos <= volume->end_seg && c_info->offset == seg_sz) {			pos->seg_pos ++;			pos->seg_byte_pos = 0;			c_info->offset = 0;		}		/*  Allow escape from this loop on signal!		 */		FT_SIGNAL_EXIT(_DONT_BLOCK);		TRACE(ft_t_noise, "\n"		      KERN_INFO "remaining:  %d\n"		      KERN_INFO "seg_pos:    %d\n"		      KERN_INFO "end_seg:    %d\n"		      KERN_INFO "result:     %d",		      remaining, seg_pos, volume->end_seg, result);  	} while (remaining > 0 && seg_pos <= volume->end_seg);	TRACE_EXIT 0;}/* return segment id of next segment containing valid data, -EIO otherwise */static int search_valid_segment(unsigned int segment,				const unsigned int end_seg,				const unsigned int max_foffs,				zft_position *pos,				cmpr_info *c_info,				const zft_volinfo *volume,				__u8 *buf){	cmpr_info tmp_info;	int seg_sz;	TRACE_FUN(ft_t_flow);		memset(&tmp_info, 0, sizeof(cmpr_info));	while (segment <= end_seg) {		FT_SIGNAL_EXIT(_DONT_BLOCK);		TRACE(ft_t_noise,		      "Searching readable segment between %d and %d",		      segment, end_seg);		seg_sz = zft_fetch_segment(segment, buf, FT_RD_AHEAD);		if ((seg_sz > 0) &&		    (get_cseg (&tmp_info, buf, seg_sz, volume) >= 0) &&		    (tmp_info.foffs != 0 || segment == volume->start_seg)) {			if ((tmp_info.foffs>>10) > max_foffs) {				TRACE_ABORT(-EIO, ft_t_noise, "\n"					    KERN_INFO "cseg.foff: %d\n"					    KERN_INFO "dest     : %d",					    (int)(tmp_info.foffs >> 10),					    max_foffs);			}			DUMP_CMPR_INFO(ft_t_noise, "", &tmp_info);			*c_info           = tmp_info;			pos->seg_pos      = segment;			pos->volume_pos   = c_info->foffs;			pos->seg_byte_pos = c_info->offset;			TRACE(ft_t_noise, "found segment at %d", segment);			TRACE_EXIT 0;		}		segment++;	}	TRACE_EXIT -EIO;}static int slow_seek_forward(unsigned int dest,			     cmpr_info *c_info,			     zft_position *pos,			     const zft_volinfo *volume,			     __u8 *buf){	unsigned int distance;	int result = 0;	TRACE_FUN(ft_t_flow);			distance = dest - (pos->volume_pos >> 10);	while ((distance > 0) &&	       (result = slow_seek_forward_until_error(distance,						       c_info,						       pos,						       volume,						       buf)) < 0) {		if (result == -EINTR) {			break;		}		TRACE(ft_t_noise, "seg_pos: %d", pos->seg_pos);		/* the failing segment is either pos->seg_pos or		 * pos->seg_pos + 1. There is no need to further try		 * that segment, because ftape_read_segment() already		 * has tried very much to read it. So we start with		 * following segment, which is pos->seg_pos + 1		 */		if(search_valid_segment(pos->seg_pos+1, volume->end_seg, dest,					pos, c_info,					volume, buf) < 0) {			TRACE(ft_t_noise, "search_valid_segment() failed");			result = -EIO;			break;		}		distance = dest - (pos->volume_pos >> 10);		result = 0;		TRACE(ft_t_noise, "segment: %d", pos->seg_pos);		/* found valid segment, retry the seek */	}	TRACE_EXIT result;}static int compute_seg_pos(const unsigned int dest,			   zft_position *pos,			   const zft_volinfo *volume){	int segment;	int distance = dest - (pos->volume_pos >> 10);	unsigned int raw_size;	unsigned int virt_size;	unsigned int factor;	TRACE_FUN(ft_t_flow);	if (distance >= 0) {		raw_size  = volume->end_seg - pos->seg_pos + 1;		virt_size = ((unsigned int)(volume->size>>10) 			     - (unsigned int)(pos->volume_pos>>10)			     + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);		virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;		if (virt_size == 0 || raw_size == 0) {			TRACE_EXIT 0;		}		if (raw_size >= (1<<25)) {			factor = raw_size/(virt_size>>7);		} else {			factor = (raw_size<<7)/virt_size;		}		segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);		segment = (segment * factor)>>7;	} else {		raw_size  = pos->seg_pos - volume->start_seg + 1;		virt_size = ((unsigned int)(pos->volume_pos>>10)			     + FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS - 1);		virt_size /= FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS;		if (virt_size == 0 || raw_size == 0) {			TRACE_EXIT 0;		}		if (raw_size >= (1<<25)) {			factor = raw_size/(virt_size>>7);		} else {			factor = (raw_size<<7)/virt_size;		}		segment = distance/(FT_SECTORS_PER_SEGMENT-FT_ECC_SECTORS);	}	TRACE(ft_t_noise, "factor: %d/%d", factor, 1<<7);	TRACE_EXIT segment;}static struct zft_cmpr_ops cmpr_ops = {	zftc_write,	zftc_read,	zftc_seek,	zftc_lock,	zftc_reset,	zftc_cleanup};int zft_compressor_init(void){	TRACE_FUN(ft_t_flow);	#ifdef MODULE	printk(KERN_INFO "zftape compressor v1.00a 970514 for " FTAPE_VERSION "\n");        if (TRACE_LEVEL >= ft_t_info) {		printk(KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");        }#else /* !MODULE */	/* print a short no-nonsense boot message */	printk(KERN_INFO "zftape compressor v1.00a 970514\n");	printk(KERN_INFO "For use with " FTAPE_VERSION "\n");#endif /* MODULE */	TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);	TRACE(ft_t_info, "installing compressor for zftape ...");	TRACE_CATCH(zft_cmpr_register(&cmpr_ops),);	TRACE_EXIT 0;}#ifdef MODULEMODULE_AUTHOR(	"(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de");MODULE_DESCRIPTION("Compression routines for zftape. Uses the lzrw3 algorithm by Ross Williams");MODULE_LICENSE("GPL");/* Called by modules package when installing the driver */int init_module(void){	return zft_compressor_init();}#endif /* MODULE */

⌨️ 快捷键说明

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