From 8de1a273e1229c7f9e51a3c308f8081881b7749f Mon Sep 17 00:00:00 2001 From: hannken Date: Wed, 17 Sep 2008 14:49:25 +0000 Subject: [PATCH] Replace the fss unmount hook with a vfs_hook. fssvar.h: struct device * -> device_t. fss.c: establish unmount hook on first attach, remove on last detach. vfs_syscalls.c: remove the call of fss_umount_hook(). vfs_trans.c: destroy cow handlers on unmount as fstrans_unmount() will be called before vfs_hooks. --- sys/dev/fss.c | 40 +++++++++++++++++++++++++--------------- sys/dev/fssvar.h | 6 ++---- sys/kern/vfs_syscalls.c | 15 +++------------ sys/kern/vfs_trans.c | 12 +++++++++--- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/sys/dev/fss.c b/sys/dev/fss.c index 69e3f0ad5b3a..bb85e4e112ca 100644 --- a/sys/dev/fss.c +++ b/sys/dev/fss.c @@ -1,4 +1,4 @@ -/* $NetBSD: fss.c,v 1.56 2008/09/14 16:10:19 hannken Exp $ */ +/* $NetBSD: fss.c,v 1.57 2008/09/17 14:49:25 hannken Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.56 2008/09/14 16:10:19 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fss.c,v 1.57 2008/09/17 14:49:25 hannken Exp $"); #include #include @@ -76,6 +76,7 @@ dev_type_strategy(fss_strategy); dev_type_dump(fss_dump); dev_type_size(fss_size); +static void fss_unmount_hook(struct mount *); static int fss_copy_on_write(void *, struct buf *, bool); static inline void fss_error(struct fss_softc *, const char *); static int fss_create_files(struct fss_softc *, struct fss_set *, @@ -91,6 +92,12 @@ static int fss_bs_io(struct fss_softc *, fss_io_type, u_int32_t, off_t, int, void *); static u_int32_t *fss_bs_indir(struct fss_softc *, u_int32_t); +static kmutex_t fss_device_lock; /* Protect fss_num_attached. */ +static int fss_num_attached = 0; /* Number of attached devices. */ +static struct vfs_hooks fss_vfs_hooks = { + .vh_unmount = fss_unmount_hook +}; + const struct bdevsw fss_bdevsw = { fss_open, fss_close, fss_strategy, fss_ioctl, fss_dump, fss_size, D_DISK @@ -113,6 +120,7 @@ void fssattach(int num) { + mutex_init(&fss_device_lock, MUTEX_DEFAULT, IPL_NONE); if (config_cfattach_attach(fss_cd.cd_name, &fss_ca)) aprint_error("%s: unable to register\n", fss_cd.cd_name); } @@ -140,6 +148,11 @@ fss_attach(device_t parent, device_t self, void *aux) disk_init(sc->sc_dkdev, device_xname(self), NULL); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); + + mutex_enter(&fss_device_lock); + if (fss_num_attached++ == 0) + vfs_hooks_attach(&fss_vfs_hooks); + mutex_exit(&fss_device_lock); } static int @@ -150,6 +163,11 @@ fss_detach(device_t self, int flags) if (sc->sc_flags & FSS_ACTIVE) return EBUSY; + mutex_enter(&fss_device_lock); + if (--fss_num_attached == 0) + vfs_hooks_detach(&fss_vfs_hooks); + mutex_exit(&fss_device_lock); + pmf_device_deregister(self); mutex_destroy(&sc->sc_slock); mutex_destroy(&sc->sc_lock); @@ -464,10 +482,10 @@ fss_softc_free(struct fss_softc *sc) } /* - * Check if an unmount is ok. If forced, set this snapshot into ERROR state. + * Set all active snapshots on this file system into ERROR state. */ -int -fss_umount_hook(struct mount *mp, int forced) +static void +fss_unmount_hook(struct mount *mp) { int i; struct fss_softc *sc; @@ -477,18 +495,10 @@ fss_umount_hook(struct mount *mp, int forced) continue; mutex_enter(&sc->sc_slock); if ((sc->sc_flags & FSS_ACTIVE) != 0 && - sc->sc_mount == mp) { - if (forced) - fss_error(sc, "forced unmount"); - else { - mutex_exit(&sc->sc_slock); - return EBUSY; - } - } + sc->sc_mount == mp) + fss_error(sc, "forced unmount"); mutex_exit(&sc->sc_slock); } - - return 0; } /* diff --git a/sys/dev/fssvar.h b/sys/dev/fssvar.h index 902223c437c3..67b0bd8263b8 100644 --- a/sys/dev/fssvar.h +++ b/sys/dev/fssvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: fssvar.h,v 1.22 2008/09/14 16:10:19 hannken Exp $ */ +/* $NetBSD: fssvar.h,v 1.23 2008/09/17 14:49:25 hannken Exp $ */ /*- * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. @@ -119,7 +119,7 @@ struct fss_cache { }; struct fss_softc { - struct device *sc_dev; /* Self */ + device_t sc_dev; /* Self */ kmutex_t sc_slock; /* Protect this softc */ kmutex_t sc_lock; /* Sleep lock for fss_ioctl */ kcondvar_t sc_work_cv; /* Signals work for the kernel thread */ @@ -158,8 +158,6 @@ struct fss_softc { u_int32_t *sc_indir_data; /* Current indir cluster data */ }; -int fss_umount_hook(struct mount *, int); - #endif /* _KERNEL */ #endif /* !_SYS_DEV_FSSVAR_H */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index b48faf864f29..c9869e219856 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.370 2008/07/31 05:38:05 simonb Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.371 2008/09/17 14:49:25 hannken Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -63,12 +63,11 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.370 2008/07/31 05:38:05 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.371 2008/09/17 14:49:25 hannken Exp $"); #include "opt_compat_netbsd.h" #include "opt_compat_43.h" #include "opt_fileassoc.h" -#include "fss.h" #include "veriexec.h" #include @@ -111,10 +110,6 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.370 2008/07/31 05:38:05 simonb Ex #include #endif -#if NFSS > 0 -#include -#endif - MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount struct"); static int change_dir(struct nameidata *, struct lwp *); @@ -764,11 +759,7 @@ dounmount(struct mount *mp, int flags, struct lwp *l) vfs_deallocate_syncvnode(mp); error = 0; if ((mp->mnt_flag & MNT_RDONLY) == 0) { -#if NFSS > 0 - error = fss_umount_hook(mp, (flags & MNT_FORCE)); -#endif - if (error == 0) - error = VFS_SYNC(mp, MNT_WAIT, l->l_cred); + error = VFS_SYNC(mp, MNT_WAIT, l->l_cred); } vfs_scrubvnlist(mp); if (error == 0 || (flags & MNT_FORCE)) diff --git a/sys/kern/vfs_trans.c b/sys/kern/vfs_trans.c index 12c1546674c6..5751861fcf5a 100644 --- a/sys/kern/vfs_trans.c +++ b/sys/kern/vfs_trans.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_trans.c,v 1.22 2008/06/24 18:50:30 ad Exp $ */ +/* $NetBSD: vfs_trans.c,v 1.23 2008/09/17 14:49:25 hannken Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.22 2008/06/24 18:50:30 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_trans.c,v 1.23 2008/09/17 14:49:25 hannken Exp $"); /* * File system transaction operations. @@ -143,6 +143,7 @@ void fstrans_unmount(struct mount *mp) { struct fstrans_mount_info *fmi; + struct fscow_handler *hp; if ((fmi = mp->mnt_transinfo) == NULL) return; @@ -150,7 +151,12 @@ fstrans_unmount(struct mount *mp) KASSERT(fmi->fmi_state == FSTRANS_NORMAL); rw_destroy(&fmi->fmi_lazy_lock); rw_destroy(&fmi->fmi_shared_lock); - KASSERT(SLIST_EMPTY(&fmi->fmi_cow_handler)); + rw_enter(&fmi->fmi_cow_lock, RW_WRITER); + while ((hp = SLIST_FIRST(&fmi->fmi_cow_handler)) != NULL) { + SLIST_REMOVE(&fmi->fmi_cow_handler, hp, fscow_handler, ch_list); + kmem_free(hp, sizeof(*hp)); + } + rw_exit(&fmi->fmi_cow_lock); rw_destroy(&fmi->fmi_cow_lock); kmem_free(fmi, sizeof(*fmi)); mp->mnt_iflag &= ~IMNT_HAS_TRANS;