Re: Oops in Zftape Driver (kernel 2.2.5)

Mikael Pettersson (mikpe@csd.uu.se)
Sat, 10 Apr 1999 02:36:50 +0200 (MET DST)


David Frana wrote:

> Hello, i have found this bug in (z)ftape under Linux-2.2.5,
> i hope the attached Files provide Enough information,
> if they do not, let me know (fhopge@cin.net)
> thank you.

[describes how "mt tell" causes oops]

Yep, I can reproduce this bug.
Insert a tape, mt rewind, mt tell --> oops. This is bad
since is leaves the ftape driver in a "busy" state and
it even seems to leave the hardware (a Seagate TST3200R
on a CTC-2Mb fast controller in my case) in a useless state;
I have to power-cycle to get it back.

The problem appears to be that the driver isn't properly
initialized at this point: in particular the volume table
doesn't seem to have been read. First mt_tell() called
zft_find_volume() with zft_pos.seg_pos == -1: this -1
is promptly cast to unsigned which caused the first "<"
comparison in zft_find_volume() to fail. Second, "cur_vtbl"
is NULL, which caused the NULL ptr oops.

The proper fix would be ensure that the volume table has been
read at this point, but I don't really know where and how
this should be done. The patch below is a bandaid which cures
the immediate problem for me.

(ftape-4.02 has fixed this bug. I have a big patch which adds
ftape-4.02 to kernel 2.2.5 and fixes some bugs; contact me
if you want it.)

/ Mikael

--- linux-2.2.5-ac6/drivers/char/ftape/zftape/zftape-vtbl.c.~1~ Tue Nov 25 23:45:28 1997
+++ linux-2.2.5-ac6/drivers/char/ftape/zftape/zftape-vtbl.c Thu Apr 8 23:01:04 1999
@@ -720,7 +720,7 @@
tape_vtbl.blk_sz = zft_blk_sz;
TRACE_EXIT &tape_vtbl;
}
- if (seg_pos < zft_first_vtbl->start_seg) {
+ if ((int)seg_pos < (int)zft_first_vtbl->start_seg) {
TRACE_EXIT (cur_vtbl = zft_first_vtbl);
}
while (seg_pos > cur_vtbl->end_seg) {
--- linux-2.2.5-ac6/drivers/char/ftape/zftape/zftape-ctl.c.~1~ Mon May 11 19:50:15 1998
+++ linux-2.2.5-ac6/drivers/char/ftape/zftape/zftape-ctl.c Thu Apr 8 22:59:35 1999
@@ -552,10 +552,14 @@
*/
static int mt_tell(int *arg)
{
+ const zft_volinfo *vtbl;
TRACE_FUN(ft_t_flow);

- *arg = zft_div_blksz(zft_pos.volume_pos,
- zft_find_volume(zft_pos.seg_pos)->blk_sz);
+ vtbl = zft_find_volume(zft_pos.seg_pos);
+ *arg = vtbl->blk_sz
+ ? zft_div_blksz(zft_pos.volume_pos, vtbl->blk_sz)
+ : -1;
+
TRACE_EXIT 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/