Tue Jun 15 18:53:48 2010 UTC ()
Implement rumpblk_deregister, for unregistering fake block devices
(from etfs_deregister).  Prompted by use case from njoly.


(pooka)
diff -r1.12 -r1.13 src/sys/rump/librump/rumpvfs/rump_vfs_private.h
diff -r1.39 -r1.40 src/sys/rump/librump/rumpvfs/rumpblk.c
diff -r1.52 -r1.53 src/sys/rump/librump/rumpvfs/rumpfs.c

cvs diff -r1.12 -r1.13 src/sys/rump/librump/rumpvfs/rump_vfs_private.h (expand / switch to unified diff)

--- src/sys/rump/librump/rumpvfs/rump_vfs_private.h 2010/04/30 21:02:36 1.12
+++ src/sys/rump/librump/rumpvfs/rump_vfs_private.h 2010/06/15 18:53:48 1.13
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rump_vfs_private.h,v 1.12 2010/04/30 21:02:36 pooka Exp $ */ 1/* $NetBSD: rump_vfs_private.h,v 1.13 2010/06/15 18:53:48 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2008 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -31,26 +31,27 @@ @@ -31,26 +31,27 @@
31#include <sys/types.h> 31#include <sys/types.h>
32#include <sys/conf.h> 32#include <sys/conf.h>
33 33
34void rump_vfs_init(void); 34void rump_vfs_init(void);
35void rump_vfs_fini(void); 35void rump_vfs_fini(void);
36 36
37void rumpfs_init(void); 37void rumpfs_init(void);
38 38
39int rump_devnull_init(void); 39int rump_devnull_init(void);
40 40
41#define RUMPBLK_DEVMAJOR 197 /* from conf/majors, XXX: not via config yet */ 41#define RUMPBLK_DEVMAJOR 197 /* from conf/majors, XXX: not via config yet */
42#define RUMPBLK_SIZENOTSET ((uint64_t)-1) 42#define RUMPBLK_SIZENOTSET ((uint64_t)-1)
43int rumpblk_register(const char *, devminor_t *, uint64_t, uint64_t); 43int rumpblk_register(const char *, devminor_t *, uint64_t, uint64_t);
 44int rumpblk_deregister(const char *);
44int rumpblk_init(void); 45int rumpblk_init(void);
45 46
46void rump_biodone(void *, size_t, int); 47void rump_biodone(void *, size_t, int);
47 48
48int rump_vfs_makeonedevnode(dev_t, const char *, devmajor_t, devminor_t); 49int rump_vfs_makeonedevnode(dev_t, const char *, devmajor_t, devminor_t);
49int rump_vfs_makedevnodes(dev_t, const char *, char, 50int rump_vfs_makedevnodes(dev_t, const char *, char,
50 devmajor_t, devminor_t, int); 51 devmajor_t, devminor_t, int);
51void rump_vfs_builddevs(struct devsw_conv *, size_t numelem); 52void rump_vfs_builddevs(struct devsw_conv *, size_t numelem);
52 53
53#include <sys/mount.h> 54#include <sys/mount.h>
54#include <sys/vnode.h> 55#include <sys/vnode.h>
55#include <rump/rump.h> 56#include <rump/rump.h>
56 57

cvs diff -r1.39 -r1.40 src/sys/rump/librump/rumpvfs/rumpblk.c (expand / switch to unified diff)

--- src/sys/rump/librump/rumpvfs/rumpblk.c 2010/05/01 14:37:53 1.39
+++ src/sys/rump/librump/rumpvfs/rumpblk.c 2010/06/15 18:53:48 1.40
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rumpblk.c,v 1.39 2010/05/01 14:37:53 pooka Exp $ */ 1/* $NetBSD: rumpblk.c,v 1.40 2010/06/15 18:53:48 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2009 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2009 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by the 6 * Development of this software was supported by the
7 * Finnish Cultural Foundation. 7 * Finnish Cultural Foundation.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -42,27 +42,27 @@ @@ -42,27 +42,27 @@
42 * we get way less carnage. 42 * we get way less carnage.
43 * 43 *
44 * However, it is quite costly in writing large amounts of 44 * However, it is quite costly in writing large amounts of
45 * file data, since old contents cannot merely be overwritten, but 45 * file data, since old contents cannot merely be overwritten, but
46 * must be paged in first before replacing (i.e. r/m/w). Ideally, 46 * must be paged in first before replacing (i.e. r/m/w). Ideally,
47 * we should use directio. The problem is that directio can fail 47 * we should use directio. The problem is that directio can fail
48 * silently causing improper file system semantics (i.e. unflushed 48 * silently causing improper file system semantics (i.e. unflushed
49 * data). Therefore, default to mmap for now. Even so, directio 49 * data). Therefore, default to mmap for now. Even so, directio
50 * _should_ be safe and can be enabled by compiling this module 50 * _should_ be safe and can be enabled by compiling this module
51 * with -DHAS_DIRECTIO. 51 * with -DHAS_DIRECTIO.
52 */ 52 */
53 53
54#include <sys/cdefs.h> 54#include <sys/cdefs.h>
55__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.39 2010/05/01 14:37:53 pooka Exp $"); 55__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.40 2010/06/15 18:53:48 pooka Exp $");
56 56
57#include <sys/param.h> 57#include <sys/param.h>
58#include <sys/buf.h> 58#include <sys/buf.h>
59#include <sys/conf.h> 59#include <sys/conf.h>
60#include <sys/condvar.h> 60#include <sys/condvar.h>
61#include <sys/disklabel.h> 61#include <sys/disklabel.h>
62#include <sys/evcnt.h> 62#include <sys/evcnt.h>
63#include <sys/fcntl.h> 63#include <sys/fcntl.h>
64#include <sys/kmem.h> 64#include <sys/kmem.h>
65#include <sys/malloc.h> 65#include <sys/malloc.h>
66#include <sys/queue.h> 66#include <sys/queue.h>
67#include <sys/stat.h> 67#include <sys/stat.h>
68 68
@@ -374,27 +374,26 @@ rumpblk_init(void) @@ -374,27 +374,26 @@ rumpblk_init(void)
374 "rumpblk", "all windows busy"); 374 "rumpblk", "all windows busy");
375 375
376 if (blkfail) { 376 if (blkfail) {
377 return devsw_attach("rumpblk", 377 return devsw_attach("rumpblk",
378 &rumpblk_bdevsw_fail, &rumpblkmaj, 378 &rumpblk_bdevsw_fail, &rumpblkmaj,
379 &rumpblk_cdevsw, &rumpblkmaj); 379 &rumpblk_cdevsw, &rumpblkmaj);
380 } else { 380 } else {
381 return devsw_attach("rumpblk", 381 return devsw_attach("rumpblk",
382 &rumpblk_bdevsw, &rumpblkmaj, 382 &rumpblk_bdevsw, &rumpblkmaj,
383 &rumpblk_cdevsw, &rumpblkmaj); 383 &rumpblk_cdevsw, &rumpblkmaj);
384 } 384 }
385} 385}
386 386
387/* XXX: no deregister */ 
388int 387int
389rumpblk_register(const char *path, devminor_t *dmin, 388rumpblk_register(const char *path, devminor_t *dmin,
390 uint64_t offset, uint64_t size) 389 uint64_t offset, uint64_t size)
391{ 390{
392 struct rblkdev *rblk; 391 struct rblkdev *rblk;
393 uint64_t flen; 392 uint64_t flen;
394 size_t len; 393 size_t len;
395 int ftype, error, i; 394 int ftype, error, i;
396 395
397 /* devices might not report correct size unless they're open */ 396 /* devices might not report correct size unless they're open */
398 if (rumpuser_getfileinfo(path, &flen, &ftype, &error) == -1) 397 if (rumpuser_getfileinfo(path, &flen, &ftype, &error) == -1)
399 return error; 398 return error;
400 399
@@ -432,26 +431,59 @@ rumpblk_register(const char *path, devmi @@ -432,26 +431,59 @@ rumpblk_register(const char *path, devmi
432 rblk->rblk_size = size; 431 rblk->rblk_size = size;
433 } else { 432 } else {
434 KASSERT(offset < flen); 433 KASSERT(offset < flen);
435 rblk->rblk_size = flen - offset; 434 rblk->rblk_size = flen - offset;
436 } 435 }
437 rblk->rblk_ftype = ftype; 436 rblk->rblk_ftype = ftype;
438 makedefaultlabel(&rblk->rblk_label, rblk->rblk_size, i); 437 makedefaultlabel(&rblk->rblk_label, rblk->rblk_size, i);
439 mutex_exit(&rumpblk_lock); 438 mutex_exit(&rumpblk_lock);
440 439
441 *dmin = i; 440 *dmin = i;
442 return 0; 441 return 0;
443} 442}
444 443
 444/*
 445 * Unregister rumpblk. It's the callers responsibility to make
 446 * sure it's no longer in use.
 447 */
 448int
 449rumpblk_deregister(const char *path)
 450{
 451 struct rblkdev *rblk;
 452 int i;
 453
 454 mutex_enter(&rumpblk_lock);
 455 for (i = 0; i < RUMPBLK_SIZE; i++) {
 456 if (minors[i].rblk_path&&strcmp(minors[i].rblk_path, path)==0) {
 457 break;
 458 }
 459 }
 460 mutex_exit(&rumpblk_lock);
 461
 462 if (i == RUMPBLK_SIZE)
 463 return ENOENT;
 464
 465 rblk = &minors[i];
 466 KASSERT(rblk->rblk_fd == -1);
 467 KASSERT(rblk->rblk_opencnt == 0);
 468
 469 wincleanup(rblk);
 470 free(rblk->rblk_path, M_TEMP);
 471 rblk->rblk_path = NULL;
 472 memset(&rblk->rblk_label, 0, sizeof(rblk->rblk_label));
 473
 474 return 0;
 475}
 476
445int 477int
446rumpblk_open(dev_t dev, int flag, int fmt, struct lwp *l) 478rumpblk_open(dev_t dev, int flag, int fmt, struct lwp *l)
447{ 479{
448 struct rblkdev *rblk = &minors[minor(dev)]; 480 struct rblkdev *rblk = &minors[minor(dev)];
449 int error, fd; 481 int error, fd;
450 482
451 if (rblk->rblk_path == NULL) 483 if (rblk->rblk_path == NULL)
452 return ENXIO; 484 return ENXIO;
453 485
454 if (rblk->rblk_fd != -1) 486 if (rblk->rblk_fd != -1)
455 return 0; /* XXX: refcount, open mode */ 487 return 0; /* XXX: refcount, open mode */
456 fd = rumpuser_open(rblk->rblk_path, OFLAGS(flag), &error); 488 fd = rumpuser_open(rblk->rblk_path, OFLAGS(flag), &error);
457 if (error) 489 if (error)

cvs diff -r1.52 -r1.53 src/sys/rump/librump/rumpvfs/rumpfs.c (expand / switch to unified diff)

--- src/sys/rump/librump/rumpvfs/rumpfs.c 2010/06/15 17:23:31 1.52
+++ src/sys/rump/librump/rumpvfs/rumpfs.c 2010/06/15 18:53:48 1.53
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rumpfs.c,v 1.52 2010/06/15 17:23:31 njoly Exp $ */ 1/* $NetBSD: rumpfs.c,v 1.53 2010/06/15 18:53:48 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2009 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2009 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -16,27 +16,27 @@ @@ -16,27 +16,27 @@
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE. 25 * SUCH DAMAGE.
26 */ 26 */
27 27
28#include <sys/cdefs.h> 28#include <sys/cdefs.h>
29__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.52 2010/06/15 17:23:31 njoly Exp $"); 29__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.53 2010/06/15 18:53:48 pooka Exp $");
30 30
31#include <sys/param.h> 31#include <sys/param.h>
32#include <sys/atomic.h> 32#include <sys/atomic.h>
33#include <sys/dirent.h> 33#include <sys/dirent.h>
34#include <sys/errno.h> 34#include <sys/errno.h>
35#include <sys/filedesc.h> 35#include <sys/filedesc.h>
36#include <sys/fcntl.h> 36#include <sys/fcntl.h>
37#include <sys/kauth.h> 37#include <sys/kauth.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/module.h> 39#include <sys/module.h>
40#include <sys/mount.h> 40#include <sys/mount.h>
41#include <sys/namei.h> 41#include <sys/namei.h>
42#include <sys/lock.h> 42#include <sys/lock.h>
@@ -162,26 +162,28 @@ static struct rumpfs_node *makeprivate(e @@ -162,26 +162,28 @@ static struct rumpfs_node *makeprivate(e
162 162
163/* 163/*
164 * Extra Terrestrial stuff. We map a given key (pathname) to a file on 164 * Extra Terrestrial stuff. We map a given key (pathname) to a file on
165 * the host FS. ET phones home only from the root node of rumpfs. 165 * the host FS. ET phones home only from the root node of rumpfs.
166 * 166 *
167 * When an etfs node is removed, a vnode potentially behind it is not 167 * When an etfs node is removed, a vnode potentially behind it is not
168 * immediately recycled. 168 * immediately recycled.
169 */ 169 */
170 170
171struct etfs { 171struct etfs {
172 char et_key[MAXPATHLEN]; 172 char et_key[MAXPATHLEN];
173 size_t et_keylen; 173 size_t et_keylen;
174 bool et_prefixkey; 174 bool et_prefixkey;
 175 bool et_removing;
 176 devminor_t et_blkmin;
175 177
176 LIST_ENTRY(etfs) et_entries; 178 LIST_ENTRY(etfs) et_entries;
177 179
178 struct rumpfs_node *et_rn; 180 struct rumpfs_node *et_rn;
179}; 181};
180static kmutex_t etfs_lock; 182static kmutex_t etfs_lock;
181static LIST_HEAD(, etfs) etfs_list = LIST_HEAD_INITIALIZER(etfs_list); 183static LIST_HEAD(, etfs) etfs_list = LIST_HEAD_INITIALIZER(etfs_list);
182 184
183static enum vtype 185static enum vtype
184ettype_to_vtype(enum rump_etfs_type et) 186ettype_to_vtype(enum rump_etfs_type et)
185{ 187{
186 enum vtype vt; 188 enum vtype vt;
187 189
@@ -257,27 +259,27 @@ etfs_find(const char *key, struct etfs * @@ -257,27 +259,27 @@ etfs_find(const char *key, struct etfs *
257 return false; 259 return false;
258} 260}
259 261
260#define REGDIR(ftype) \ 262#define REGDIR(ftype) \
261 ((ftype) == RUMP_ETFS_DIR || (ftype) == RUMP_ETFS_DIR_SUBDIRS) 263 ((ftype) == RUMP_ETFS_DIR || (ftype) == RUMP_ETFS_DIR_SUBDIRS)
262static int 264static int
263doregister(const char *key, const char *hostpath,  265doregister(const char *key, const char *hostpath,
264 enum rump_etfs_type ftype, uint64_t begin, uint64_t size) 266 enum rump_etfs_type ftype, uint64_t begin, uint64_t size)
265{ 267{
266 struct etfs *et; 268 struct etfs *et;
267 struct rumpfs_node *rn; 269 struct rumpfs_node *rn;
268 uint64_t fsize; 270 uint64_t fsize;
269 dev_t rdev = NODEV; 271 dev_t rdev = NODEV;
270 devminor_t dmin; 272 devminor_t dmin = -1;
271 int hft, error; 273 int hft, error;
272 274
273 if (rumpuser_getfileinfo(hostpath, &fsize, &hft, &error)) 275 if (rumpuser_getfileinfo(hostpath, &fsize, &hft, &error))
274 return error; 276 return error;
275 277
276 /* etfs directory requires a directory on the host */ 278 /* etfs directory requires a directory on the host */
277 if (REGDIR(ftype)) { 279 if (REGDIR(ftype)) {
278 if (hft != RUMPUSER_FT_DIR) 280 if (hft != RUMPUSER_FT_DIR)
279 return ENOTDIR; 281 return ENOTDIR;
280 if (begin != 0) 282 if (begin != 0)
281 return EISDIR; 283 return EISDIR;
282 if (size != RUMP_ETFS_SIZE_ENDOFF) 284 if (size != RUMP_ETFS_SIZE_ENDOFF)
283 return EISDIR; 285 return EISDIR;
@@ -293,53 +295,56 @@ doregister(const char *key, const char * @@ -293,53 +295,56 @@ doregister(const char *key, const char *
293 295
294 if (ftype == RUMP_ETFS_BLK || ftype == RUMP_ETFS_CHR) { 296 if (ftype == RUMP_ETFS_BLK || ftype == RUMP_ETFS_CHR) {
295 error = rumpblk_register(hostpath, &dmin, begin, size); 297 error = rumpblk_register(hostpath, &dmin, begin, size);
296 if (error != 0) { 298 if (error != 0) {
297 return error; 299 return error;
298 } 300 }
299 rdev = makedev(RUMPBLK_DEVMAJOR, dmin); 301 rdev = makedev(RUMPBLK_DEVMAJOR, dmin);
300 } 302 }
301 303
302 et = kmem_alloc(sizeof(*et), KM_SLEEP); 304 et = kmem_alloc(sizeof(*et), KM_SLEEP);
303 strcpy(et->et_key, key); 305 strcpy(et->et_key, key);
304 et->et_keylen = strlen(et->et_key); 306 et->et_keylen = strlen(et->et_key);
305 et->et_rn = rn = makeprivate(ettype_to_vtype(ftype), rdev, size); 307 et->et_rn = rn = makeprivate(ettype_to_vtype(ftype), rdev, size);
 308 et->et_removing = false;
 309 et->et_blkmin = dmin;
306 310
307 if (ftype == RUMP_ETFS_REG || REGDIR(ftype)) { 311 if (ftype == RUMP_ETFS_REG || REGDIR(ftype) || et->et_blkmin != -1) {
308 size_t len = strlen(hostpath)+1; 312 size_t len = strlen(hostpath)+1;
309 313
310 rn->rn_hostpath = malloc(len, M_TEMP, M_WAITOK | M_ZERO); 314 rn->rn_hostpath = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
311 memcpy(rn->rn_hostpath, hostpath, len); 315 memcpy(rn->rn_hostpath, hostpath, len);
312 rn->rn_offset = begin; 316 rn->rn_offset = begin;
313 } 317 }
314 318
315 if (REGDIR(ftype)) { 319 if (REGDIR(ftype)) {
316 rn->rn_flags |= RUMPNODE_DIR_ET; 320 rn->rn_flags |= RUMPNODE_DIR_ET;
317 et->et_prefixkey = true; 321 et->et_prefixkey = true;
318 } else { 322 } else {
319 et->et_prefixkey = false; 323 et->et_prefixkey = false;
320 } 324 }
321 325
322 if (ftype == RUMP_ETFS_DIR_SUBDIRS) 326 if (ftype == RUMP_ETFS_DIR_SUBDIRS)
323 rn->rn_flags |= RUMPNODE_DIR_ETSUBS; 327 rn->rn_flags |= RUMPNODE_DIR_ETSUBS;
324 328
325 mutex_enter(&etfs_lock); 329 mutex_enter(&etfs_lock);
326 if (etfs_find(key, NULL, REGDIR(ftype))) { 330 if (etfs_find(key, NULL, REGDIR(ftype))) {
327 mutex_exit(&etfs_lock); 331 mutex_exit(&etfs_lock);
 332 if (et->et_blkmin != -1)
 333 rumpblk_deregister(hostpath);
328 if (et->et_rn->rn_hostpath != NULL) 334 if (et->et_rn->rn_hostpath != NULL)
329 free(et->et_rn->rn_hostpath, M_TEMP); 335 free(et->et_rn->rn_hostpath, M_TEMP);
330 kmem_free(et->et_rn, sizeof(*et->et_rn)); 336 kmem_free(et->et_rn, sizeof(*et->et_rn));
331 kmem_free(et, sizeof(*et)); 337 kmem_free(et, sizeof(*et));
332 /* XXX: rumpblk_deregister(hostpath); */ 
333 return EEXIST; 338 return EEXIST;
334 } 339 }
335 LIST_INSERT_HEAD(&etfs_list, et, et_entries); 340 LIST_INSERT_HEAD(&etfs_list, et, et_entries);
336 mutex_exit(&etfs_lock); 341 mutex_exit(&etfs_lock);
337 342
338 return 0; 343 return 0;
339} 344}
340#undef REGDIR 345#undef REGDIR
341 346
342int 347int
343rump_etfs_register(const char *key, const char *hostpath, 348rump_etfs_register(const char *key, const char *hostpath,
344 enum rump_etfs_type ftype) 349 enum rump_etfs_type ftype)
345{ 350{
@@ -356,47 +361,73 @@ rump_etfs_register_withsize(const char * @@ -356,47 +361,73 @@ rump_etfs_register_withsize(const char *
356 * Check that we're mapping at block offsets. I guess this 361 * Check that we're mapping at block offsets. I guess this
357 * is not technically necessary except for BLK/CHR backends 362 * is not technically necessary except for BLK/CHR backends
358 * (i.e. what getfileinfo() returns, not ftype) and can be 363 * (i.e. what getfileinfo() returns, not ftype) and can be
359 * removed later if there are problems. 364 * removed later if there are problems.
360 */ 365 */
361 if ((begin & (DEV_BSIZE-1)) != 0) 366 if ((begin & (DEV_BSIZE-1)) != 0)
362 return EINVAL; 367 return EINVAL;
363 if (size != RUMP_ETFS_SIZE_ENDOFF && (size & (DEV_BSIZE-1)) != 0) 368 if (size != RUMP_ETFS_SIZE_ENDOFF && (size & (DEV_BSIZE-1)) != 0)
364 return EINVAL; 369 return EINVAL;
365 370
366 return doregister(key, hostpath, ftype, begin, size); 371 return doregister(key, hostpath, ftype, begin, size);
367} 372}
368 373
 374/* remove etfs mapping. caller's responsibility to make sure it's not in use */
369int 375int
370rump_etfs_remove(const char *key) 376rump_etfs_remove(const char *key)
371{ 377{
372 struct etfs *et; 378 struct etfs *et;
373 size_t keylen = strlen(key); 379 size_t keylen = strlen(key);
 380 int rv;
374 381
375 mutex_enter(&etfs_lock); 382 mutex_enter(&etfs_lock);
376 LIST_FOREACH(et, &etfs_list, et_entries) { 383 LIST_FOREACH(et, &etfs_list, et_entries) {
377 if (keylen == et->et_keylen && strcmp(et->et_key, key) == 0) { 384 if (keylen == et->et_keylen && strcmp(et->et_key, key) == 0) {
378 LIST_REMOVE(et, et_entries); 385 if (et->et_removing)
379 if (et->et_rn->rn_hostpath != NULL) 386 et = NULL;
380 free(et->et_rn->rn_hostpath, M_TEMP); 387 else
381 kmem_free(et->et_rn, sizeof(*et->et_rn)); 388 et->et_removing = true;
382 kmem_free(et, sizeof(*et)); 
383 break; 389 break;
384 } 390 }
385 } 391 }
386 mutex_exit(&etfs_lock); 392 mutex_exit(&etfs_lock);
387 
388 if (!et) 393 if (!et)
389 return ENOENT; 394 return ENOENT;
 395
 396 /*
 397 * ok, we know what we want to remove and have signalled there
 398 * actually are men at work. first, unregister from rumpblk
 399 */
 400 if (et->et_blkmin != -1) {
 401 rv = rumpblk_deregister(et->et_rn->rn_hostpath);
 402 } else {
 403 rv = 0;
 404 }
 405 KASSERT(rv == 0);
 406
 407 /* then do the actual removal */
 408 mutex_enter(&etfs_lock);
 409 LIST_REMOVE(et, et_entries);
 410 mutex_exit(&etfs_lock);
 411
 412 /* node is unreachable, safe to nuke all device copies */
 413 if (et->et_blkmin != -1)
 414 vdevgone(RUMPBLK_DEVMAJOR, et->et_blkmin, et->et_blkmin, VBLK);
 415
 416 if (et->et_rn->rn_hostpath != NULL)
 417 free(et->et_rn->rn_hostpath, M_TEMP);
 418 kmem_free(et->et_rn, sizeof(*et->et_rn));
 419 kmem_free(et, sizeof(*et));
 420
390 return 0; 421 return 0;
391} 422}
392 423
393/* 424/*
394 * rumpfs 425 * rumpfs
395 */ 426 */
396 427
397static int lastino = 1; 428static int lastino = 1;
398static kmutex_t reclock; 429static kmutex_t reclock;
399 430
400static struct rumpfs_node * 431static struct rumpfs_node *
401makeprivate(enum vtype vt, dev_t rdev, off_t size) 432makeprivate(enum vtype vt, dev_t rdev, off_t size)
402{ 433{