Re: feature req: vnconfig should work on readonly fs; round 3

2006-09-19 Thread Pedro Martelletto
On Mon, Sep 11, 2006 at 03:59:45PM +, Paul Stoeber wrote:
 Let's see if I can get this closer to right.
 The patch is against and tested on -current.
 Thank you, Pedro, for your help.

Paul,

Here's a slightly revised version of your patch. It would be nice to
have a couple of test reports on it (from people on misc@).

-p.

Index: sys/dev/vnd.c
===
RCS file: /cvs/src/sys/dev/vnd.c,v
retrieving revision 1.62
diff -u -p -r1.62 vnd.c
--- sys/dev/vnd.c   13 Aug 2006 17:55:07 -  1.62
+++ sys/dev/vnd.c   19 Sep 2006 15:40:17 -
@@ -142,6 +142,9 @@ struct vnd_softc {
 #defineVNF_HAVELABEL   0x0400
 #defineVNF_BUSY0x0800
 #defineVNF_SIMPLE  0x1000
+#defineVNF_READONLY0x2000
+
+#defineVNDRW(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;
Index: usr.sbin/vnconfig/vnconfig.c
===
RCS file: /cvs/src/usr.sbin/vnconfig/vnconfig.c,v
retrieving revision 1.18
diff -u -p -r1.18 vnconfig.c
--- usr.sbin/vnconfig/vnconfig.c1 Jul 2006 07:36:27 -   1.18
+++ usr.sbin/vnconfig/vnconfig.c19 Sep 2006 15:40:17 -
@@ -226,9 +226,9 @@ config(char *dev, char *file, int action
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;



feature req: vnconfig should work on readonly fs; round 3

2006-09-11 Thread Paul Stoeber
Let's see if I can get this closer to right.
The patch is against and tested on -current.
Thank you, Pedro, for your help.

--- sys/dev/vnd.c.orig  Sun Sep 10 19:18:28 2006
+++ sys/dev/vnd.c   Mon Sep 11 15:54:30 2006
@@ -142,7 +142,10 @@
 #defineVNF_HAVELABEL   0x0400
 #defineVNF_BUSY0x0800
 #defineVNF_SIMPLE  0x1000
+#defineVNF_READONLY0x2000
 
+#define FLG(vnd) (vnd-sc_flags  VNF_READONLY ? FREAD : FREAD|FWRITE)
+
 struct vnd_softc *vnd_softc;
 int numvnd = 0;
 
@@ -234,6 +237,11 @@
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,25 @@
}
 
/*
-* Always open for read and write.
-* This is probably bogus, but it lets vn_open()
+* 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 (EROFS == error) {
+   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, FLG(vnd), p-p_ucred, p);
vndunlock(vnd);
return (error);
}
@@ -838,7 +851,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);
}
@@ -851,7 +864,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);
@@ -1087,7 +1100,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   Sun Sep 10 19:19:25 2006
+++ usr.sbin/vnconfig/vnconfig.cMon Sep 11 15:28:27 2006
@@ -226,7 +226,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) {