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); |