diff options
author | Pedro Martelletto <pedro@cvs.openbsd.org> | 2006-09-20 13:51:20 +0000 |
---|---|---|
committer | Pedro Martelletto <pedro@cvs.openbsd.org> | 2006-09-20 13:51:20 +0000 |
commit | aff164e3dc2d93984a5509aeefb0efe5542f6343 (patch) | |
tree | 1d0039490fd7f266c9a0ec3db21ea11f1e8905da | |
parent | f36fa7376b2cb66322f3072979cb62f703828e1f (diff) |
Make vnd(4) work on read-only file systems, from Paul Stoeber, okay tedu@
-rw-r--r-- | sys/dev/vnd.c | 34 | ||||
-rw-r--r-- | usr.sbin/vnconfig/vnconfig.c | 6 |
2 files changed, 27 insertions, 13 deletions
diff --git a/sys/dev/vnd.c b/sys/dev/vnd.c index 535cbb42014..a8d132a8641 100644 --- a/sys/dev/vnd.c +++ b/sys/dev/vnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vnd.c,v 1.62 2006/08/13 17:55:07 thib Exp $ */ +/* $OpenBSD: vnd.c,v 1.63 2006/09/20 13:51:19 pedro Exp $ */ /* $NetBSD: vnd.c,v 1.26 1996/03/30 23:06:11 christos Exp $ */ /* @@ -142,6 +142,9 @@ struct vnd_softc { #define VNF_HAVELABEL 0x0400 #define VNF_BUSY 0x0800 #define VNF_SIMPLE 0x1000 +#define VNF_READONLY 0x2000 + +#define VNDRW(v) ((v)->sc_flags & VNF_READONLY ? FREAD : FREAD|FWRITE) struct vnd_softc *vnd_softc; int numvnd = 0; @@ -234,6 +237,11 @@ vndopen(dev, flags, mode, p) if ((error = vndlock(sc)) != 0) return (error); + if ((flags & FWRITE) && (sc->sc_flags & VNF_READONLY)) { + error = EROFS; + goto bad; + } + if ((sc->sc_flags & VNF_INITED) && (sc->sc_flags & VNF_HAVELABEL) == 0) { sc->sc_flags |= VNF_HAVELABEL; @@ -817,20 +825,26 @@ vndioctl(dev, cmd, addr, flag, p) } /* - * Always open for read and write. - * This is probably bogus, but it lets vn_open() - * weed out directories, sockets, etc. so we don't - * have to worry about them. + * Open for read and write first. This lets vn_open() weed out + * directories, sockets, etc. so we don't 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; + error = vn_open(&nd, FREAD|FWRITE, 0); + if (error == EROFS) { + vnd->sc_flags |= VNF_READONLY; + error = vn_open(&nd, FREAD, 0); + } + if (error) { 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, VNDRW(vnd), p->p_ucred, p); vndunlock(vnd); return (error); } @@ -838,7 +852,7 @@ vndioctl(dev, cmd, addr, flag, p) 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, VNDRW(vnd), p->p_ucred, p); vndunlock(vnd); return (error); } @@ -851,7 +865,7 @@ vndioctl(dev, cmd, addr, flag, p) 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, VNDRW(vnd), p->p_ucred, p); vndunlock(vnd); return (error); @@ -1087,7 +1101,7 @@ vndclear(vnd) 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, VNDRW(vnd), vnd->sc_cred, p); crfree(vnd->sc_cred); vnd->sc_vp = (struct vnode *)0; vnd->sc_cred = (struct ucred *)0; diff --git a/usr.sbin/vnconfig/vnconfig.c b/usr.sbin/vnconfig/vnconfig.c index e2dfe2769c9..589a364ac0a 100644 --- a/usr.sbin/vnconfig/vnconfig.c +++ b/usr.sbin/vnconfig/vnconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vnconfig.c,v 1.18 2006/07/01 07:36:27 jmc Exp $ */ +/* $OpenBSD: vnconfig.c,v 1.19 2006/09/20 13:51:19 pedro Exp $ */ /* * Copyright (c) 1993 University of Utah. * Copyright (c) 1990, 1993 @@ -226,9 +226,9 @@ config(char *dev, char *file, int action, char *key, size_t keylen) 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"); + f = fopen(rdev, "r"); if (f == NULL) { warn("%s", rdev); rv = -1; |