*BSD News Article 17741


Return to BSD News archive

Newsgroups: comp.os.386bsd.bugs
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!math.ohio-state.edu!cs.utexas.edu!geraldo.cc.utexas.edu!portal.austin.ibm.com!awdprime.austin.ibm.com!fredriks
From: fredriks@austin.ibm.com (Lars Fredriksen)
Subject: Bug with the tape driver/kernel configuration 0.2.[3-4]
Originator: @worf.cet.austin.ibm.com
Sender: news@austin.ibm.com (News id)
Message-ID: <C9GBxC.2FHt@austin.ibm.com>
Date: Wed, 30 Jun 1993 20:36:48 GMT
Organization: IBM Austin
Lines: 81


Hi,
	With the 0.2.4 patchkit the tape driver is configured as a 
block device, and MAKEDEV from 0.2.3 (I believe) creates /dev/st0
as a block device.

	I don't understand why there is a block device for the tape 
device, and removing that feature (?) will remove the problem I am 
about to describe.

	Basically if you do a tar -cvf /dev/st0 ., will sooner or
later crash your system. The write system call, goes throught the
ufs layers and ends up in spec_write. Here a check is made to see
if you are writing to a  block device, and if so, an ioctl to the
block device is done to as for the partition table. Well the st
device driver has no knowledge of partition tables, and returns
EINVAL on that ioctl. The code in spec_write doesn't check the 
return code, and you will get a page fault in the kernel when
dpart.part == 0. Since dpart is an automatic, this doesn't happen 
all the time.

The code looks as follows:

spec_write(vp, uio, ioflag, cred)
[....]
        switch (vp->v_type) {

        case VCHR:

                /*
                 * Negative offsets allowed only for /dev/kmem
                 */
                if (uio->uio_offset < 0 && major(vp->v_rdev) != mem_no)
                        return (EINVAL);
                VOP_UNLOCK(vp);
                error = (*cdevsw[major(vp->v_rdev)].d_write)
                        (vp->v_rdev, uio, ioflag);
                VOP_LOCK(vp);
                return (error);

        case VBLK:
                if (uio->uio_resid == 0)
                        return (0);
                if (uio->uio_offset < 0)
                        return (EINVAL);
                bsize = BLKDEV_IOSIZE;
                if ((*bdevsw[major(vp->v_rdev)].d_ioctl)(vp->v_rdev,
DIOCGPART,
                    (caddr_t)&dpart, FREAD, p) == 0) {

  ->>>>>                 if (dpart.part->p_fstype == FS_BSDFFS &&

                            dpart.part->p_frag != 0 && dpart.part->p_fsize
!= 0)

                                bsize = dpart.part->p_frag *
                                    dpart.part->p_fsize;
                }


The if (dpart.part->p_fstype == FS_BFSDFFS is what is causing the page fault,
when dpart.part == 0.


If for some reason there is a need for a block tape device, the st driver has
to be modified to handle the DIOCGPART ioctl, or there has to be a check
after doing the ioctl to take appropriate action. On the other hand if there
is no need for a block tape device (I haven't seen anyone else out there IBM,
SUN, HP having a block tape device), then we just have to fix /dev/MAKEDEV and
/sys/i386/i386/conf.c to remove the st blockdevice support.

Lars.

PS. This has been reported via sendbug so the patchkit people should have
a copy of the above. Rodney et al, if you didn't get it (email connection
has been a little flakey), please let me know.
-- 

Regards,

----------------------------------------------------------------------------