The patch appears to work for me on 3.9 i386, and
I do need your comments on it. Thank you, Joachim.
--- sys/dev/vnd.c.orig Fri Sep 8 03:41:21 2006
+++ sys/dev/vnd.c Sat Sep 9 05:09:38 2006
@@ -142,7 +142,10 @@
#define VNF_HAVELABEL 0x0400
#define VNF_BUSY 0x0800
#define VNF_SIMPLE 0x1000
+#define VNF_READONLY 0x2000
+#define FLG(vnd) (vnd->sc_flags & VNF_READONLY ? FREAD : FREAD|FWRITE)
+
struct vnd_softc *vnd_softc;
int numvnd = 0;
@@ -231,6 +234,9 @@
return (ENXIO);
sc = &vnd_softc[unit];
+ if (flags & FWRITE && sc->sc_flags & VNF_READONLY)
+ return (EROFS);
+
if ((error = vndlock(sc)) != 0)
return (error);
@@ -817,14 +823,15 @@
* have to worry about them.
*/
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, vio->vnd_file, p);
- if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) {
+ vnd->sc_flags &= ~VNF_READONLY;
+ if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0 && (error !=
EROFS || (vnd->sc_flags |= VNF_READONLY, (error = vn_open(&nd, FREAD, 0)) !=
0))) {
vndunlock(vnd);
return (error);
}
error = VOP_GETATTR(nd.ni_vp, &vattr, p->p_ucred, p);
if (error) {
VOP_UNLOCK(nd.ni_vp, 0, p);
- (void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
+ (void) vn_close(nd.ni_vp, FLG(vnd), p->p_ucred, p);
vndunlock(vnd);
return (error);
}
@@ -832,7 +839,7 @@
vnd->sc_vp = nd.ni_vp;
vnd->sc_size = btodb(vattr.va_size); /* note truncation */
if ((error = vndsetcred(vnd, p->p_ucred)) != 0) {
- (void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
+ (void) vn_close(nd.ni_vp, FLG(vnd), p->p_ucred, p);
vndunlock(vnd);
return (error);
}
@@ -845,7 +852,7 @@
if ((error = copyin(vio->vnd_key, key,
vio->vnd_keylen)) != 0) {
- (void) vn_close(nd.ni_vp, FREAD|FWRITE,
+ (void) vn_close(nd.ni_vp, FLG(vnd),
p->p_ucred, p);
vndunlock(vnd);
return (error);
@@ -1082,7 +1089,7 @@
vnd->sc_flags &= ~VNF_INITED;
if (vp == (struct vnode *)0)
panic("vndioctl: null vp");
- (void) vn_close(vp, FREAD|FWRITE, vnd->sc_cred, p);
+ (void) vn_close(vp, FLG(vnd), vnd->sc_cred, p);
crfree(vnd->sc_cred);
vnd->sc_vp = (struct vnode *)0;
vnd->sc_cred = (struct ucred *)0;
--- usr.sbin/vnconfig/vnconfig.c.orig Sat Sep 9 04:37:15 2006
+++ usr.sbin/vnconfig/vnconfig.c Sat Sep 9 04:59:25 2006
@@ -159,7 +159,7 @@
char *rdev;
int rv;
- if (opendev(dev, O_RDWR, OPENDEV_PART, &rdev) < 0)
+ if (opendev(dev, O_RDONLY, OPENDEV_PART, &rdev) < 0)
err(4, "%s", rdev);
f = fopen(rdev, "rw");
if (f == NULL) {