Subject: kern/3811: vnconfig hangs if target file is less than 2048 512-bytes
To: None <gnats-bugs@gnats.netbsd.org>
From: None <enami@ba2.so-net.or.jp>
List: netbsd-bugs
Date: 06/29/1997 13:02:48
>Number: 3811
>Category: kern
>Synopsis: vnconfig hangs if target file is less than 2048 512-bytes block and configured without geomspec.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Jun 28 21:35:02 1997
>Last-Modified:
>Originator: enami tsugutomo
>Organization:
>Release: NetBSD-current 1997 June 27
>Environment:
System: NetBSD pavlov.enami.ba2.so-net.or.jp 1.2G NetBSD 1.2G (PAVLOV) #299: Sat Jun 28 11:55:32 JST 1997 enami@pavlov.enami.ba2.so-net.or.jp:/b/netbsd/kernel/compile/PAVLOV i386
>Description:
vnconfig hangs if target file is less than 2048 512-bytes block
and tried to config without specifiying geomspec.
>How-To-Repeat:
Here is log done on NetBSD/i386.
Script started on Sun Jun 29 12:22:22 1997
king-show# cd /var/tmp
king-show# dd if=/dev/zero of=tako bs=100k count=10
10+0 records in
10+0 records out
1024000 bytes transferred in 1 secs (1024000 bytes/sec)
king-show# ls -l tako
-rw-r--r-- 1 root wheel 1024000 Jun 29 12:22 tako
king-show# date
Sun Jun 29 12:23:04 JST 1997
king-show# vnconfig -v -c /dev/vnd0d /var/tmp/tako
vnconfig: VNDIOCSET: Invalid argument
^C
king-show# date
Sun Jun 29 12:26:28 JST 1997
>Fix:
vnconfig hangs during closing vnd. It is because ioctl bail out
without unlocking vnd if target file is shorter than 2048 512-byte
block.
Just add missing vndunlock() before following return:
if (vnd->sc_size < (32 * 64))
return (EINVAL);
or is it better to centerize unlock like this?
Index: vnd.c
===================================================================
RCS file: /a/cvsroot/NetBSD/src/sys/dev/vnd.c,v
retrieving revision 1.1.1.12
diff -u -r1.1.1.12 vnd.c
--- vnd.c 1997/06/28 00:07:53 1.1.1.12
+++ vnd.c 1997/06/29 03:15:53
@@ -704,16 +704,14 @@
* have to worry about them.
*/
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, vio->vnd_file, p);
- if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) {
- vndunlock(vnd);
- return(error);
- }
+ if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0)
+ goto bad;
+
error = VOP_GETATTR(nd.ni_vp, &vattr, p->p_ucred, p);
if (error) {
VOP_UNLOCK(nd.ni_vp);
(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
- vndunlock(vnd);
- return(error);
+ goto bad;
}
VOP_UNLOCK(nd.ni_vp);
vnd->sc_vp = nd.ni_vp;
@@ -737,8 +735,8 @@
(vnd->sc_geom.vng_secsize % DEV_BSIZE) != 0) {
(void) vn_close(nd.ni_vp, FREAD|FWRITE,
p->p_ucred, p);
- vndunlock(vnd);
- return (EINVAL);
+ error = EINVAL;
+ goto bad;
}
/*
@@ -757,16 +755,18 @@
if (vnd->sc_size < geomsize) {
(void) vn_close(nd.ni_vp, FREAD|FWRITE,
p->p_ucred, p);
- vndunlock(vnd);
- return (EINVAL);
+ error = EINVAL;
+ goto bad;
}
} else {
/*
* Size must be at least 2048 DEV_BSIZE blocks
* (1M) in order to use this geometry.
*/
- if (vnd->sc_size < (32 * 64))
- return (EINVAL);
+ if (vnd->sc_size < (32 * 64)) {
+ error = EINVAL;
+ goto bad;
+ }
vnd->sc_geom.vng_secsize = DEV_BSIZE;
vnd->sc_geom.vng_nsectors = 32;
@@ -788,8 +788,7 @@
if ((error = vndsetcred(vnd, p->p_ucred)) != 0) {
(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
- vndunlock(vnd);
- return(error);
+ goto bad;
}
vndthrottle(vnd, vnd->sc_vp);
vio->vnd_size = dbtob(vnd->sc_size);
@@ -813,8 +812,6 @@
/* Try and read the disklabel. */
vndgetdisklabel(dev);
- vndunlock(vnd);
-
break;
case VNDIOCCLR:
@@ -831,8 +828,8 @@
if ((vnd->sc_dkdev.dk_openmask & ~pmask) ||
((vnd->sc_dkdev.dk_bopenmask & pmask) &&
(vnd->sc_dkdev.dk_copenmask & pmask))) {
- vndunlock(vnd);
- return (EBUSY);
+ error = EBUSY;
+ goto bad;
}
vndclear(vnd);
@@ -844,19 +841,17 @@
/* Detatch the disk. */
disk_detach(&vnd->sc_dkdev);
- vndunlock(vnd);
-
break;
case DIOCGDINFO:
*(struct disklabel *)data = *(vnd->sc_dkdev.dk_label);
- break;
+ return (0);
case DIOCGPART:
((struct partinfo *)data)->disklab = vnd->sc_dkdev.dk_label;
((struct partinfo *)data)->part =
&vnd->sc_dkdev.dk_label->d_partitions[DISKPART(dev)];
- break;
+ return (0);
case DIOCWDINFO:
case DIOCSDINFO:
@@ -876,10 +871,6 @@
vnd->sc_flags &= ~VNF_LABELLING;
- vndunlock(vnd);
-
- if (error)
- return (error);
break;
case DIOCWLABEL:
@@ -887,13 +878,15 @@
vnd->sc_flags |= VNF_WLABEL;
else
vnd->sc_flags &= ~VNF_WLABEL;
- break;
+ return (0);
default:
return (ENOTTY);
}
- return (0);
+ bad:
+ vndunlock(vnd);
+ return (error);
}
/*
>Audit-Trail:
>Unformatted: