diff --git a/sys/rump/librump/rumpvfs/rump_vfs_private.h b/sys/rump/librump/rumpvfs/rump_vfs_private.h index 3ff67251049d..1fcdb84e96c3 100644 --- a/sys/rump/librump/rumpvfs/rump_vfs_private.h +++ b/sys/rump/librump/rumpvfs/rump_vfs_private.h @@ -1,4 +1,4 @@ -/* $NetBSD: rump_vfs_private.h,v 1.12 2010/04/30 21:02:36 pooka Exp $ */ +/* $NetBSD: rump_vfs_private.h,v 1.13 2010/06/15 18:53:48 pooka Exp $ */ /* * Copyright (c) 2008 Antti Kantee. All Rights Reserved. @@ -41,6 +41,7 @@ int rump_devnull_init(void); #define RUMPBLK_DEVMAJOR 197 /* from conf/majors, XXX: not via config yet */ #define RUMPBLK_SIZENOTSET ((uint64_t)-1) int rumpblk_register(const char *, devminor_t *, uint64_t, uint64_t); +int rumpblk_deregister(const char *); int rumpblk_init(void); void rump_biodone(void *, size_t, int); diff --git a/sys/rump/librump/rumpvfs/rumpblk.c b/sys/rump/librump/rumpvfs/rumpblk.c index a41fc7207f02..2fc614a2af76 100644 --- a/sys/rump/librump/rumpvfs/rumpblk.c +++ b/sys/rump/librump/rumpvfs/rumpblk.c @@ -1,4 +1,4 @@ -/* $NetBSD: rumpblk.c,v 1.39 2010/05/01 14:37:53 pooka Exp $ */ +/* $NetBSD: rumpblk.c,v 1.40 2010/06/15 18:53:48 pooka Exp $ */ /* * Copyright (c) 2009 Antti Kantee. All Rights Reserved. @@ -52,7 +52,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.39 2010/05/01 14:37:53 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.40 2010/06/15 18:53:48 pooka Exp $"); #include #include @@ -384,7 +384,6 @@ rumpblk_init(void) } } -/* XXX: no deregister */ int rumpblk_register(const char *path, devminor_t *dmin, uint64_t offset, uint64_t size) @@ -442,6 +441,39 @@ rumpblk_register(const char *path, devminor_t *dmin, return 0; } +/* + * Unregister rumpblk. It's the callers responsibility to make + * sure it's no longer in use. + */ +int +rumpblk_deregister(const char *path) +{ + struct rblkdev *rblk; + int i; + + mutex_enter(&rumpblk_lock); + for (i = 0; i < RUMPBLK_SIZE; i++) { + if (minors[i].rblk_path&&strcmp(minors[i].rblk_path, path)==0) { + break; + } + } + mutex_exit(&rumpblk_lock); + + if (i == RUMPBLK_SIZE) + return ENOENT; + + rblk = &minors[i]; + KASSERT(rblk->rblk_fd == -1); + KASSERT(rblk->rblk_opencnt == 0); + + wincleanup(rblk); + free(rblk->rblk_path, M_TEMP); + rblk->rblk_path = NULL; + memset(&rblk->rblk_label, 0, sizeof(rblk->rblk_label)); + + return 0; +} + int rumpblk_open(dev_t dev, int flag, int fmt, struct lwp *l) { diff --git a/sys/rump/librump/rumpvfs/rumpfs.c b/sys/rump/librump/rumpvfs/rumpfs.c index c5ac6d76b284..8561c9d4e0ff 100644 --- a/sys/rump/librump/rumpvfs/rumpfs.c +++ b/sys/rump/librump/rumpvfs/rumpfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: rumpfs.c,v 1.52 2010/06/15 17:23:31 njoly Exp $ */ +/* $NetBSD: rumpfs.c,v 1.53 2010/06/15 18:53:48 pooka Exp $ */ /* * Copyright (c) 2009 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.52 2010/06/15 17:23:31 njoly Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.53 2010/06/15 18:53:48 pooka Exp $"); #include #include @@ -172,6 +172,8 @@ struct etfs { char et_key[MAXPATHLEN]; size_t et_keylen; bool et_prefixkey; + bool et_removing; + devminor_t et_blkmin; LIST_ENTRY(etfs) et_entries; @@ -267,7 +269,7 @@ doregister(const char *key, const char *hostpath, struct rumpfs_node *rn; uint64_t fsize; dev_t rdev = NODEV; - devminor_t dmin; + devminor_t dmin = -1; int hft, error; if (rumpuser_getfileinfo(hostpath, &fsize, &hft, &error)) @@ -303,8 +305,10 @@ doregister(const char *key, const char *hostpath, strcpy(et->et_key, key); et->et_keylen = strlen(et->et_key); et->et_rn = rn = makeprivate(ettype_to_vtype(ftype), rdev, size); + et->et_removing = false; + et->et_blkmin = dmin; - if (ftype == RUMP_ETFS_REG || REGDIR(ftype)) { + if (ftype == RUMP_ETFS_REG || REGDIR(ftype) || et->et_blkmin != -1) { size_t len = strlen(hostpath)+1; rn->rn_hostpath = malloc(len, M_TEMP, M_WAITOK | M_ZERO); @@ -325,11 +329,12 @@ doregister(const char *key, const char *hostpath, mutex_enter(&etfs_lock); if (etfs_find(key, NULL, REGDIR(ftype))) { mutex_exit(&etfs_lock); + if (et->et_blkmin != -1) + rumpblk_deregister(hostpath); if (et->et_rn->rn_hostpath != NULL) free(et->et_rn->rn_hostpath, M_TEMP); kmem_free(et->et_rn, sizeof(*et->et_rn)); kmem_free(et, sizeof(*et)); - /* XXX: rumpblk_deregister(hostpath); */ return EEXIST; } LIST_INSERT_HEAD(&etfs_list, et, et_entries); @@ -366,27 +371,53 @@ rump_etfs_register_withsize(const char *key, const char *hostpath, return doregister(key, hostpath, ftype, begin, size); } +/* remove etfs mapping. caller's responsibility to make sure it's not in use */ int rump_etfs_remove(const char *key) { struct etfs *et; size_t keylen = strlen(key); + int rv; mutex_enter(&etfs_lock); LIST_FOREACH(et, &etfs_list, et_entries) { if (keylen == et->et_keylen && strcmp(et->et_key, key) == 0) { - LIST_REMOVE(et, et_entries); - if (et->et_rn->rn_hostpath != NULL) - free(et->et_rn->rn_hostpath, M_TEMP); - kmem_free(et->et_rn, sizeof(*et->et_rn)); - kmem_free(et, sizeof(*et)); + if (et->et_removing) + et = NULL; + else + et->et_removing = true; break; } } mutex_exit(&etfs_lock); - if (!et) return ENOENT; + + /* + * ok, we know what we want to remove and have signalled there + * actually are men at work. first, unregister from rumpblk + */ + if (et->et_blkmin != -1) { + rv = rumpblk_deregister(et->et_rn->rn_hostpath); + } else { + rv = 0; + } + KASSERT(rv == 0); + + /* then do the actual removal */ + mutex_enter(&etfs_lock); + LIST_REMOVE(et, et_entries); + mutex_exit(&etfs_lock); + + /* node is unreachable, safe to nuke all device copies */ + if (et->et_blkmin != -1) + vdevgone(RUMPBLK_DEVMAJOR, et->et_blkmin, et->et_blkmin, VBLK); + + if (et->et_rn->rn_hostpath != NULL) + free(et->et_rn->rn_hostpath, M_TEMP); + kmem_free(et->et_rn, sizeof(*et->et_rn)); + kmem_free(et, sizeof(*et)); + return 0; }