2 * Copyright (C) 1994-1997 Claus-Justus Heine
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2, or (at
7 your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
20 * This file implements a "generic" interface between the *
21 * zftape-driver and a compression-algorithm. The *
22 * compression-algorithm currently used is a LZ77. I use the *
23 * implementation lzrw3 by Ross N. Williams (Renaissance *
24 * Software). The compression program itself is in the file
25 * lzrw3.c * and lzrw3.h. To adopt another compression algorithm
26 * the functions * zft_compress() and zft_uncompress() must be
27 * changed * appropriately. See below.
30 #include <linux/errno.h>
32 #include <linux/module.h>
34 #include <linux/zftape.h>
36 #include <asm/uaccess.h>
38 #include "../zftape/zftape-init.h"
39 #include "../zftape/zftape-eof.h"
40 #include "../zftape/zftape-ctl.h"
41 #include "../zftape/zftape-write.h"
42 #include "../zftape/zftape-read.h"
43 #include "../zftape/zftape-rw.h"
44 #include "../compressor/zftape-compress.h"
45 #include "../zftape/zftape-vtbl.h"
46 #include "../compressor/lzrw3.h"
52 /* I handle the allocation of this buffer as a special case, because
53 * it's size varies depending on the tape length inserted.
58 static void *zftc_wrk_mem
= NULL
;
59 static __u8
*zftc_buf
= NULL
;
60 static void *zftc_scratch_buf
= NULL
;
62 /* compression statistics
64 static unsigned int zftc_wr_uncompressed
= 0;
65 static unsigned int zftc_wr_compressed
= 0;
66 static unsigned int zftc_rd_uncompressed
= 0;
67 static unsigned int zftc_rd_compressed
= 0;
70 static int zftc_write(int *write_cnt
,
71 __u8
*dst_buf
, const int seg_sz
,
72 const __u8 __user
*src_buf
, const int req_len
,
73 const zft_position
*pos
, const zft_volinfo
*volume
);
74 static int zftc_read(int *read_cnt
,
75 __u8 __user
*dst_buf
, const int to_do
,
76 const __u8
*src_buf
, const int seg_sz
,
77 const zft_position
*pos
, const zft_volinfo
*volume
);
78 static int zftc_seek(unsigned int new_block_pos
,
79 zft_position
*pos
, const zft_volinfo
*volume
,
81 static void zftc_lock (void);
82 static void zftc_reset (void);
83 static void zftc_cleanup(void);
84 static void zftc_stats (void);
86 /* compressed segment. This conforms to QIC-80-MC, Revision K.
88 * Rev. K applies to tapes with `fixed length format' which is
89 * indicated by format code 2,3 and 5. See below for format code 4 and 6
91 * 2 bytes: offset of compression segment structure
92 * 29k > offset >= 29k-18: data from previous segment ens in this
93 * segment and no compressed block starts
95 * offset == 0: data from previous segment occupies entire
96 * segment and continues in next segment
97 * n bytes: remainder from previous segment
100 * 4 bytes: 4 bytes: files set byte offset
101 * Post Rev. K and QIC-3020/3020:
102 * 8 bytes: 8 bytes: files set byte offset
103 * 2 bytes: byte count N (amount of data following)
104 * bit 15 is set if data is compressed, bit 15 is not
105 * set if data is uncompressed
106 * N bytes: data (as much as specified in the byte count)
107 * 2 bytes: byte count N_1 of next cluster
108 * N_1 bytes: data of next cluset
109 * 2 bytes: byte count N_2 of next cluster
112 * Note that the `N' byte count accounts only for the bytes that in the
113 * current segment if the cluster spans to the next segment.
118 int cmpr_pos
; /* actual position in compression buffer */
119 int cmpr_sz
; /* what is left in the compression buffer
120 * when copying the compressed data to the
123 unsigned int first_block
; /* location of header information in
126 unsigned int count
; /* amount of data of current block
127 * contained in current segment
129 unsigned int offset
; /* offset in current segment */
130 unsigned int spans
:1; /* might continue in next segment */
131 unsigned int uncmpr
; /* 0x8000 if this block contains
134 __s64 foffs
; /* file set byte offset, same as in
135 * compression map segment
139 static cmpr_info cseg
; /* static data. Must be kept uptodate and shared by
140 * read, write and seek functions
143 #define DUMP_CMPR_INFO(level, msg, info) \
144 TRACE(level, msg "\n" \
145 KERN_INFO "cmpr_pos : %d\n" \
146 KERN_INFO "cmpr_sz : %d\n" \
147 KERN_INFO "first_block: %d\n" \
148 KERN_INFO "count : %d\n" \
149 KERN_INFO "offset : %d\n" \
150 KERN_INFO "spans : %d\n" \
151 KERN_INFO "uncmpr : 0x%04x\n" \
152 KERN_INFO "foffs : " LL_X, \
153 (info)->cmpr_pos, (info)->cmpr_sz, (info)->first_block, \
154 (info)->count, (info)->offset, (info)->spans == 1, \
155 (info)->uncmpr, LL((info)->foffs))
157 /* dispatch compression segment info, return error code
159 * afterwards, cseg->offset points to start of data of the NEXT
160 * compressed block, and cseg->count contains the amount of data
161 * left in the actual compressed block. cseg->spans is set to 1 if
162 * the block is continued in the following segment. Otherwise it is
165 static int get_cseg (cmpr_info
*cinfo
, const __u8
*buff
,
166 const unsigned int seg_sz
,
167 const zft_volinfo
*volume
)
169 TRACE_FUN(ft_t_flow
);
171 cinfo
->first_block
= GET2(buff
, 0);
172 if (cinfo
->first_block
== 0) { /* data spans to next segment */
173 cinfo
->count
= seg_sz
- sizeof(__u16
);
174 cinfo
->offset
= seg_sz
;
176 } else { /* cluster definetely ends in this segment */
177 if (cinfo
->first_block
> seg_sz
) {
179 TRACE_ABORT(-EIO
, ft_t_err
, "corrupted data:\n"
180 KERN_INFO
"segment size: %d\n"
181 KERN_INFO
"first block : %d",
182 seg_sz
, cinfo
->first_block
);
184 cinfo
->count
= cinfo
->first_block
- sizeof(__u16
);
185 cinfo
->offset
= cinfo
->first_block
;
188 /* now get the offset the first block should have in the
189 * uncompressed data stream.
191 * For this magic `18' refer to CRF-3 standard or QIC-80MC,
194 if ((seg_sz
- cinfo
->offset
) > 18) {
195 if (volume
->qic113
) { /* > revision K */
196 TRACE(ft_t_data_flow
, "New QIC-113 compliance");
197 cinfo
->foffs
= GET8(buff
, cinfo
->offset
);
198 cinfo
->offset
+= sizeof(__s64
);
200 TRACE(/* ft_t_data_flow */ ft_t_noise
, "pre QIC-113 version");
201 cinfo
->foffs
= (__s64
)GET4(buff
, cinfo
->offset
);
202 cinfo
->offset
+= sizeof(__u32
);
205 if (cinfo
->foffs
> volume
->size
) {
206 TRACE_ABORT(-EIO
, ft_t_err
, "Inconsistency:\n"
207 KERN_INFO
"offset in current volume: %d\n"
208 KERN_INFO
"size of current volume : %d",
209 (int)(cinfo
->foffs
>>10), (int)(volume
->size
>>10));
211 if (cinfo
->cmpr_pos
+ cinfo
->count
> volume
->blk_sz
) {
212 TRACE_ABORT(-EIO
, ft_t_err
, "Inconsistency:\n"
213 KERN_INFO
"block size : %d\n"
214 KERN_INFO
"data record: %d",
215 volume
->blk_sz
, cinfo
->cmpr_pos
+ cinfo
->count
);
217 DUMP_CMPR_INFO(ft_t_noise
/* ft_t_any */, "", cinfo
);
221 /* This one is called, when a new cluster starts in same segment.
223 * Note: if this is the first cluster in the current segment, we must
224 * not check whether there are more than 18 bytes available because
225 * this have already been done in get_cseg() and there may be less
226 * than 18 bytes available due to header information.
229 static void get_next_cluster(cmpr_info
*cluster
, const __u8
*buff
,
230 const int seg_sz
, const int finish
)
232 TRACE_FUN(ft_t_flow
);
234 if (seg_sz
- cluster
->offset
> 18 || cluster
->foffs
!= 0) {
235 cluster
->count
= GET2(buff
, cluster
->offset
);
236 cluster
->uncmpr
= cluster
->count
& 0x8000;
237 cluster
->count
-= cluster
->uncmpr
;
238 cluster
->offset
+= sizeof(__u16
);
240 if ((cluster
->offset
+ cluster
->count
) < seg_sz
) {
242 } else if (cluster
->offset
+ cluster
->count
== seg_sz
) {
243 cluster
->spans
= !finish
;
245 /* either an error or a volume written by an
246 * old version. If this is a data error, then we'll
249 TRACE(ft_t_data_flow
, "Either error or old volume");
251 cluster
->count
= seg_sz
- cluster
->offset
;
258 DUMP_CMPR_INFO(ft_t_noise
/* ft_t_any */ , "", cluster
);
262 static void zftc_lock(void)
266 /* this function is needed for zftape_reset_position in zftape-io.c
268 static void zftc_reset(void)
270 TRACE_FUN(ft_t_flow
);
272 memset((void *)&cseg
, '\0', sizeof(cseg
));
277 static int cmpr_mem_initialized
= 0;
278 static unsigned int alloc_blksz
= 0;
280 static int zft_allocate_cmpr_mem(unsigned int blksz
)
282 TRACE_FUN(ft_t_flow
);
284 if (cmpr_mem_initialized
&& blksz
== alloc_blksz
) {
287 TRACE_CATCH(zft_vmalloc_once(&zftc_wrk_mem
, CMPR_WRK_MEM_SIZE
),
289 TRACE_CATCH(zft_vmalloc_always(&zftc_buf
, blksz
+ CMPR_OVERRUN
),
292 TRACE_CATCH(zft_vmalloc_always(&zftc_scratch_buf
, blksz
+CMPR_OVERRUN
),
294 cmpr_mem_initialized
= 1;
298 static void zftc_cleanup(void)
300 TRACE_FUN(ft_t_flow
);
302 zft_vfree(&zftc_wrk_mem
, CMPR_WRK_MEM_SIZE
);
303 zft_vfree(&zftc_buf
, alloc_blksz
+ CMPR_OVERRUN
);
304 zft_vfree(&zftc_scratch_buf
, alloc_blksz
+ CMPR_OVERRUN
);
305 cmpr_mem_initialized
= alloc_blksz
= 0;
309 /*****************************************************************************
311 * The following two functions "ftape_compress()" and *
312 * "ftape_uncompress()" are the interface to the actual compression *
313 * algorithm (i.e. they are calling the "compress()" function from *
314 * the lzrw3 package for now). These routines could quite easily be *
315 * changed to adopt another compression algorithm instead of lzrw3, *
316 * which currently is used. *
318 *****************************************************************************/
320 /* called by zft_compress_write() to perform the compression. Must
321 * return the size of the compressed data.
323 * NOTE: The size of the compressed data should not exceed the size of
324 * the uncompressed data. Most compression algorithms have means
325 * to store data unchanged if the "compressed" data amount would
326 * exceed the original one. Mostly this is done by storing some
327 * flag-bytes in front of the compressed data to indicate if it
328 * is compressed or not. Thus the worst compression result
329 * length is the original length plus those flag-bytes.
331 * We don't want that, as the QIC-80 standard provides a means
332 * of marking uncompressed blocks by simply setting bit 15 of
333 * the compressed block's length. Thus a compessed block can
334 * have at most a length of 2^15-1 bytes. The QIC-80 standard
335 * restricts the block-length even further, allowing only 29k -
338 * Currently, the maximum blocksize used by zftape is 28k.
340 * In short: don't exceed the length of the input-package, set
341 * bit 15 of the compressed size to 1 if you have copied data
342 * instead of compressing it.
344 static int zft_compress(__u8
*in_buffer
, unsigned int in_sz
, __u8
*out_buffer
)
347 TRACE_FUN(ft_t_flow
);
350 lzrw3_compress(COMPRESS_ACTION_COMPRESS
, zftc_wrk_mem
,
351 in_buffer
, in_sz
, out_buffer
, &compressed_sz
);
352 if (TRACE_LEVEL
>= ft_t_info
) {
353 /* the compiler will optimize this away when
354 * compiled with NO_TRACE_AT_ALL option
356 TRACE(ft_t_data_flow
, "\n"
357 KERN_INFO
"before compression: %d bytes\n"
358 KERN_INFO
"after compresison : %d bytes",
360 (int)(compressed_sz
< 0
361 ? -compressed_sz
: compressed_sz
));
362 /* for statistical purposes
364 zftc_wr_compressed
+= (compressed_sz
< 0
365 ? -compressed_sz
: compressed_sz
);
366 zftc_wr_uncompressed
+= in_sz
;
368 TRACE_EXIT (int)compressed_sz
;
371 /* called by zft_compress_read() to decompress the data. Must
372 * return the size of the decompressed data for sanity checks
373 * (compared with zft_blk_sz)
375 * NOTE: Read the note for zft_compress() above! If bit 15 of the
376 * parameter in_sz is set, then the data in in_buffer isn't
377 * compressed, which must be handled by the un-compression
378 * algorithm. (I changed lzrw3 to handle this.)
380 * The parameter max_out_sz is needed to prevent buffer overruns when
381 * uncompressing corrupt data.
383 static unsigned int zft_uncompress(__u8
*in_buffer
,
386 unsigned int max_out_sz
)
388 TRACE_FUN(ft_t_flow
);
390 lzrw3_compress(COMPRESS_ACTION_DECOMPRESS
, zftc_wrk_mem
,
391 in_buffer
, (__s32
)in_sz
,
392 out_buffer
, (__u32
*)&max_out_sz
);
394 if (TRACE_LEVEL
>= ft_t_info
) {
395 TRACE(ft_t_data_flow
, "\n"
396 KERN_INFO
"before decompression: %d bytes\n"
397 KERN_INFO
"after decompression : %d bytes",
398 in_sz
< 0 ? -in_sz
: in_sz
,(int)max_out_sz
);
399 /* for statistical purposes
401 zftc_rd_compressed
+= in_sz
< 0 ? -in_sz
: in_sz
;
402 zftc_rd_uncompressed
+= max_out_sz
;
404 TRACE_EXIT (unsigned int)max_out_sz
;
407 /* print some statistics about the efficiency of the compression to
410 static void zftc_stats(void)
412 TRACE_FUN(ft_t_flow
);
414 if (TRACE_LEVEL
< ft_t_info
) {
417 if (zftc_wr_uncompressed
!= 0) {
418 if (zftc_wr_compressed
> (1<<14)) {
419 TRACE(ft_t_info
, "compression statistics (writing):\n"
420 KERN_INFO
" compr./uncmpr. : %3d %%",
421 (((zftc_wr_compressed
>>10) * 100)
422 / (zftc_wr_uncompressed
>>10)));
424 TRACE(ft_t_info
, "compression statistics (writing):\n"
425 KERN_INFO
" compr./uncmpr. : %3d %%",
426 ((zftc_wr_compressed
* 100)
427 / zftc_wr_uncompressed
));
430 if (zftc_rd_uncompressed
!= 0) {
431 if (zftc_rd_compressed
> (1<<14)) {
432 TRACE(ft_t_info
, "compression statistics (reading):\n"
433 KERN_INFO
" compr./uncmpr. : %3d %%",
434 (((zftc_rd_compressed
>>10) * 100)
435 / (zftc_rd_uncompressed
>>10)));
437 TRACE(ft_t_info
, "compression statistics (reading):\n"
438 KERN_INFO
" compr./uncmpr. : %3d %%",
439 ((zftc_rd_compressed
* 100)
440 / zftc_rd_uncompressed
));
443 /* only print it once: */
444 zftc_wr_uncompressed
=
446 zftc_rd_uncompressed
=
447 zftc_rd_compressed
= 0;
451 /* start new compressed block
453 static int start_new_cseg(cmpr_info
*cluster
,
455 const zft_position
*pos
,
456 const unsigned int blk_sz
,
458 const int this_segs_sz
,
464 TRACE_FUN(ft_t_flow
);
466 size_left
= this_segs_sz
- sizeof(__u16
) - cluster
->cmpr_sz
;
467 TRACE(ft_t_data_flow
,"\n"
468 KERN_INFO
"segment size : %d\n"
469 KERN_INFO
"compressed_sz: %d\n"
470 KERN_INFO
"size_left : %d",
471 this_segs_sz
, cluster
->cmpr_sz
, size_left
);
472 if (size_left
> 18) { /* start a new cluseter */
473 cp_cnt
= cluster
->cmpr_sz
;
474 cluster
->cmpr_sz
= 0;
475 buf_pos
= cp_cnt
+ sizeof(__u16
);
476 PUT2(dst_buf
, 0, buf_pos
);
479 __s64 foffs
= pos
->volume_pos
;
480 if (cp_cnt
) foffs
+= (__s64
)blk_sz
;
482 TRACE(ft_t_data_flow
, "new style QIC-113 header");
483 PUT8(dst_buf
, buf_pos
, foffs
);
484 buf_pos
+= sizeof(__s64
);
486 __u32 foffs
= (__u32
)pos
->volume_pos
;
487 if (cp_cnt
) foffs
+= (__u32
)blk_sz
;
489 TRACE(ft_t_data_flow
, "old style QIC-80MC header");
490 PUT4(dst_buf
, buf_pos
, foffs
);
491 buf_pos
+= sizeof(__u32
);
493 } else if (size_left
>= 0) {
494 cp_cnt
= cluster
->cmpr_sz
;
495 cluster
->cmpr_sz
= 0;
496 buf_pos
= cp_cnt
+ sizeof(__u16
);
497 PUT2(dst_buf
, 0, buf_pos
);
498 /* zero unused part of segment. */
499 memset(dst_buf
+ buf_pos
, '\0', size_left
);
500 buf_pos
= this_segs_sz
;
501 } else { /* need entire segment and more space */
503 cp_cnt
= this_segs_sz
- sizeof(__u16
);
504 cluster
->cmpr_sz
-= cp_cnt
;
505 buf_pos
= this_segs_sz
;
507 memcpy(dst_buf
+ sizeof(__u16
), src_buf
+ cluster
->cmpr_pos
, cp_cnt
);
508 cluster
->cmpr_pos
+= cp_cnt
;
512 /* return-value: the number of bytes removed from the user-buffer
513 * `src_buf' or error code
515 * int *write_cnt : how much actually has been moved to the
516 * dst_buf. Need not be initialized when
517 * function returns with an error code
518 * (negativ return value)
519 * __u8 *dst_buf : kernel space buffer where the has to be
520 * copied to. The contents of this buffers
521 * goes to a specific segment.
522 * const int seg_sz : the size of the segment dst_buf will be
524 * const zft_position *pos : struct containing the coordinates in
525 * the current volume (byte position,
526 * segment id of current segment etc)
527 * const zft_volinfo *volume: information about the current volume,
529 * const __u8 *src_buf : user space buffer that contains the
530 * data the user wants to be written to
532 * const int req_len : the amount of data the user wants to be
535 static int zftc_write(int *write_cnt
,
536 __u8
*dst_buf
, const int seg_sz
,
537 const __u8 __user
*src_buf
, const int req_len
,
538 const zft_position
*pos
, const zft_volinfo
*volume
)
540 int req_len_left
= req_len
;
543 int buf_pos_write
= pos
->seg_byte_pos
;
544 TRACE_FUN(ft_t_flow
);
546 /* Note: we do not unlock the module because
547 * there are some values cached in that `cseg' variable. We
548 * don't don't want to use this information when being
549 * unloaded by kerneld even when the tape is full or when we
550 * cannot allocate enough memory.
552 if (pos
->tape_pos
> (volume
->size
-volume
->blk_sz
-ZFT_CMPR_OVERHEAD
)) {
555 if (zft_allocate_cmpr_mem(volume
->blk_sz
) < 0) {
556 /* should we unlock the module? But it shouldn't
557 * be locked anyway ...
561 if (buf_pos_write
== 0) { /* fill a new segment */
562 *write_cnt
= buf_pos_write
= start_new_cseg(&cseg
,
569 if (cseg
.cmpr_sz
== 0 && cseg
.cmpr_pos
!= 0) {
570 req_len_left
-= result
= volume
->blk_sz
;
576 *write_cnt
= result
= 0;
579 len_left
= seg_sz
- buf_pos_write
;
580 while ((req_len_left
> 0) && (len_left
> 18)) {
581 /* now we have some size left for a new compressed
582 * block. We know, that the compression buffer is
583 * empty (else there wouldn't be any space left).
585 if (copy_from_user(zftc_scratch_buf
, src_buf
+ result
,
586 volume
->blk_sz
) != 0) {
589 req_len_left
-= volume
->blk_sz
;
590 cseg
.cmpr_sz
= zft_compress(zftc_scratch_buf
, volume
->blk_sz
,
592 if (cseg
.cmpr_sz
< 0) {
593 cseg
.uncmpr
= 0x8000;
594 cseg
.cmpr_sz
= -cseg
.cmpr_sz
;
598 /* increment "result" iff we copied the entire
599 * compressed block to the zft_deblock_buf
601 len_left
-= sizeof(__u16
);
602 if (len_left
>= cseg
.cmpr_sz
) {
603 len_left
-= cseg
.count
= cseg
.cmpr_sz
;
604 cseg
.cmpr_pos
= cseg
.cmpr_sz
= 0;
605 result
+= volume
->blk_sz
;
609 cseg
.count
= len_left
;
612 PUT2(dst_buf
, buf_pos_write
, cseg
.uncmpr
| cseg
.count
);
613 buf_pos_write
+= sizeof(__u16
);
614 memcpy(dst_buf
+ buf_pos_write
, zftc_buf
, cseg
.count
);
615 buf_pos_write
+= cseg
.count
;
616 *write_cnt
+= cseg
.count
+ sizeof(__u16
);
617 FT_SIGNAL_EXIT(_DONT_BLOCK
);
619 /* erase the remainder of the segment if less than 18 bytes
620 * left (18 bytes is due to the QIC-80 standard)
622 if (len_left
<= 18) {
623 memset(dst_buf
+ buf_pos_write
, '\0', len_left
);
624 (*write_cnt
) += len_left
;
626 TRACE(ft_t_data_flow
, "returning %d", result
);
632 * int *read_cnt: the number of bytes we removed from the zft_deblock_buf
634 * int *to_do : the remaining size of the read-request.
638 * char *buff : buff is the address of the upper part of the user
639 * buffer, that hasn't been filled with data yet.
641 * int buf_pos_read : copy of from _ftape_read()
642 * int buf_len_read : copy of buf_len_rd from _ftape_read()
643 * char *zft_deblock_buf: zft_deblock_buf
644 * unsigned short blk_sz: the block size valid for this volume, may differ
646 * int finish: if != 0 means that this is the last segment belonging
648 * returns the amount of data actually copied to the user-buffer
650 * to_do MUST NOT SHRINK except to indicate an EOF. In this case *to_do has to
653 static int zftc_read (int *read_cnt
,
654 __u8 __user
*dst_buf
, const int to_do
,
655 const __u8
*src_buf
, const int seg_sz
,
656 const zft_position
*pos
, const zft_volinfo
*volume
)
660 int remaining
= to_do
;
661 TRACE_FUN(ft_t_flow
);
663 TRACE_CATCH(zft_allocate_cmpr_mem(volume
->blk_sz
),);
664 if (pos
->seg_byte_pos
== 0) {
665 /* new segment just read
667 TRACE_CATCH(get_cseg(&cseg
, src_buf
, seg_sz
, volume
),
669 memcpy(zftc_buf
+ cseg
.cmpr_pos
, src_buf
+ sizeof(__u16
),
671 cseg
.cmpr_pos
+= cseg
.count
;
672 *read_cnt
= cseg
.offset
;
673 DUMP_CMPR_INFO(ft_t_noise
/* ft_t_any */, "", &cseg
);
677 /* loop and uncompress until user buffer full or
678 * deblock-buffer empty
680 TRACE(ft_t_data_flow
, "compressed_sz: %d, compos : %d, *read_cnt: %d",
681 cseg
.cmpr_sz
, cseg
.cmpr_pos
, *read_cnt
);
682 while ((cseg
.spans
== 0) && (remaining
> 0)) {
683 if (cseg
.cmpr_pos
!= 0) { /* cmpr buf is not empty */
685 zft_uncompress(zftc_buf
,
686 cseg
.uncmpr
== 0x8000 ?
687 -cseg
.cmpr_pos
: cseg
.cmpr_pos
,
690 if (uncompressed_sz
!= volume
->blk_sz
) {
692 TRACE_ABORT(-EIO
, ft_t_warn
,
693 "Uncompressed blk (%d) != blk size (%d)",
694 uncompressed_sz
, volume
->blk_sz
);
696 if (copy_to_user(dst_buf
+ result
,
698 uncompressed_sz
) != 0 ) {
701 remaining
-= uncompressed_sz
;
702 result
+= uncompressed_sz
;
706 get_next_cluster(&cseg
, src_buf
, seg_sz
,
707 volume
->end_seg
== pos
->seg_pos
);
708 if (cseg
.count
!= 0) {
709 memcpy(zftc_buf
, src_buf
+ cseg
.offset
,
711 cseg
.cmpr_pos
= cseg
.count
;
712 cseg
.offset
+= cseg
.count
;
713 *read_cnt
+= cseg
.count
+ sizeof(__u16
);
718 TRACE(ft_t_data_flow
, "\n"
719 KERN_INFO
"compressed_sz: %d\n"
720 KERN_INFO
"compos : %d\n"
721 KERN_INFO
"*read_cnt : %d",
722 cseg
.cmpr_sz
, cseg
.cmpr_pos
, *read_cnt
);
724 if (seg_sz
- cseg
.offset
<= 18) {
725 *read_cnt
+= seg_sz
- cseg
.offset
;
726 TRACE(ft_t_data_flow
, "expanding read cnt to: %d", *read_cnt
);
728 TRACE(ft_t_data_flow
, "\n"
729 KERN_INFO
"segment size : %d\n"
730 KERN_INFO
"read count : %d\n"
731 KERN_INFO
"buf_pos_read : %d\n"
732 KERN_INFO
"remaining : %d",
733 seg_sz
, *read_cnt
, pos
->seg_byte_pos
,
734 seg_sz
- *read_cnt
- pos
->seg_byte_pos
);
735 TRACE(ft_t_data_flow
, "returning: %d", result
);
739 /* seeks to the new data-position. Reads sometimes a segment.
741 * start_seg and end_seg give the boundaries of the current volume
742 * blk_sz is the blk_sz of the current volume as stored in the
745 * We don't allow blocksizes less than 1024 bytes, therefore we don't need
746 * a 64 bit argument for new_block_pos.
749 static int seek_in_segment(const unsigned int to_do
, cmpr_info
*c_info
,
750 const char *src_buf
, const int seg_sz
,
751 const int seg_pos
, const zft_volinfo
*volume
);
752 static int slow_seek_forward_until_error(const unsigned int distance
,
753 cmpr_info
*c_info
, zft_position
*pos
,
754 const zft_volinfo
*volume
, __u8
*buf
);
755 static int search_valid_segment(unsigned int segment
,
756 const unsigned int end_seg
,
757 const unsigned int max_foffs
,
758 zft_position
*pos
, cmpr_info
*c_info
,
759 const zft_volinfo
*volume
, __u8
*buf
);
760 static int slow_seek_forward(unsigned int dest
, cmpr_info
*c_info
,
761 zft_position
*pos
, const zft_volinfo
*volume
,
763 static int compute_seg_pos(unsigned int dest
, zft_position
*pos
,
764 const zft_volinfo
*volume
);
766 #define ZFT_SLOW_SEEK_THRESHOLD 10 /* segments */
767 #define ZFT_FAST_SEEK_MAX_TRIALS 10 /* times */
768 #define ZFT_FAST_SEEK_BACKUP 10 /* segments */
770 static int zftc_seek(unsigned int new_block_pos
,
771 zft_position
*pos
, const zft_volinfo
*volume
, __u8
*buf
)
780 int fast_seek_trials
= 0;
781 TRACE_FUN(ft_t_flow
);
783 if (new_block_pos
== 0) {
784 pos
->seg_pos
= volume
->start_seg
;
785 pos
->seg_byte_pos
= 0;
790 dest
= new_block_pos
* (volume
->blk_sz
>> 10);
791 distance
= dest
- (pos
->volume_pos
>> 10);
792 while (distance
!= 0) {
793 seg_dist
= compute_seg_pos(dest
, pos
, volume
);
794 TRACE(ft_t_noise
, "\n"
795 KERN_INFO
"seg_dist: %d\n"
796 KERN_INFO
"distance: %d\n"
797 KERN_INFO
"dest : %d\n"
798 KERN_INFO
"vpos : %d\n"
799 KERN_INFO
"seg_pos : %d\n"
800 KERN_INFO
"trials : %d",
801 seg_dist
, distance
, dest
,
802 (unsigned int)(pos
->volume_pos
>>10), pos
->seg_pos
,
806 TRACE(ft_t_bug
, "BUG: distance %d > 0, "
807 "segment difference %d < 0",
812 new_seg
= pos
->seg_pos
+ seg_dist
;
813 if (new_seg
> volume
->end_seg
) {
814 new_seg
= volume
->end_seg
;
816 if (old_seg
== new_seg
|| /* loop */
817 seg_dist
<= ZFT_SLOW_SEEK_THRESHOLD
||
818 fast_seek_trials
>= ZFT_FAST_SEEK_MAX_TRIALS
) {
819 TRACE(ft_t_noise
, "starting slow seek:\n"
820 KERN_INFO
"fast seek failed too often: %s\n"
821 KERN_INFO
"near target position : %s\n"
822 KERN_INFO
"looping between two segs : %s",
824 ZFT_FAST_SEEK_MAX_TRIALS
)
826 (seg_dist
<= ZFT_SLOW_SEEK_THRESHOLD
)
830 result
= slow_seek_forward(dest
, &cseg
,
835 limit
= volume
->end_seg
;
838 result
= search_valid_segment(new_seg
, limit
,
842 if (result
== 0 || result
== -EINTR
) {
845 if (new_seg
== volume
->start_seg
) {
846 result
= -EIO
; /* set errror
852 new_seg
-= ZFT_FAST_SEEK_BACKUP
;
853 if (new_seg
< volume
->start_seg
) {
854 new_seg
= volume
->start_seg
;
859 "Couldn't find a readable segment");
862 } else /* if (distance < 0) */ {
864 TRACE(ft_t_bug
, "BUG: distance %d < 0, "
865 "segment difference %d >0",
870 new_seg
= pos
->seg_pos
+ seg_dist
;
871 if (fast_seek_trials
> 0 && seg_dist
== 0) {
872 /* this avoids sticking to the same
873 * segment all the time. On the other hand:
874 * if we got here for the first time, and the
875 * deblock_buffer still contains a valid
876 * segment, then there is no need to skip to
877 * the previous segment if the desired position
878 * is inside this segment.
882 if (new_seg
< volume
->start_seg
) {
883 new_seg
= volume
->start_seg
;
885 limit
= pos
->seg_pos
;
888 result
= search_valid_segment(new_seg
, limit
,
892 if (result
== 0 || result
== -EINTR
) {
895 if (new_seg
== volume
->start_seg
) {
896 result
= -EIO
; /* set errror
902 new_seg
-= ZFT_FAST_SEEK_BACKUP
;
903 if (new_seg
< volume
->start_seg
) {
904 new_seg
= volume
->start_seg
;
909 "Couldn't find a readable segment");
913 distance
= dest
- (pos
->volume_pos
>> 10);
919 /* advance inside the given segment at most to_do bytes.
923 static int seek_in_segment(const unsigned int to_do
,
928 const zft_volinfo
*volume
)
931 int blk_sz
= volume
->blk_sz
>> 10;
932 int remaining
= to_do
;
933 TRACE_FUN(ft_t_flow
);
935 if (c_info
->offset
== 0) {
936 /* new segment just read
938 TRACE_CATCH(get_cseg(c_info
, src_buf
, seg_sz
, volume
),);
939 c_info
->cmpr_pos
+= c_info
->count
;
940 DUMP_CMPR_INFO(ft_t_noise
, "", c_info
);
942 /* loop and uncompress until user buffer full or
943 * deblock-buffer empty
945 TRACE(ft_t_noise
, "compressed_sz: %d, compos : %d",
946 c_info
->cmpr_sz
, c_info
->cmpr_pos
);
947 while (c_info
->spans
== 0 && remaining
> 0) {
948 if (c_info
->cmpr_pos
!= 0) { /* cmpr buf is not empty */
951 c_info
->cmpr_pos
= 0;
954 get_next_cluster(c_info
, src_buf
, seg_sz
,
955 volume
->end_seg
== seg_pos
);
956 if (c_info
->count
!= 0) {
957 c_info
->cmpr_pos
= c_info
->count
;
958 c_info
->offset
+= c_info
->count
;
963 /* Allow escape from this loop on signal!
965 FT_SIGNAL_EXIT(_DONT_BLOCK
);
966 DUMP_CMPR_INFO(ft_t_noise
, "", c_info
);
967 TRACE(ft_t_noise
, "to_do: %d", remaining
);
969 if (seg_sz
- c_info
->offset
<= 18) {
970 c_info
->offset
= seg_sz
;
972 TRACE(ft_t_noise
, "\n"
973 KERN_INFO
"segment size : %d\n"
974 KERN_INFO
"buf_pos_read : %d\n"
975 KERN_INFO
"remaining : %d",
976 seg_sz
, c_info
->offset
,
977 seg_sz
- c_info
->offset
);
981 static int slow_seek_forward_until_error(const unsigned int distance
,
984 const zft_volinfo
*volume
,
987 unsigned int remaining
= distance
;
991 TRACE_FUN(ft_t_flow
);
993 seg_pos
= pos
->seg_pos
;
995 TRACE_CATCH(seg_sz
= zft_fetch_segment(seg_pos
, buf
,
997 /* now we have the contents of the actual segment in
1000 TRACE_CATCH(result
= seek_in_segment(remaining
, c_info
, buf
,
1001 seg_sz
, seg_pos
,volume
),);
1002 remaining
-= result
;
1003 pos
->volume_pos
+= result
<<10;
1004 pos
->seg_pos
= seg_pos
;
1005 pos
->seg_byte_pos
= c_info
->offset
;
1007 if (seg_pos
<= volume
->end_seg
&& c_info
->offset
== seg_sz
) {
1009 pos
->seg_byte_pos
= 0;
1012 /* Allow escape from this loop on signal!
1014 FT_SIGNAL_EXIT(_DONT_BLOCK
);
1015 TRACE(ft_t_noise
, "\n"
1016 KERN_INFO
"remaining: %d\n"
1017 KERN_INFO
"seg_pos: %d\n"
1018 KERN_INFO
"end_seg: %d\n"
1019 KERN_INFO
"result: %d",
1020 remaining
, seg_pos
, volume
->end_seg
, result
);
1021 } while (remaining
> 0 && seg_pos
<= volume
->end_seg
);
1025 /* return segment id of next segment containing valid data, -EIO otherwise
1027 static int search_valid_segment(unsigned int segment
,
1028 const unsigned int end_seg
,
1029 const unsigned int max_foffs
,
1032 const zft_volinfo
*volume
,
1037 TRACE_FUN(ft_t_flow
);
1039 memset(&tmp_info
, 0, sizeof(cmpr_info
));
1040 while (segment
<= end_seg
) {
1041 FT_SIGNAL_EXIT(_DONT_BLOCK
);
1043 "Searching readable segment between %d and %d",
1045 seg_sz
= zft_fetch_segment(segment
, buf
, FT_RD_AHEAD
);
1047 (get_cseg (&tmp_info
, buf
, seg_sz
, volume
) >= 0) &&
1048 (tmp_info
.foffs
!= 0 || segment
== volume
->start_seg
)) {
1049 if ((tmp_info
.foffs
>>10) > max_foffs
) {
1050 TRACE_ABORT(-EIO
, ft_t_noise
, "\n"
1051 KERN_INFO
"cseg.foff: %d\n"
1052 KERN_INFO
"dest : %d",
1053 (int)(tmp_info
.foffs
>> 10),
1056 DUMP_CMPR_INFO(ft_t_noise
, "", &tmp_info
);
1058 pos
->seg_pos
= segment
;
1059 pos
->volume_pos
= c_info
->foffs
;
1060 pos
->seg_byte_pos
= c_info
->offset
;
1061 TRACE(ft_t_noise
, "found segment at %d", segment
);
1069 static int slow_seek_forward(unsigned int dest
,
1072 const zft_volinfo
*volume
,
1075 unsigned int distance
;
1077 TRACE_FUN(ft_t_flow
);
1079 distance
= dest
- (pos
->volume_pos
>> 10);
1080 while ((distance
> 0) &&
1081 (result
= slow_seek_forward_until_error(distance
,
1086 if (result
== -EINTR
) {
1089 TRACE(ft_t_noise
, "seg_pos: %d", pos
->seg_pos
);
1090 /* the failing segment is either pos->seg_pos or
1091 * pos->seg_pos + 1. There is no need to further try
1092 * that segment, because ftape_read_segment() already
1093 * has tried very much to read it. So we start with
1094 * following segment, which is pos->seg_pos + 1
1096 if(search_valid_segment(pos
->seg_pos
+1, volume
->end_seg
, dest
,
1099 TRACE(ft_t_noise
, "search_valid_segment() failed");
1103 distance
= dest
- (pos
->volume_pos
>> 10);
1105 TRACE(ft_t_noise
, "segment: %d", pos
->seg_pos
);
1106 /* found valid segment, retry the seek */
1111 static int compute_seg_pos(const unsigned int dest
,
1113 const zft_volinfo
*volume
)
1116 int distance
= dest
- (pos
->volume_pos
>> 10);
1117 unsigned int raw_size
;
1118 unsigned int virt_size
;
1119 unsigned int factor
;
1120 TRACE_FUN(ft_t_flow
);
1122 if (distance
>= 0) {
1123 raw_size
= volume
->end_seg
- pos
->seg_pos
+ 1;
1124 virt_size
= ((unsigned int)(volume
->size
>>10)
1125 - (unsigned int)(pos
->volume_pos
>>10)
1126 + FT_SECTORS_PER_SEGMENT
- FT_ECC_SECTORS
- 1);
1127 virt_size
/= FT_SECTORS_PER_SEGMENT
- FT_ECC_SECTORS
;
1128 if (virt_size
== 0 || raw_size
== 0) {
1131 if (raw_size
>= (1<<25)) {
1132 factor
= raw_size
/(virt_size
>>7);
1134 factor
= (raw_size
<<7)/virt_size
;
1136 segment
= distance
/(FT_SECTORS_PER_SEGMENT
-FT_ECC_SECTORS
);
1137 segment
= (segment
* factor
)>>7;
1139 raw_size
= pos
->seg_pos
- volume
->start_seg
+ 1;
1140 virt_size
= ((unsigned int)(pos
->volume_pos
>>10)
1141 + FT_SECTORS_PER_SEGMENT
- FT_ECC_SECTORS
- 1);
1142 virt_size
/= FT_SECTORS_PER_SEGMENT
- FT_ECC_SECTORS
;
1143 if (virt_size
== 0 || raw_size
== 0) {
1146 if (raw_size
>= (1<<25)) {
1147 factor
= raw_size
/(virt_size
>>7);
1149 factor
= (raw_size
<<7)/virt_size
;
1151 segment
= distance
/(FT_SECTORS_PER_SEGMENT
-FT_ECC_SECTORS
);
1153 TRACE(ft_t_noise
, "factor: %d/%d", factor
, 1<<7);
1157 static struct zft_cmpr_ops cmpr_ops
= {
1166 int zft_compressor_init(void)
1168 TRACE_FUN(ft_t_flow
);
1171 printk(KERN_INFO
"zftape compressor v1.00a 970514 for " FTAPE_VERSION
"\n");
1172 if (TRACE_LEVEL
>= ft_t_info
) {
1174 KERN_INFO
"(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
1175 KERN_INFO
"Compressor for zftape (lzrw3 algorithm)\n");
1178 /* print a short no-nonsense boot message */
1179 printk("zftape compressor v1.00a 970514\n");
1180 printk("For use with " FTAPE_VERSION
"\n");
1182 TRACE(ft_t_info
, "zft_compressor_init @ 0x%p", zft_compressor_init
);
1183 TRACE(ft_t_info
, "installing compressor for zftape ...");
1184 TRACE_CATCH(zft_cmpr_register(&cmpr_ops
),);
1191 "(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de");
1193 "Compression routines for zftape. Uses the lzrw3 algorithm by Ross Williams");
1194 MODULE_LICENSE("GPL");
1196 /* Called by modules package when installing the driver
1198 int init_module(void)
1200 return zft_compressor_init();