Module Name:    src
Committed By:   pooka
Date:           Thu Feb  3 15:36:30 UTC 2011

Modified Files:
        src/sys/rump/librump/rumpvfs: rumpblk.c

Log Message:
* open backend device once when the rumpblk is registered instead of
  every time the virtual device is opened.  this takes care of e.g.
  a midlife chmod crisis
* when mapping initial windows, consistently look at host size and
  host offset.  otherwise we might end up in a situation with 0
  initial windows mapped, and that will cause a crash later.


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/sys/rump/librump/rumpvfs/rumpblk.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/librump/rumpvfs/rumpblk.c
diff -u src/sys/rump/librump/rumpvfs/rumpblk.c:1.44 src/sys/rump/librump/rumpvfs/rumpblk.c:1.45
--- src/sys/rump/librump/rumpvfs/rumpblk.c:1.44	Thu Feb  3 10:06:06 2011
+++ src/sys/rump/librump/rumpvfs/rumpblk.c	Thu Feb  3 15:36:30 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpblk.c,v 1.44 2011/02/03 10:06:06 pooka Exp $	*/
+/*	$NetBSD: rumpblk.c,v 1.45 2011/02/03 15:36:30 pooka Exp $	*/
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.44 2011/02/03 10:06:06 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.45 2011/02/03 15:36:30 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -71,6 +71,15 @@
 #include "rump_private.h"
 #include "rump_vfs_private.h"
 
+/*
+ * O_DIRECT is the fastest alternative, but since it falls back to
+ * non-direct writes silently, I am not sure it will always be 100% safe.
+ * Use it and play with it, but do that with caution.
+ */
+#if 0
+#define HAS_ODIRECT
+#endif
+
 #if 0
 #define DPRINTF(x) printf x
 #else
@@ -99,6 +108,7 @@
 static struct rblkdev {
 	char *rblk_path;
 	int rblk_fd;
+	int rblk_mode;
 #ifdef HAS_ODIRECT
 	int rblk_dfd;
 #endif
@@ -152,6 +162,9 @@
 	rumpblk_ioctl, nostop, notty, nopoll, nommap, nokqfilter, D_DISK
 };
 
+static int backend_open(struct rblkdev *, const char *);
+static int backend_close(struct rblkdev *);
+
 /* fail every n out of BLKFAIL_MAX */
 #define BLKFAIL_MAX 10000
 static int blkfail;
@@ -422,10 +435,12 @@
 	}
 
 	rblk = &minors[i];
+	rblk->rblk_path = __UNCONST("taken");
+	mutex_exit(&rumpblk_lock);
+
 	len = strlen(path);
 	rblk->rblk_path = malloc(len + 1, M_TEMP, M_WAITOK);
 	strcpy(rblk->rblk_path, path);
-	rblk->rblk_fd = -1;
 	rblk->rblk_hostoffset = offset;
 	if (size != RUMPBLK_SIZENOTSET) {
 		KASSERT(size + offset <= flen);
@@ -437,7 +452,13 @@
 	rblk->rblk_hostsize = flen;
 	rblk->rblk_ftype = ftype;
 	makedefaultlabel(&rblk->rblk_label, rblk->rblk_size, i);
-	mutex_exit(&rumpblk_lock);
+
+	if ((error = backend_open(rblk, path)) != 0) {
+		memset(&rblk->rblk_label, 0, sizeof(rblk->rblk_label));
+		free(rblk->rblk_path, M_TEMP);
+		rblk->rblk_path = NULL;
+		return error;
+	}
 
 	*dmin = i;
 	return 0;
@@ -465,41 +486,52 @@
 		return ENOENT;
 
 	rblk = &minors[i];
-	KASSERT(rblk->rblk_fd == -1);
+	backend_close(rblk);
 
 	wincleanup(rblk);
 	free(rblk->rblk_path, M_TEMP);
-	rblk->rblk_path = NULL;
 	memset(&rblk->rblk_label, 0, sizeof(rblk->rblk_label));
+	rblk->rblk_path = NULL;
 
 	return 0;
 }
 
-int
-rumpblk_open(dev_t dev, int flag, int fmt, struct lwp *l)
+static int
+backend_open(struct rblkdev *rblk, const char *path)
 {
-	struct rblkdev *rblk = &minors[minor(dev)];
 	int error, fd;
 
-	if (rblk->rblk_path == NULL)
-		return ENXIO;
+	KASSERT(rblk->rblk_fd != -1);
+	fd = rumpuser_open(path, O_RDWR, &error);
+	if (error) {
+		fd = rumpuser_open(path, O_RDONLY, &error);
+		if (error)
+			return error;
+		rblk->rblk_mode = FREAD;
 
-	if (rblk->rblk_fd != -1)
-		return 0; /* XXX: refcount, open mode */
-	flag &= ~O_TRUNC;
-	fd = rumpuser_open(rblk->rblk_path, OFLAGS(flag), &error);
-	if (error)
-		return error;
+#ifdef HAS_ODIRECT
+		rblk->rblk_dfd = rumpuser_open(path,
+		    O_RDONLY | O_DIRECT, &error);
+		if (error) {
+			close(fd);
+			return error;
+		}
+#endif
+	} else {
+		rblk->rblk_mode = FREAD|FWRITE;
 
 #ifdef HAS_ODIRECT
-	rblk->rblk_dfd = rumpuser_open(rblk->rblk_path,
-	    OFLAGS(flag) | O_DIRECT, &error);
-	if (error)
-		return error;
+		rblk->rblk_dfd = rumpuser_open(path,
+		    O_RDWR | O_DIRECT, &error);
+		if (error) {
+			close(fd);
+			return error;
+		}
 #endif
+	}
 
 	if (rblk->rblk_ftype == RUMPUSER_FT_REG) {
-		uint64_t fsize = rblk->rblk_size, off = rblk->rblk_hostoffset;
+		uint64_t fsize= rblk->rblk_hostsize, off= rblk->rblk_hostoffset;
 		struct blkwin *win;
 		int i, winsize;
 
@@ -510,9 +542,9 @@
 		 */
 
 		rblk->rblk_mmflags = 0;
-		if (flag & FREAD)
+		if (rblk->rblk_mode & FREAD)
 			rblk->rblk_mmflags |= RUMPUSER_FILEMMAP_READ;
-		if (flag & FWRITE) {
+		if (rblk->rblk_mode & FWRITE) {
 			rblk->rblk_mmflags |= RUMPUSER_FILEMMAP_WRITE;
 			rblk->rblk_mmflags |= RUMPUSER_FILEMMAP_SHARED;
 		}
@@ -548,10 +580,9 @@
 	return 0;
 }
 
-int
-rumpblk_close(dev_t dev, int flag, int fmt, struct lwp *l)
+static int
+backend_close(struct rblkdev *rblk)
 {
-	struct rblkdev *rblk = &minors[minor(dev)];
 	int dummy;
 
 	if (rblk->rblk_mmflags)
@@ -559,6 +590,34 @@
 	rumpuser_fsync(rblk->rblk_fd, &dummy);
 	rumpuser_close(rblk->rblk_fd, &dummy);
 	rblk->rblk_fd = -1;
+#ifdef HAS_ODIRECT
+	if (rblk->rblk_dfd != -1) {
+		rumpuser_close(rblk->rblk_dfd, &dummy);
+		rblk->rblk_dfd = -1;
+	}
+#endif
+
+	return 0;
+}
+
+int
+rumpblk_open(dev_t dev, int flag, int fmt, struct lwp *l)
+{
+	struct rblkdev *rblk = &minors[minor(dev)];
+
+	if (rblk->rblk_fd == -1)
+		return ENXIO;
+
+	if (((flag & (FREAD|FWRITE)) & ~rblk->rblk_mode) != 0) {
+		return EACCES;
+	}
+
+	return 0;
+}
+
+int
+rumpblk_close(dev_t dev, int flag, int fmt, struct lwp *l)
+{
 
 	return 0;
 }

Reply via email to