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) {

Reply via email to