Module Name: src Committed By: pooka Date: Thu Nov 5 19:42:44 UTC 2009
Modified Files: src/sys/fs/puffs: puffs_msgif.c puffs_node.c puffs_sys.h puffs_vfsops.c puffs_vnops.c Log Message: Kill suspend support. It was never implemented correctly: * it depended on the biglock (in a very cruel way) * it was attached to userspace transactions rather than logical fs operations (If someone wants to revisit it some day, most of the stuff can be reused from cvs history) To generate a diff of this commit: cvs rdiff -u -r1.73 -r1.74 src/sys/fs/puffs/puffs_msgif.c cvs rdiff -u -r1.14 -r1.15 src/sys/fs/puffs/puffs_node.c cvs rdiff -u -r1.71 -r1.72 src/sys/fs/puffs/puffs_sys.h cvs rdiff -u -r1.82 -r1.83 src/sys/fs/puffs/puffs_vfsops.c cvs rdiff -u -r1.137 -r1.138 src/sys/fs/puffs/puffs_vnops.c 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.73 src/sys/fs/puffs/puffs_msgif.c:1.74 --- src/sys/fs/puffs/puffs_msgif.c:1.73 Wed Mar 18 10:22:42 2009 +++ src/sys/fs/puffs/puffs_msgif.c Thu Nov 5 19:42:44 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_msgif.c,v 1.73 2009/03/18 10:22:42 cegger Exp $ */ +/* $NetBSD: puffs_msgif.c,v 1.74 2009/11/05 19:42:44 pooka Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,11 +30,10 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.73 2009/03/18 10:22:42 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.74 2009/11/05 19:42:44 pooka Exp $"); #include <sys/param.h> #include <sys/atomic.h> -#include <sys/fstrans.h> #include <sys/kmem.h> #include <sys/kthread.h> #include <sys/lock.h> @@ -366,38 +365,7 @@ } } - /* - * test for suspension lock. - * - * Note that we *DO NOT* keep the lock, since that might block - * lock acquiring PLUS it would give userlandia control over - * the lock. The operation queue enforces a strict ordering: - * when the fs server gets in the op stream, it knows things - * are in order. The kernel locks can't guarantee that for - * userspace, in any case. - * - * BUT: this presents a problem for ops which have a consistency - * clause based on more than one operation. Unfortunately such - * operations (read, write) do not reliably work yet. - * - * Ya, Ya, it's wrong wong wrong, me be fixink this someday. - * - * XXX: and there is one more problem. We sometimes need to - * take a lazy lock in case the fs is suspending and we are - * executing as the fs server context. This might happen - * e.g. in the case that the user server triggers a reclaim - * in the kernel while the fs is suspending. It's not a very - * likely event, but it needs to be fixed some day. - */ - - /* - * MOREXXX: once PUFFS_WCACHEINFO is enabled, we can't take - * the mutex here, since getpages() might be called locked. - */ - fstrans_start(mp, FSTRANS_NORMAL); mutex_enter(&pmp->pmp_lock); - fstrans_done(mp); - if (pmp->pmp_status != PUFFSTAT_RUNNING) { mutex_exit(&pmp->pmp_lock); park->park_flags |= PARKFLAG_HASERROR; @@ -432,7 +400,6 @@ puffs_msg_wait(struct puffs_mount *pmp, struct puffs_msgpark *park) { struct puffs_req *preq = park->park_preq; /* XXX: hmmm */ - struct mount *mp = PMPTOMP(pmp); int error = 0; int rv; @@ -504,20 +471,6 @@ mutex_exit(&park->park_mtx); } - /* - * retake the lock and release. This makes sure (haha, - * I'm humorous) that we don't process the same vnode in - * multiple threads due to the locks hacks we have in - * puffs_lock(). In reality this is well protected by - * the biglock, but once that's gone, well, hopefully - * this will be fixed for real. (and when you read this - * comment in 2017 and subsequently barf, my condolences ;). - */ - if (rv == 0 && !fstrans_is_owner(mp)) { - fstrans_start(mp, FSTRANS_NORMAL); - fstrans_done(mp); - } - skipwait: mutex_enter(&pmp->pmp_lock); puffs_mp_release(pmp); @@ -799,63 +752,6 @@ puffs_msgpark_release1(park, 2); } -/* - * helpers - */ -static void -dosuspendresume(void *arg) -{ - struct puffs_mount *pmp = arg; - struct mount *mp; - int rv; - - mp = PMPTOMP(pmp); - /* - * XXX? does this really do any good or is it just - * paranoid stupidity? or stupid paranoia? - */ - if (mp->mnt_iflag & IMNT_UNMOUNT) { - printf("puffs dosuspendresume(): detected suspend on " - "unmounting fs\n"); - goto out; - } - - /* Do the dance. Allow only one concurrent suspend */ - rv = vfs_suspend(PMPTOMP(pmp), 1); - if (rv == 0) - vfs_resume(PMPTOMP(pmp)); - - out: - mutex_enter(&pmp->pmp_lock); - KASSERT(pmp->pmp_suspend == 1); - pmp->pmp_suspend = 0; - puffs_mp_release(pmp); - mutex_exit(&pmp->pmp_lock); - - kthread_exit(0); -} - -static void -puffsop_suspend(struct puffs_mount *pmp) -{ - int rv = 0; - - mutex_enter(&pmp->pmp_lock); - if (pmp->pmp_suspend || pmp->pmp_status != PUFFSTAT_RUNNING) { - rv = EBUSY; - } else { - puffs_mp_reference(pmp); - pmp->pmp_suspend = 1; - } - mutex_exit(&pmp->pmp_lock); - if (rv) - return; - rv = kthread_create(PRI_NONE, 0, NULL, dosuspendresume, - pmp, NULL, "puffsusp"); - - /* XXX: "return" rv */ -} - static void puffsop_flush(struct puffs_mount *pmp, struct puffs_flush *pf) { @@ -949,6 +845,7 @@ { struct puffs_mount *pmp = this; struct puffs_req *preq = (struct puffs_req *)pth; + int rv = 0; /* XXX: need to send error to userspace */ if (pth->pth_framelen < sizeof(struct puffs_req)) { @@ -968,7 +865,7 @@ break; case PUFFSOP_SUSPEND: DPRINTF(("dispatch: suspend\n")); - puffsop_suspend(pmp); + rv = EOPNOTSUPP; break; default: DPRINTF(("dispatch: invalid class 0x%x\n", preq->preq_opclass)); @@ -976,7 +873,7 @@ break; } - return 0; + return rv; } int Index: src/sys/fs/puffs/puffs_node.c diff -u src/sys/fs/puffs/puffs_node.c:1.14 src/sys/fs/puffs/puffs_node.c:1.15 --- src/sys/fs/puffs/puffs_node.c:1.14 Wed Sep 30 18:19:17 2009 +++ src/sys/fs/puffs/puffs_node.c Thu Nov 5 19:42:44 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_node.c,v 1.14 2009/09/30 18:19:17 pooka Exp $ */ +/* $NetBSD: puffs_node.c,v 1.15 2009/11/05 19:42:44 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_node.c,v 1.14 2009/09/30 18:19:17 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_node.c,v 1.15 2009/11/05 19:42:44 pooka Exp $"); #include <sys/param.h> #include <sys/hash.h> @@ -93,7 +93,6 @@ error = getnewvnode(VT_PUFFS, mp, puffs_vnodeop_p, &vp); if (error) goto bad; - vp->v_vnlock = NULL; vp->v_type = type; /* Index: src/sys/fs/puffs/puffs_sys.h diff -u src/sys/fs/puffs/puffs_sys.h:1.71 src/sys/fs/puffs/puffs_sys.h:1.72 --- src/sys/fs/puffs/puffs_sys.h:1.71 Thu Nov 5 19:22:57 2009 +++ src/sys/fs/puffs/puffs_sys.h Thu Nov 5 19:42:44 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_sys.h,v 1.71 2009/11/05 19:22:57 pooka Exp $ */ +/* $NetBSD: puffs_sys.h,v 1.72 2009/11/05 19:42:44 pooka Exp $ */ /* * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. @@ -153,7 +153,7 @@ #define PNODE_NOREFS 0x01 /* no backend reference */ #define PNODE_DYING 0x02 /* NOREFS + inactive */ -#define PNODE_SUSPEND 0x04 /* issue all operations as FAF */ +#define PNODE_FAF 0x04 /* issue all operations as FAF */ #define PNODE_DOINACT 0x08 /* if inactive-on-demand, call inactive */ #define PNODE_METACACHE_ATIME 0x10 /* cache atime metadata */ Index: src/sys/fs/puffs/puffs_vfsops.c diff -u src/sys/fs/puffs/puffs_vfsops.c:1.82 src/sys/fs/puffs/puffs_vfsops.c:1.83 --- src/sys/fs/puffs/puffs_vfsops.c:1.82 Wed Mar 18 10:22:42 2009 +++ src/sys/fs/puffs/puffs_vfsops.c Thu Nov 5 19:42:44 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vfsops.c,v 1.82 2009/03/18 10:22:42 cegger Exp $ */ +/* $NetBSD: puffs_vfsops.c,v 1.83 2009/11/05 19:42:44 pooka Exp $ */ /* * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.82 2009/03/18 10:22:42 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.83 2009/11/05 19:42:44 pooka Exp $"); #include <sys/param.h> #include <sys/mount.h> @@ -40,7 +40,6 @@ #include <sys/vnode.h> #include <sys/dirent.h> #include <sys/kauth.h> -#include <sys/fstrans.h> #include <sys/proc.h> #include <sys/module.h> @@ -109,9 +108,6 @@ if (!data) return EINVAL; - error = fstrans_mount(mp); - if (error) - return error; args = (struct puffs_kargs *)data; /* devel phase */ @@ -224,7 +220,6 @@ mp->mnt_dev_bshift = DEV_BSHIFT; mp->mnt_flag &= ~MNT_LOCAL; /* we don't really know, so ... */ mp->mnt_data = pmp; - mp->mnt_iflag |= IMNT_HAS_TRANS; pmp->pmp_status = PUFFSTAT_MOUNTING; pmp->pmp_mp = mp; @@ -267,8 +262,6 @@ vfs_getnewfsid(mp); out: - if (error) - fstrans_unmount(mp); if (error && pmp && pmp->pmp_pnodehash) kmem_free(pmp->pmp_pnodehash, BUCKETALLOC(pmp->pmp_npnodehash)); if (error && pmp) @@ -365,7 +358,6 @@ cv_destroy(&pmp->pmp_msg_waiter_cv); mutex_destroy(&pmp->pmp_lock); - fstrans_unmount(mp); kmem_free(pmp->pmp_pnodehash, BUCKETALLOC(pmp->pmp_npnodehash)); kmem_free(pmp, sizeof(struct puffs_mount)); error = 0; @@ -436,17 +428,12 @@ } static int -pageflush(struct mount *mp, kauth_cred_t cred, int waitfor, int suspending) +pageflush(struct mount *mp, kauth_cred_t cred, int waitfor) { struct puffs_node *pn; struct vnode *vp, *mvp; int error, rv; - KASSERT(((waitfor == MNT_WAIT) && suspending) == 0); - KASSERT((suspending == 0) - || (fstrans_is_owner(mp) - && fstrans_getstate(mp) == FSTRANS_SUSPENDING)); - error = 0; /* Allocate a marker vnode. */ @@ -489,9 +476,6 @@ * dounmount(), when we are wait-flushing all the dirty * vnodes through other routes in any case. So there, * sync() doesn't actually sync. Happy now? - * - * NOTE: if we're suspending, vget() does NOT lock. - * See puffs_lock() for details. */ rv = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK); if (rv) { @@ -503,36 +487,16 @@ continue; } - /* - * Thread information to puffs_strategy() through the - * pnode flags: we want to issue the putpages operations - * as FAF if we're suspending, since it's very probable - * that our execution context is that of the userspace - * daemon. We can do this because: - * + we send the "going to suspend" prior to this part - * + if any of the writes fails in userspace, it's the - * file system server's problem to decide if this was a - * failed snapshot when it gets the "snapshot complete" - * notification. - * + if any of the writes fail in the kernel already, we - * immediately fail *and* notify the user server of - * failure. - * - * We also do FAFs if we're called from the syncer. This - * is just general optimization for trickle sync: no need - * to really guarantee that the stuff ended on backing - * storage. - * TODO: Maybe also hint the user server of this twist? - */ - if (suspending || waitfor == MNT_LAZY) { + /* hmm.. is the FAF thing entirely sensible? */ + if (waitfor == MNT_LAZY) { mutex_enter(&vp->v_interlock); - pn->pn_stat |= PNODE_SUSPEND; + pn->pn_stat |= PNODE_FAF; mutex_exit(&vp->v_interlock); } rv = VOP_FSYNC(vp, cred, waitfor, 0, 0); - if (suspending || waitfor == MNT_LAZY) { + if (waitfor == MNT_LAZY) { mutex_enter(&vp->v_interlock); - pn->pn_stat &= ~PNODE_SUSPEND; + pn->pn_stat &= ~PNODE_FAF; mutex_exit(&vp->v_interlock); } if (rv) @@ -553,7 +517,7 @@ struct puffs_mount *pmp = MPTOPUFFSMP(mp); int error, rv; - error = pageflush(mp, cred, waitfor, 0); + error = pageflush(mp, cred, waitfor); /* sync fs */ PUFFS_MSG_ALLOC(vfs, sync); @@ -732,79 +696,6 @@ return EOPNOTSUPP; } -int -puffs_vfsop_suspendctl(struct mount *mp, int cmd) -{ - PUFFS_MSG_VARS(vfs, suspend); - struct puffs_mount *pmp; - int error; - - pmp = MPTOPUFFSMP(mp); - switch (cmd) { - case SUSPEND_SUSPEND: - DPRINTF(("puffs_suspendctl: suspending\n")); - if ((error = fstrans_setstate(mp, FSTRANS_SUSPENDING)) != 0) - break; - PUFFS_MSG_ALLOC(vfs, suspend); - puffs_msg_setfaf(park_suspend); - suspend_msg->pvfsr_status = PUFFS_SUSPEND_START; - puffs_msg_setinfo(park_suspend, PUFFSOP_VFS, - PUFFS_VFS_SUSPEND, NULL); - - puffs_msg_enqueue(pmp, park_suspend); - PUFFS_MSG_RELEASE(suspend); - - error = pageflush(mp, FSCRED, 0, 1); - if (error == 0) - error = fstrans_setstate(mp, FSTRANS_SUSPENDED); - - if (error != 0) { - PUFFS_MSG_ALLOC(vfs, suspend); - puffs_msg_setfaf(park_suspend); - suspend_msg->pvfsr_status = PUFFS_SUSPEND_ERROR; - puffs_msg_setinfo(park_suspend, PUFFSOP_VFS, - PUFFS_VFS_SUSPEND, NULL); - - puffs_msg_enqueue(pmp, park_suspend); - PUFFS_MSG_RELEASE(suspend); - (void) fstrans_setstate(mp, FSTRANS_NORMAL); - break; - } - - PUFFS_MSG_ALLOC(vfs, suspend); - puffs_msg_setfaf(park_suspend); - suspend_msg->pvfsr_status = PUFFS_SUSPEND_SUSPENDED; - puffs_msg_setinfo(park_suspend, PUFFSOP_VFS, - PUFFS_VFS_SUSPEND, NULL); - - puffs_msg_enqueue(pmp, park_suspend); - PUFFS_MSG_RELEASE(suspend); - - break; - - case SUSPEND_RESUME: - DPRINTF(("puffs_suspendctl: resume\n")); - error = 0; - (void) fstrans_setstate(mp, FSTRANS_NORMAL); - PUFFS_MSG_ALLOC(vfs, suspend); - puffs_msg_setfaf(park_suspend); - suspend_msg->pvfsr_status = PUFFS_SUSPEND_RESUME; - puffs_msg_setinfo(park_suspend, PUFFSOP_VFS, - PUFFS_VFS_SUSPEND, NULL); - - puffs_msg_enqueue(pmp, park_suspend); - PUFFS_MSG_RELEASE(suspend); - break; - - default: - error = EINVAL; - break; - } - - DPRINTF(("puffs_suspendctl: return %d\n", error)); - return error; -} - const struct vnodeopv_desc * const puffs_vnodeopv_descs[] = { &puffs_vnodeop_opv_desc, &puffs_specop_opv_desc, @@ -832,7 +723,7 @@ NULL, /* mountroot */ puffs_vfsop_snapshot, /* snapshot */ vfs_stdextattrctl, /* extattrctl */ - puffs_vfsop_suspendctl, /* suspendctl */ + (void *)eopnotsupp, /* suspendctl */ genfs_renamelock_enter, genfs_renamelock_exit, (void *)eopnotsupp, Index: src/sys/fs/puffs/puffs_vnops.c diff -u src/sys/fs/puffs/puffs_vnops.c:1.137 src/sys/fs/puffs/puffs_vnops.c:1.138 --- src/sys/fs/puffs/puffs_vnops.c:1.137 Thu Nov 5 19:22:57 2009 +++ src/sys/fs/puffs/puffs_vnops.c Thu Nov 5 19:42:44 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.137 2009/11/05 19:22:57 pooka Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.138 2009/11/05 19:42:44 pooka Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,11 +30,10 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.137 2009/11/05 19:22:57 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.138 2009/11/05 19:42:44 pooka Exp $"); #include <sys/param.h> #include <sys/buf.h> -#include <sys/fstrans.h> #include <sys/malloc.h> #include <sys/mount.h> #include <sys/namei.h> @@ -91,16 +90,9 @@ int puffs_vnop_checkop(void *); - -#if 0 -#define puffs_lock genfs_lock -#define puffs_unlock genfs_unlock -#define puffs_islocked genfs_islocked -#else -int puffs_vnop_lock(void *); -int puffs_vnop_unlock(void *); -int puffs_vnop_islocked(void *); -#endif +#define puffs_vnop_lock genfs_lock +#define puffs_vnop_unlock genfs_unlock +#define puffs_vnop_islocked genfs_islocked int (**puffs_vnodeop_p)(void *); const struct vnodeopv_entry_desc puffs_vnodeop_entries[] = { @@ -2198,7 +2190,7 @@ mutex_enter(&vp->v_interlock); if (vp->v_iflag & VI_XLOCK) dofaf = 1; - if (pn->pn_stat & PNODE_SUSPEND) + if (pn->pn_stat & PNODE_FAF) dofaf = 1; mutex_exit(&vp->v_interlock); } @@ -2557,77 +2549,6 @@ return error; } -int -puffs_vnop_lock(void *v) -{ - struct vop_lock_args /* { - struct vnode *a_vp; - int a_flags; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct mount *mp = vp->v_mount; - int flags = ap->a_flags; - -#if 0 - DPRINTF(("puffs_lock: lock %p, args 0x%x\n", vp, ap->a_flags)); -#endif - - if (flags & LK_INTERLOCK) { - mutex_exit(&vp->v_interlock); - flags &= ~LK_INTERLOCK; - } - - /* - * XXX: this avoids deadlocking when we're suspending. - * e.g. some ops holding the vnode lock might be blocked for - * the vfs transaction lock so we'd deadlock. - * - * Now once again this is skating on the thin ice of modern life, - * since we are breaking the consistency guarantee provided - * _to the user server_ by vnode locking. Hopefully this will - * get fixed soon enough by getting rid of the dependency on - * vnode locks alltogether. - */ - if (fstrans_is_owner(mp) && fstrans_getstate(mp) == FSTRANS_SUSPENDING){ - return 0; - } - - return vlockmgr(&vp->v_lock, flags); -} - -int -puffs_vnop_unlock(void *v) -{ - struct vop_unlock_args /* { - struct vnode *a_vp; - int a_flags; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct mount *mp = vp->v_mount; - -#if 0 - DPRINTF(("puffs_unlock: lock %p, args 0x%x\n", vp, ap->a_flags)); -#endif - - /* XXX: see puffs_lock() */ - if (fstrans_is_owner(mp) && fstrans_getstate(mp) == FSTRANS_SUSPENDING){ - return 0; - } - - return vlockmgr(&vp->v_lock, ap->a_flags | LK_RELEASE); -} - -int -puffs_vnop_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - int rv; - - rv = vlockstatus(&ap->a_vp->v_lock); - return rv; -} - - /* * spec & fifo. These call the miscfs spec and fifo vectors, but issue * FAF update information for the puffs node first.