Implement rumpblk_deregister, for unregistering fake block devices
(from etfs_deregister). Prompted by use case from njoly.
This commit is contained in:
parent
eb8e417a7b
commit
28e6724056
|
@ -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);
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/param.h>
|
||||
#include <sys/buf.h>
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/param.h>
|
||||
#include <sys/atomic.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue