Add a PUFFS_UNMOUNT server->kernel request, which causes the kernel
to initiate self destruct, i.e. unmount(MNT_FORCE). This, however, is a semi-controlled self-destruct, since all caches are flushed before the (possibly) violent unmount takes place.
This commit is contained in:
parent
e9d13d47e1
commit
d728f5380d
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: puffs_msgif.c,v 1.76 2009/12/07 20:57:55 pooka Exp $ */
|
/* $NetBSD: puffs_msgif.c,v 1.77 2010/01/07 22:45:31 pooka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved.
|
* Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved.
|
||||||
@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.76 2009/12/07 20:57:55 pooka Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.77 2010/01/07 22:45:31 pooka Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/atomic.h>
|
#include <sys/atomic.h>
|
||||||
@ -855,6 +855,7 @@ puffs_msgif_dispatch(void *this, struct putter_hdr *pth)
|
|||||||
DPRINTF(("dispatch: vn/vfs message 0x%x\n", preq->preq_optype));
|
DPRINTF(("dispatch: vn/vfs message 0x%x\n", preq->preq_optype));
|
||||||
puffsop_msg(pmp, preq);
|
puffsop_msg(pmp, preq);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUFFSOP_FLUSH: /* process in sop thread */
|
case PUFFSOP_FLUSH: /* process in sop thread */
|
||||||
{
|
{
|
||||||
struct puffs_flush *pf;
|
struct puffs_flush *pf;
|
||||||
@ -877,6 +878,23 @@ puffs_msgif_dispatch(void *this, struct putter_hdr *pth)
|
|||||||
mutex_exit(&pmp->pmp_sopmtx);
|
mutex_exit(&pmp->pmp_sopmtx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PUFFSOP_UNMOUNT: /* process in sop thread */
|
||||||
|
{
|
||||||
|
|
||||||
|
DPRINTF(("dispatch: unmount 0x%x\n", preq->preq_optype));
|
||||||
|
|
||||||
|
psopr = kmem_alloc(sizeof(*psopr), KM_SLEEP);
|
||||||
|
psopr->psopr_preq = *preq;
|
||||||
|
psopr->psopr_sopreq = PUFFS_SOPREQ_UNMOUNT;
|
||||||
|
|
||||||
|
mutex_enter(&pmp->pmp_sopmtx);
|
||||||
|
TAILQ_INSERT_TAIL(&pmp->pmp_sopreqs, psopr, psopr_entries);
|
||||||
|
cv_signal(&pmp->pmp_sopcv);
|
||||||
|
mutex_exit(&pmp->pmp_sopmtx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DPRINTF(("dispatch: invalid class 0x%x\n", preq->preq_opclass));
|
DPRINTF(("dispatch: invalid class 0x%x\n", preq->preq_opclass));
|
||||||
puffs_msg_sendresp(pmp, preq, EOPNOTSUPP);
|
puffs_msg_sendresp(pmp, preq, EOPNOTSUPP);
|
||||||
@ -897,8 +915,10 @@ void
|
|||||||
puffs_sop_thread(void *arg)
|
puffs_sop_thread(void *arg)
|
||||||
{
|
{
|
||||||
struct puffs_mount *pmp = arg;
|
struct puffs_mount *pmp = arg;
|
||||||
|
struct mount *mp = PMPTOMP(pmp);
|
||||||
struct puffs_sopreq *psopr;
|
struct puffs_sopreq *psopr;
|
||||||
bool keeprunning;
|
bool keeprunning;
|
||||||
|
bool unmountme = false;
|
||||||
|
|
||||||
mutex_enter(&pmp->pmp_sopmtx);
|
mutex_enter(&pmp->pmp_sopmtx);
|
||||||
for (keeprunning = true; keeprunning; ) {
|
for (keeprunning = true; keeprunning; ) {
|
||||||
@ -914,6 +934,18 @@ puffs_sop_thread(void *arg)
|
|||||||
case PUFFS_SOPREQ_FLUSH:
|
case PUFFS_SOPREQ_FLUSH:
|
||||||
puffsop_flush(pmp, &psopr->psopr_pf);
|
puffsop_flush(pmp, &psopr->psopr_pf);
|
||||||
break;
|
break;
|
||||||
|
case PUFFS_SOPREQ_UNMOUNT:
|
||||||
|
puffs_msg_sendresp(pmp, &sopreq->psopr_preq, 0);
|
||||||
|
|
||||||
|
unmountme = true;
|
||||||
|
keeprunning = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We know the mountpoint is still alive because
|
||||||
|
* the thread that is us (poetic?) is still alive.
|
||||||
|
*/
|
||||||
|
atomic_inc_uint((unsigned int*)&mp->mnt_refcnt);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
kmem_free(psopr, sizeof(*psopr));
|
kmem_free(psopr, sizeof(*psopr));
|
||||||
@ -921,8 +953,7 @@ puffs_sop_thread(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Purge remaining ops. could send error, but that is highly
|
* Purge remaining ops. could send error, but ...
|
||||||
* unlikely to reach the caller.
|
|
||||||
*/
|
*/
|
||||||
while ((psopr = TAILQ_FIRST(&pmp->pmp_sopreqs)) != NULL) {
|
while ((psopr = TAILQ_FIRST(&pmp->pmp_sopreqs)) != NULL) {
|
||||||
TAILQ_REMOVE(&pmp->pmp_sopreqs, psopr, psopr_entries);
|
TAILQ_REMOVE(&pmp->pmp_sopreqs, psopr, psopr_entries);
|
||||||
@ -932,9 +963,21 @@ puffs_sop_thread(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pmp->pmp_sopthrcount--;
|
pmp->pmp_sopthrcount--;
|
||||||
cv_signal(&pmp->pmp_sopcv);
|
cv_broadcast(&pmp->pmp_sopcv);
|
||||||
mutex_exit(&pmp->pmp_sopmtx); /* not allowed to access fs after this */
|
mutex_exit(&pmp->pmp_sopmtx); /* not allowed to access fs after this */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If unmount was requested, we can now safely do it here, since
|
||||||
|
* our context is dead from the point-of-view of puffs_unmount()
|
||||||
|
* and we are just another thread. dounmount() makes internally
|
||||||
|
* sure that VFS_UNMOUNT() isn't called reentrantly and that it
|
||||||
|
* is eventually completed.
|
||||||
|
*/
|
||||||
|
if (unmountme) {
|
||||||
|
(void)dounmount(mp, MNT_FORCE, curlwp);
|
||||||
|
vfs_destroy(mp);
|
||||||
|
}
|
||||||
|
|
||||||
kthread_exit(0);
|
kthread_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: puffs_msgif.h,v 1.68 2009/10/17 23:22:04 pooka Exp $ */
|
/* $NetBSD: puffs_msgif.h,v 1.69 2010/01/07 22:45:31 pooka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved.
|
* Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved.
|
||||||
@ -52,6 +52,7 @@
|
|||||||
#define PUFFSOP_ERROR 0x04 /* only kernel-> */
|
#define PUFFSOP_ERROR 0x04 /* only kernel-> */
|
||||||
#define PUFFSOP_FLUSH 0x05 /* ->kernel */
|
#define PUFFSOP_FLUSH 0x05 /* ->kernel */
|
||||||
#define PUFFSOP_SUSPEND 0x06 /* ->kernel */
|
#define PUFFSOP_SUSPEND 0x06 /* ->kernel */
|
||||||
|
#define PUFFSOP_UNMOUNT 0x07 /* ->kernel */
|
||||||
|
|
||||||
#define PUFFSOPFLAG_FAF 0x10 /* fire-and-forget */
|
#define PUFFSOPFLAG_FAF 0x10 /* fire-and-forget */
|
||||||
#define PUFFSOPFLAG_ISRESPONSE 0x20 /* req is actually a resp */
|
#define PUFFSOPFLAG_ISRESPONSE 0x20 /* req is actually a resp */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: puffs_sys.h,v 1.73 2009/12/07 20:57:55 pooka Exp $ */
|
/* $NetBSD: puffs_sys.h,v 1.74 2010/01/07 22:45:31 pooka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
|
* Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
|
||||||
@ -101,6 +101,7 @@ struct puffs_newcookie {
|
|||||||
enum puffs_sopreqtype {
|
enum puffs_sopreqtype {
|
||||||
PUFFS_SOPREQ_EXIT,
|
PUFFS_SOPREQ_EXIT,
|
||||||
PUFFS_SOPREQ_FLUSH,
|
PUFFS_SOPREQ_FLUSH,
|
||||||
|
PUFFS_SOPREQ_UNMOUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct puffs_sopreq {
|
struct puffs_sopreq {
|
||||||
|
Loading…
Reference in New Issue
Block a user