Module Name: src Committed By: pooka Date: Thu Jan 7 22:45:31 UTC 2010
Modified Files: src/sys/fs/puffs: puffs_msgif.c puffs_msgif.h puffs_sys.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.76 -r1.77 src/sys/fs/puffs/puffs_msgif.c cvs rdiff -u -r1.68 -r1.69 src/sys/fs/puffs/puffs_msgif.h cvs rdiff -u -r1.73 -r1.74 src/sys/fs/puffs/puffs_sys.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/fs/puffs/puffs_msgif.c diff -u src/sys/fs/puffs/puffs_msgif.c:1.76 src/sys/fs/puffs/puffs_msgif.c:1.77 --- src/sys/fs/puffs/puffs_msgif.c:1.76 Mon Dec 7 20:57:55 2009 +++ src/sys/fs/puffs/puffs_msgif.c Thu Jan 7 22:45:31 2010 @@ -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. @@ -30,7 +30,7 @@ */ #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/atomic.h> @@ -855,6 +855,7 @@ DPRINTF(("dispatch: vn/vfs message 0x%x\n", preq->preq_optype)); puffsop_msg(pmp, preq); break; + case PUFFSOP_FLUSH: /* process in sop thread */ { struct puffs_flush *pf; @@ -877,6 +878,23 @@ mutex_exit(&pmp->pmp_sopmtx); 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: DPRINTF(("dispatch: invalid class 0x%x\n", preq->preq_opclass)); puffs_msg_sendresp(pmp, preq, EOPNOTSUPP); @@ -897,8 +915,10 @@ puffs_sop_thread(void *arg) { struct puffs_mount *pmp = arg; + struct mount *mp = PMPTOMP(pmp); struct puffs_sopreq *psopr; bool keeprunning; + bool unmountme = false; mutex_enter(&pmp->pmp_sopmtx); for (keeprunning = true; keeprunning; ) { @@ -914,6 +934,18 @@ case PUFFS_SOPREQ_FLUSH: puffsop_flush(pmp, &psopr->psopr_pf); 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)); @@ -921,8 +953,7 @@ } /* - * Purge remaining ops. could send error, but that is highly - * unlikely to reach the caller. + * Purge remaining ops. could send error, but ... */ while ((psopr = TAILQ_FIRST(&pmp->pmp_sopreqs)) != NULL) { TAILQ_REMOVE(&pmp->pmp_sopreqs, psopr, psopr_entries); @@ -932,9 +963,21 @@ } 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 */ + /* + * 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); } Index: src/sys/fs/puffs/puffs_msgif.h diff -u src/sys/fs/puffs/puffs_msgif.h:1.68 src/sys/fs/puffs/puffs_msgif.h:1.69 --- src/sys/fs/puffs/puffs_msgif.h:1.68 Sat Oct 17 23:22:04 2009 +++ src/sys/fs/puffs/puffs_msgif.h Thu Jan 7 22:45:31 2010 @@ -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. @@ -52,6 +52,7 @@ #define PUFFSOP_ERROR 0x04 /* only kernel-> */ #define PUFFSOP_FLUSH 0x05 /* ->kernel */ #define PUFFSOP_SUSPEND 0x06 /* ->kernel */ +#define PUFFSOP_UNMOUNT 0x07 /* ->kernel */ #define PUFFSOPFLAG_FAF 0x10 /* fire-and-forget */ #define PUFFSOPFLAG_ISRESPONSE 0x20 /* req is actually a resp */ Index: src/sys/fs/puffs/puffs_sys.h diff -u src/sys/fs/puffs/puffs_sys.h:1.73 src/sys/fs/puffs/puffs_sys.h:1.74 --- src/sys/fs/puffs/puffs_sys.h:1.73 Mon Dec 7 20:57:55 2009 +++ src/sys/fs/puffs/puffs_sys.h Thu Jan 7 22:45:31 2010 @@ -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. @@ -101,6 +101,7 @@ enum puffs_sopreqtype { PUFFS_SOPREQ_EXIT, PUFFS_SOPREQ_FLUSH, + PUFFS_SOPREQ_UNMOUNT, }; struct puffs_sopreq {