Deleted Added
full compact
g_mirror.c (157290) g_mirror.c (157630)
1/*-
2 * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/geom/mirror/g_mirror.c 157290 2006-03-30 12:15:41Z pjd $");
28__FBSDID("$FreeBSD: head/sys/geom/mirror/g_mirror.c 157630 2006-04-10 10:32:22Z pjd $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/limits.h>
35#include <sys/lock.h>
36#include <sys/mutex.h>

--- 36 unchanged lines hidden (view full) ---

73 &g_mirror_syncreqs, 0, "Parallel synchronization I/O requests.");
74
75#define MSLEEP(ident, mtx, priority, wmesg, timeout) do { \
76 G_MIRROR_DEBUG(4, "%s: Sleeping %p.", __func__, (ident)); \
77 msleep((ident), (mtx), (priority), (wmesg), (timeout)); \
78 G_MIRROR_DEBUG(4, "%s: Woken up %p.", __func__, (ident)); \
79} while (0)
80
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/limits.h>
35#include <sys/lock.h>
36#include <sys/mutex.h>

--- 36 unchanged lines hidden (view full) ---

73 &g_mirror_syncreqs, 0, "Parallel synchronization I/O requests.");
74
75#define MSLEEP(ident, mtx, priority, wmesg, timeout) do { \
76 G_MIRROR_DEBUG(4, "%s: Sleeping %p.", __func__, (ident)); \
77 msleep((ident), (mtx), (priority), (wmesg), (timeout)); \
78 G_MIRROR_DEBUG(4, "%s: Woken up %p.", __func__, (ident)); \
79} while (0)
80
81static eventhandler_tag g_mirror_pre_sync = NULL, g_mirror_post_sync = NULL;
81static eventhandler_tag g_mirror_pre_sync = NULL;
82
83static int g_mirror_destroy_geom(struct gctl_req *req, struct g_class *mp,
84 struct g_geom *gp);
85static g_taste_t g_mirror_taste;
86static void g_mirror_init(struct g_class *mp);
87static void g_mirror_fini(struct g_class *mp);
88
89struct g_class g_mirror_class = {

--- 2602 unchanged lines hidden (view full) ---

2692 if (md->md_version < G_MIRROR_VERSION) {
2693 G_MIRROR_DEBUG(0, "Upgrading metadata on %s (v%d->v%d).",
2694 pp->name, md->md_version, G_MIRROR_VERSION);
2695 g_mirror_update_metadata(disk);
2696 }
2697 return (0);
2698}
2699
82
83static int g_mirror_destroy_geom(struct gctl_req *req, struct g_class *mp,
84 struct g_geom *gp);
85static g_taste_t g_mirror_taste;
86static void g_mirror_init(struct g_class *mp);
87static void g_mirror_fini(struct g_class *mp);
88
89struct g_class g_mirror_class = {

--- 2602 unchanged lines hidden (view full) ---

2692 if (md->md_version < G_MIRROR_VERSION) {
2693 G_MIRROR_DEBUG(0, "Upgrading metadata on %s (v%d->v%d).",
2694 pp->name, md->md_version, G_MIRROR_VERSION);
2695 g_mirror_update_metadata(disk);
2696 }
2697 return (0);
2698}
2699
2700static void
2701g_mirror_destroy_delayed(void *arg, int flag)
2702{
2703 struct g_mirror_softc *sc;
2704 int error;
2705
2706 if (flag == EV_CANCEL) {
2707 G_MIRROR_DEBUG(1, "Destroying canceled.");
2708 return;
2709 }
2710 sc = arg;
2711 g_topology_unlock();
2712 sx_xlock(&sc->sc_lock);
2713 KASSERT((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) == 0,
2714 ("DESTROY flag set on %s.", sc->sc_name));
2715 KASSERT((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROYING) != 0,
2716 ("DESTROYING flag not set on %s.", sc->sc_name));
2717 G_MIRROR_DEBUG(1, "Destroying %s (delayed).", sc->sc_name);
2718 error = g_mirror_destroy(sc, G_MIRROR_DESTROY_SOFT);
2719 if (error != 0) {
2720 G_MIRROR_DEBUG(0, "Cannot destroy %s.", sc->sc_name);
2721 sx_xunlock(&sc->sc_lock);
2722 }
2723 g_topology_lock();
2724}
2725
2700static int
2701g_mirror_access(struct g_provider *pp, int acr, int acw, int ace)
2702{
2703 struct g_mirror_softc *sc;
2726static int
2727g_mirror_access(struct g_provider *pp, int acr, int acw, int ace)
2728{
2729 struct g_mirror_softc *sc;
2704 int dcr, dcw, dce;
2730 int dcr, dcw, dce, error = 0;
2705
2706 g_topology_assert();
2707 G_MIRROR_DEBUG(2, "Access request for %s: r%dw%de%d.", pp->name, acr,
2708 acw, ace);
2709
2710 dcr = pp->acr + acr;
2711 dcw = pp->acw + acw;
2712 dce = pp->ace + ace;
2713
2714 sc = pp->geom->softc;
2731
2732 g_topology_assert();
2733 G_MIRROR_DEBUG(2, "Access request for %s: r%dw%de%d.", pp->name, acr,
2734 acw, ace);
2735
2736 dcr = pp->acr + acr;
2737 dcw = pp->acw + acw;
2738 dce = pp->ace + ace;
2739
2740 sc = pp->geom->softc;
2715 if (sc == NULL || LIST_EMPTY(&sc->sc_disks) ||
2716 (sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
2717 if (acr <= 0 && acw <= 0 && ace <= 0)
2718 return (0);
2719 else
2720 return (ENXIO);
2741 KASSERT(sc != NULL, ("NULL softc (provider=%s).", pp->name));
2742
2743 g_topology_unlock();
2744 sx_xlock(&sc->sc_lock);
2745 if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0 ||
2746 LIST_EMPTY(&sc->sc_disks)) {
2747 if (acr > 0 || acw > 0 || ace > 0)
2748 error = ENXIO;
2749 goto end;
2721 }
2750 }
2722 if (dcw == 0 && !sc->sc_idle) {
2723 g_topology_unlock();
2724 sx_xlock(&sc->sc_lock);
2751 if (dcw == 0 && !sc->sc_idle)
2725 g_mirror_idle(sc, dcw);
2752 g_mirror_idle(sc, dcw);
2726 sx_xunlock(&sc->sc_lock);
2727 g_topology_lock();
2753 if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROYING) != 0) {
2754 if (acr > 0 || acw > 0 || ace > 0) {
2755 error = ENXIO;
2756 goto end;
2757 }
2758 if (dcr == 0 && dcw == 0 && dce == 0) {
2759 g_post_event(g_mirror_destroy_delayed, sc, M_WAITOK,
2760 sc, NULL);
2761 }
2728 }
2762 }
2729 return (0);
2763end:
2764 sx_xunlock(&sc->sc_lock);
2765 g_topology_lock();
2766 return (error);
2730}
2731
2732static struct g_geom *
2733g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md)
2734{
2735 struct g_mirror_softc *sc;
2736 struct g_geom *gp;
2737 int error, timeout;

--- 70 unchanged lines hidden (view full) ---

2808 * Run timeout.
2809 */
2810 timeout = g_mirror_timeout * hz;
2811 callout_reset(&sc->sc_callout, timeout, g_mirror_go, sc);
2812 return (sc->sc_geom);
2813}
2814
2815int
2767}
2768
2769static struct g_geom *
2770g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md)
2771{
2772 struct g_mirror_softc *sc;
2773 struct g_geom *gp;
2774 int error, timeout;

--- 70 unchanged lines hidden (view full) ---

2845 * Run timeout.
2846 */
2847 timeout = g_mirror_timeout * hz;
2848 callout_reset(&sc->sc_callout, timeout, g_mirror_go, sc);
2849 return (sc->sc_geom);
2850}
2851
2852int
2816g_mirror_destroy(struct g_mirror_softc *sc, boolean_t force)
2853g_mirror_destroy(struct g_mirror_softc *sc, int how)
2817{
2854{
2855 struct g_mirror_disk *disk;
2818 struct g_provider *pp;
2819
2820 g_topology_assert_not();
2821 if (sc == NULL)
2822 return (ENXIO);
2823 sx_assert(&sc->sc_lock, SX_XLOCKED);
2824
2825 pp = sc->sc_provider;
2826 if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
2856 struct g_provider *pp;
2857
2858 g_topology_assert_not();
2859 if (sc == NULL)
2860 return (ENXIO);
2861 sx_assert(&sc->sc_lock, SX_XLOCKED);
2862
2863 pp = sc->sc_provider;
2864 if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
2827 if (force) {
2828 G_MIRROR_DEBUG(1, "Device %s is still open, so it "
2829 "can't be definitely removed.", pp->name);
2830 } else {
2865 switch (how) {
2866 case G_MIRROR_DESTROY_SOFT:
2831 G_MIRROR_DEBUG(1,
2832 "Device %s is still open (r%dw%de%d).", pp->name,
2833 pp->acr, pp->acw, pp->ace);
2834 return (EBUSY);
2867 G_MIRROR_DEBUG(1,
2868 "Device %s is still open (r%dw%de%d).", pp->name,
2869 pp->acr, pp->acw, pp->ace);
2870 return (EBUSY);
2871 case G_MIRROR_DESTROY_DELAYED:
2872 G_MIRROR_DEBUG(1,
2873 "Device %s will be destroyed on last close.",
2874 pp->name);
2875 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
2876 if (disk->d_state ==
2877 G_MIRROR_DISK_STATE_SYNCHRONIZING) {
2878 g_mirror_sync_stop(disk, 1);
2879 }
2880 }
2881 sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROYING;
2882 return (EBUSY);
2883 case G_MIRROR_DESTROY_HARD:
2884 G_MIRROR_DEBUG(1, "Device %s is still open, so it "
2885 "can't be definitely removed.", pp->name);
2835 }
2836 }
2837
2838 sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY;
2839 sc->sc_flags |= G_MIRROR_DEVICE_FLAG_WAIT;
2840 G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc);
2841 sx_xunlock(&sc->sc_lock);
2842 mtx_lock(&sc->sc_queue_mtx);

--- 89 unchanged lines hidden (view full) ---

2932 G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
2933 g_topology_unlock();
2934 sx_xlock(&sc->sc_lock);
2935 error = g_mirror_add_disk(sc, pp, &md);
2936 if (error != 0) {
2937 G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
2938 pp->name, gp->name, error);
2939 if (LIST_EMPTY(&sc->sc_disks)) {
2886 }
2887 }
2888
2889 sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY;
2890 sc->sc_flags |= G_MIRROR_DEVICE_FLAG_WAIT;
2891 G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc);
2892 sx_xunlock(&sc->sc_lock);
2893 mtx_lock(&sc->sc_queue_mtx);

--- 89 unchanged lines hidden (view full) ---

2983 G_MIRROR_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name);
2984 g_topology_unlock();
2985 sx_xlock(&sc->sc_lock);
2986 error = g_mirror_add_disk(sc, pp, &md);
2987 if (error != 0) {
2988 G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
2989 pp->name, gp->name, error);
2990 if (LIST_EMPTY(&sc->sc_disks)) {
2991 g_cancel_event(sc);
2940 g_mirror_destroy(sc, 1);
2941 g_topology_lock();
2942 return (NULL);
2943 }
2944 gp = NULL;
2945 }
2946 sx_xunlock(&sc->sc_lock);
2947 g_topology_lock();

--- 5 unchanged lines hidden (view full) ---

2953 struct g_class *mp __unused, struct g_geom *gp)
2954{
2955 struct g_mirror_softc *sc;
2956 int error;
2957
2958 g_topology_unlock();
2959 sc = gp->softc;
2960 sx_xlock(&sc->sc_lock);
2992 g_mirror_destroy(sc, 1);
2993 g_topology_lock();
2994 return (NULL);
2995 }
2996 gp = NULL;
2997 }
2998 sx_xunlock(&sc->sc_lock);
2999 g_topology_lock();

--- 5 unchanged lines hidden (view full) ---

3005 struct g_class *mp __unused, struct g_geom *gp)
3006{
3007 struct g_mirror_softc *sc;
3008 int error;
3009
3010 g_topology_unlock();
3011 sc = gp->softc;
3012 sx_xlock(&sc->sc_lock);
3013 g_cancel_event(sc);
2961 error = g_mirror_destroy(gp->softc, 0);
2962 if (error != 0)
2963 sx_xunlock(&sc->sc_lock);
2964 g_topology_lock();
2965 return (error);
2966}
2967
2968static void

--- 113 unchanged lines hidden (view full) ---

3082}
3083
3084static void
3085g_mirror_shutdown_pre_sync(void *arg, int howto)
3086{
3087 struct g_class *mp;
3088 struct g_geom *gp, *gp2;
3089 struct g_mirror_softc *sc;
3014 error = g_mirror_destroy(gp->softc, 0);
3015 if (error != 0)
3016 sx_xunlock(&sc->sc_lock);
3017 g_topology_lock();
3018 return (error);
3019}
3020
3021static void

--- 113 unchanged lines hidden (view full) ---

3135}
3136
3137static void
3138g_mirror_shutdown_pre_sync(void *arg, int howto)
3139{
3140 struct g_class *mp;
3141 struct g_geom *gp, *gp2;
3142 struct g_mirror_softc *sc;
3090 struct g_mirror_disk *disk;
3143 int error;
3091
3092 mp = arg;
3093 DROP_GIANT();
3094 g_topology_lock();
3095 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
3096 if ((sc = gp->softc) == NULL)
3097 continue;
3144
3145 mp = arg;
3146 DROP_GIANT();
3147 g_topology_lock();
3148 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
3149 if ((sc = gp->softc) == NULL)
3150 continue;
3098 g_topology_unlock();
3099 sx_xlock(&sc->sc_lock);
3100 LIST_FOREACH(disk, &sc->sc_disks, d_next) {
3101 if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING)
3102 g_mirror_sync_stop(disk, 1);
3103 }
3104 sx_xunlock(&sc->sc_lock);
3105 g_topology_lock();
3106 }
3107 g_topology_unlock();
3108 PICKUP_GIANT();
3109}
3110
3111static void
3112g_mirror_shutdown_post_sync(void *arg, int howto)
3113{
3114 struct g_class *mp;
3115 struct g_geom *gp, *gp2;
3116 struct g_mirror_softc *sc;
3117
3118 mp = arg;
3119 DROP_GIANT();
3120 g_topology_lock();
3121 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
3122 if ((sc = gp->softc) == NULL)
3151 /* Skip synchronization geom. */
3152 if (gp == sc->sc_sync.ds_geom)
3123 continue;
3124 g_topology_unlock();
3125 sx_xlock(&sc->sc_lock);
3153 continue;
3154 g_topology_unlock();
3155 sx_xlock(&sc->sc_lock);
3126 g_mirror_destroy(sc, 1);
3156 g_cancel_event(sc);
3157 error = g_mirror_destroy(sc, G_MIRROR_DESTROY_DELAYED);
3158 if (error != 0)
3159 sx_xunlock(&sc->sc_lock);
3127 g_topology_lock();
3128 }
3129 g_topology_unlock();
3130 PICKUP_GIANT();
3160 g_topology_lock();
3161 }
3162 g_topology_unlock();
3163 PICKUP_GIANT();
3131#if 0
3132 tsleep(&gp, PRIBIO, "m:shutdown", hz * 20);
3133#endif
3134}
3135
3136static void
3137g_mirror_init(struct g_class *mp)
3138{
3139
3140 g_mirror_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync,
3141 g_mirror_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST);
3164}
3165
3166static void
3167g_mirror_init(struct g_class *mp)
3168{
3169
3170 g_mirror_pre_sync = EVENTHANDLER_REGISTER(shutdown_pre_sync,
3171 g_mirror_shutdown_pre_sync, mp, SHUTDOWN_PRI_FIRST);
3142 g_mirror_post_sync = EVENTHANDLER_REGISTER(shutdown_post_sync,
3143 g_mirror_shutdown_post_sync, mp, SHUTDOWN_PRI_FIRST);
3144 if (g_mirror_pre_sync == NULL || g_mirror_post_sync == NULL)
3172 if (g_mirror_pre_sync == NULL)
3145 G_MIRROR_DEBUG(0, "Warning! Cannot register shutdown event.");
3146}
3147
3148static void
3149g_mirror_fini(struct g_class *mp)
3150{
3151
3152 if (g_mirror_pre_sync != NULL)
3153 EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_mirror_pre_sync);
3173 G_MIRROR_DEBUG(0, "Warning! Cannot register shutdown event.");
3174}
3175
3176static void
3177g_mirror_fini(struct g_class *mp)
3178{
3179
3180 if (g_mirror_pre_sync != NULL)
3181 EVENTHANDLER_DEREGISTER(shutdown_pre_sync, g_mirror_pre_sync);
3154 if (g_mirror_post_sync != NULL)
3155 EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_mirror_post_sync);
3156}
3157
3158DECLARE_GEOM_CLASS(g_mirror_class, g_mirror);
3182}
3183
3184DECLARE_GEOM_CLASS(g_mirror_class, g_mirror);