aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r--drivers/block/drbd/drbd_main.c251
1 files changed, 211 insertions, 40 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 298b868910dc..a5dca6affcbb 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -45,7 +45,7 @@
45#include <linux/reboot.h> 45#include <linux/reboot.h>
46#include <linux/notifier.h> 46#include <linux/notifier.h>
47#include <linux/kthread.h> 47#include <linux/kthread.h>
48 48#include <linux/workqueue.h>
49#define __KERNEL_SYSCALLS__ 49#define __KERNEL_SYSCALLS__
50#include <linux/unistd.h> 50#include <linux/unistd.h>
51#include <linux/vmalloc.h> 51#include <linux/vmalloc.h>
@@ -2299,6 +2299,7 @@ static void drbd_cleanup(void)
2299 idr_for_each_entry(&minors, mdev, i) { 2299 idr_for_each_entry(&minors, mdev, i) {
2300 idr_remove(&minors, mdev_to_minor(mdev)); 2300 idr_remove(&minors, mdev_to_minor(mdev));
2301 idr_remove(&mdev->tconn->volumes, mdev->vnr); 2301 idr_remove(&mdev->tconn->volumes, mdev->vnr);
2302 destroy_workqueue(mdev->submit.wq);
2302 del_gendisk(mdev->vdisk); 2303 del_gendisk(mdev->vdisk);
2303 /* synchronize_rcu(); No other threads running at this point */ 2304 /* synchronize_rcu(); No other threads running at this point */
2304 kref_put(&mdev->kref, &drbd_minor_destroy); 2305 kref_put(&mdev->kref, &drbd_minor_destroy);
@@ -2588,6 +2589,21 @@ void conn_destroy(struct kref *kref)
2588 kfree(tconn); 2589 kfree(tconn);
2589} 2590}
2590 2591
2592int init_submitter(struct drbd_conf *mdev)
2593{
2594 /* opencoded create_singlethread_workqueue(),
2595 * to be able to say "drbd%d", ..., minor */
2596 mdev->submit.wq = alloc_workqueue("drbd%u_submit",
2597 WQ_UNBOUND | WQ_MEM_RECLAIM, 1, mdev->minor);
2598 if (!mdev->submit.wq)
2599 return -ENOMEM;
2600
2601 INIT_WORK(&mdev->submit.worker, do_submit);
2602 spin_lock_init(&mdev->submit.lock);
2603 INIT_LIST_HEAD(&mdev->submit.writes);
2604 return 0;
2605}
2606
2591enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr) 2607enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr)
2592{ 2608{
2593 struct drbd_conf *mdev; 2609 struct drbd_conf *mdev;
@@ -2677,6 +2693,12 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor,
2677 goto out_idr_remove_minor; 2693 goto out_idr_remove_minor;
2678 } 2694 }
2679 2695
2696 if (init_submitter(mdev)) {
2697 err = ERR_NOMEM;
2698 drbd_msg_put_info("unable to create submit workqueue");
2699 goto out_idr_remove_vol;
2700 }
2701
2680 add_disk(disk); 2702 add_disk(disk);
2681 kref_init(&mdev->kref); /* one ref for both idrs and the the add_disk */ 2703 kref_init(&mdev->kref); /* one ref for both idrs and the the add_disk */
2682 2704
@@ -2687,6 +2709,8 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor,
2687 2709
2688 return NO_ERROR; 2710 return NO_ERROR;
2689 2711
2712out_idr_remove_vol:
2713 idr_remove(&tconn->volumes, vnr_got);
2690out_idr_remove_minor: 2714out_idr_remove_minor:
2691 idr_remove(&minors, minor_got); 2715 idr_remove(&minors, minor_got);
2692 synchronize_rcu(); 2716 synchronize_rcu();
@@ -2794,6 +2818,7 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
2794 blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); 2818 blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
2795 blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); 2819 blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
2796 2820
2821 kfree(ldev->disk_conf);
2797 kfree(ldev); 2822 kfree(ldev);
2798} 2823}
2799 2824
@@ -2833,8 +2858,9 @@ void conn_md_sync(struct drbd_tconn *tconn)
2833 rcu_read_unlock(); 2858 rcu_read_unlock();
2834} 2859}
2835 2860
2861/* aligned 4kByte */
2836struct meta_data_on_disk { 2862struct meta_data_on_disk {
2837 u64 la_size; /* last agreed size. */ 2863 u64 la_size_sect; /* last agreed size. */
2838 u64 uuid[UI_SIZE]; /* UUIDs. */ 2864 u64 uuid[UI_SIZE]; /* UUIDs. */
2839 u64 device_uuid; 2865 u64 device_uuid;
2840 u64 reserved_u64_1; 2866 u64 reserved_u64_1;
@@ -2842,13 +2868,17 @@ struct meta_data_on_disk {
2842 u32 magic; 2868 u32 magic;
2843 u32 md_size_sect; 2869 u32 md_size_sect;
2844 u32 al_offset; /* offset to this block */ 2870 u32 al_offset; /* offset to this block */
2845 u32 al_nr_extents; /* important for restoring the AL */ 2871 u32 al_nr_extents; /* important for restoring the AL (userspace) */
2846 /* `-- act_log->nr_elements <-- ldev->dc.al_extents */ 2872 /* `-- act_log->nr_elements <-- ldev->dc.al_extents */
2847 u32 bm_offset; /* offset to the bitmap, from here */ 2873 u32 bm_offset; /* offset to the bitmap, from here */
2848 u32 bm_bytes_per_bit; /* BM_BLOCK_SIZE */ 2874 u32 bm_bytes_per_bit; /* BM_BLOCK_SIZE */
2849 u32 la_peer_max_bio_size; /* last peer max_bio_size */ 2875 u32 la_peer_max_bio_size; /* last peer max_bio_size */
2850 u32 reserved_u32[3];
2851 2876
2877 /* see al_tr_number_to_on_disk_sector() */
2878 u32 al_stripes;
2879 u32 al_stripe_size_4k;
2880
2881 u8 reserved_u8[4096 - (7*8 + 10*4)];
2852} __packed; 2882} __packed;
2853 2883
2854/** 2884/**
@@ -2861,6 +2891,10 @@ void drbd_md_sync(struct drbd_conf *mdev)
2861 sector_t sector; 2891 sector_t sector;
2862 int i; 2892 int i;
2863 2893
2894 /* Don't accidentally change the DRBD meta data layout. */
2895 BUILD_BUG_ON(UI_SIZE != 4);
2896 BUILD_BUG_ON(sizeof(struct meta_data_on_disk) != 4096);
2897
2864 del_timer(&mdev->md_sync_timer); 2898 del_timer(&mdev->md_sync_timer);
2865 /* timer may be rearmed by drbd_md_mark_dirty() now. */ 2899 /* timer may be rearmed by drbd_md_mark_dirty() now. */
2866 if (!test_and_clear_bit(MD_DIRTY, &mdev->flags)) 2900 if (!test_and_clear_bit(MD_DIRTY, &mdev->flags))
@@ -2875,9 +2909,9 @@ void drbd_md_sync(struct drbd_conf *mdev)
2875 if (!buffer) 2909 if (!buffer)
2876 goto out; 2910 goto out;
2877 2911
2878 memset(buffer, 0, 512); 2912 memset(buffer, 0, sizeof(*buffer));
2879 2913
2880 buffer->la_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev)); 2914 buffer->la_size_sect = cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
2881 for (i = UI_CURRENT; i < UI_SIZE; i++) 2915 for (i = UI_CURRENT; i < UI_SIZE; i++)
2882 buffer->uuid[i] = cpu_to_be64(mdev->ldev->md.uuid[i]); 2916 buffer->uuid[i] = cpu_to_be64(mdev->ldev->md.uuid[i]);
2883 buffer->flags = cpu_to_be32(mdev->ldev->md.flags); 2917 buffer->flags = cpu_to_be32(mdev->ldev->md.flags);
@@ -2892,7 +2926,10 @@ void drbd_md_sync(struct drbd_conf *mdev)
2892 buffer->bm_offset = cpu_to_be32(mdev->ldev->md.bm_offset); 2926 buffer->bm_offset = cpu_to_be32(mdev->ldev->md.bm_offset);
2893 buffer->la_peer_max_bio_size = cpu_to_be32(mdev->peer_max_bio_size); 2927 buffer->la_peer_max_bio_size = cpu_to_be32(mdev->peer_max_bio_size);
2894 2928
2895 D_ASSERT(drbd_md_ss__(mdev, mdev->ldev) == mdev->ldev->md.md_offset); 2929 buffer->al_stripes = cpu_to_be32(mdev->ldev->md.al_stripes);
2930 buffer->al_stripe_size_4k = cpu_to_be32(mdev->ldev->md.al_stripe_size_4k);
2931
2932 D_ASSERT(drbd_md_ss(mdev->ldev) == mdev->ldev->md.md_offset);
2896 sector = mdev->ldev->md.md_offset; 2933 sector = mdev->ldev->md.md_offset;
2897 2934
2898 if (drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) { 2935 if (drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
@@ -2910,13 +2947,141 @@ out:
2910 put_ldev(mdev); 2947 put_ldev(mdev);
2911} 2948}
2912 2949
2950static int check_activity_log_stripe_size(struct drbd_conf *mdev,
2951 struct meta_data_on_disk *on_disk,
2952 struct drbd_md *in_core)
2953{
2954 u32 al_stripes = be32_to_cpu(on_disk->al_stripes);
2955 u32 al_stripe_size_4k = be32_to_cpu(on_disk->al_stripe_size_4k);
2956 u64 al_size_4k;
2957
2958 /* both not set: default to old fixed size activity log */
2959 if (al_stripes == 0 && al_stripe_size_4k == 0) {
2960 al_stripes = 1;
2961 al_stripe_size_4k = MD_32kB_SECT/8;
2962 }
2963
2964 /* some paranoia plausibility checks */
2965
2966 /* we need both values to be set */
2967 if (al_stripes == 0 || al_stripe_size_4k == 0)
2968 goto err;
2969
2970 al_size_4k = (u64)al_stripes * al_stripe_size_4k;
2971
2972 /* Upper limit of activity log area, to avoid potential overflow
2973 * problems in al_tr_number_to_on_disk_sector(). As right now, more
2974 * than 72 * 4k blocks total only increases the amount of history,
2975 * limiting this arbitrarily to 16 GB is not a real limitation ;-) */
2976 if (al_size_4k > (16 * 1024 * 1024/4))
2977 goto err;
2978
2979 /* Lower limit: we need at least 8 transaction slots (32kB)
2980 * to not break existing setups */
2981 if (al_size_4k < MD_32kB_SECT/8)
2982 goto err;
2983
2984 in_core->al_stripe_size_4k = al_stripe_size_4k;
2985 in_core->al_stripes = al_stripes;
2986 in_core->al_size_4k = al_size_4k;
2987
2988 return 0;
2989err:
2990 dev_err(DEV, "invalid activity log striping: al_stripes=%u, al_stripe_size_4k=%u\n",
2991 al_stripes, al_stripe_size_4k);
2992 return -EINVAL;
2993}
2994
2995static int check_offsets_and_sizes(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
2996{
2997 sector_t capacity = drbd_get_capacity(bdev->md_bdev);
2998 struct drbd_md *in_core = &bdev->md;
2999 s32 on_disk_al_sect;
3000 s32 on_disk_bm_sect;
3001
3002 /* The on-disk size of the activity log, calculated from offsets, and
3003 * the size of the activity log calculated from the stripe settings,
3004 * should match.
3005 * Though we could relax this a bit: it is ok, if the striped activity log
3006 * fits in the available on-disk activity log size.
3007 * Right now, that would break how resize is implemented.
3008 * TODO: make drbd_determine_dev_size() (and the drbdmeta tool) aware
3009 * of possible unused padding space in the on disk layout. */
3010 if (in_core->al_offset < 0) {
3011 if (in_core->bm_offset > in_core->al_offset)
3012 goto err;
3013 on_disk_al_sect = -in_core->al_offset;
3014 on_disk_bm_sect = in_core->al_offset - in_core->bm_offset;
3015 } else {
3016 if (in_core->al_offset != MD_4kB_SECT)
3017 goto err;
3018 if (in_core->bm_offset < in_core->al_offset + in_core->al_size_4k * MD_4kB_SECT)
3019 goto err;
3020
3021 on_disk_al_sect = in_core->bm_offset - MD_4kB_SECT;
3022 on_disk_bm_sect = in_core->md_size_sect - in_core->bm_offset;
3023 }
3024
3025 /* old fixed size meta data is exactly that: fixed. */
3026 if (in_core->meta_dev_idx >= 0) {
3027 if (in_core->md_size_sect != MD_128MB_SECT
3028 || in_core->al_offset != MD_4kB_SECT
3029 || in_core->bm_offset != MD_4kB_SECT + MD_32kB_SECT
3030 || in_core->al_stripes != 1
3031 || in_core->al_stripe_size_4k != MD_32kB_SECT/8)
3032 goto err;
3033 }
3034
3035 if (capacity < in_core->md_size_sect)
3036 goto err;
3037 if (capacity - in_core->md_size_sect < drbd_md_first_sector(bdev))
3038 goto err;
3039
3040 /* should be aligned, and at least 32k */
3041 if ((on_disk_al_sect & 7) || (on_disk_al_sect < MD_32kB_SECT))
3042 goto err;
3043
3044 /* should fit (for now: exactly) into the available on-disk space;
3045 * overflow prevention is in check_activity_log_stripe_size() above. */
3046 if (on_disk_al_sect != in_core->al_size_4k * MD_4kB_SECT)
3047 goto err;
3048
3049 /* again, should be aligned */
3050 if (in_core->bm_offset & 7)
3051 goto err;
3052
3053 /* FIXME check for device grow with flex external meta data? */
3054
3055 /* can the available bitmap space cover the last agreed device size? */
3056 if (on_disk_bm_sect < (in_core->la_size_sect+7)/MD_4kB_SECT/8/512)
3057 goto err;
3058
3059 return 0;
3060
3061err:
3062 dev_err(DEV, "meta data offsets don't make sense: idx=%d "
3063 "al_s=%u, al_sz4k=%u, al_offset=%d, bm_offset=%d, "
3064 "md_size_sect=%u, la_size=%llu, md_capacity=%llu\n",
3065 in_core->meta_dev_idx,
3066 in_core->al_stripes, in_core->al_stripe_size_4k,
3067 in_core->al_offset, in_core->bm_offset, in_core->md_size_sect,
3068 (unsigned long long)in_core->la_size_sect,
3069 (unsigned long long)capacity);
3070
3071 return -EINVAL;
3072}
3073
3074
2913/** 3075/**
2914 * drbd_md_read() - Reads in the meta data super block 3076 * drbd_md_read() - Reads in the meta data super block
2915 * @mdev: DRBD device. 3077 * @mdev: DRBD device.
2916 * @bdev: Device from which the meta data should be read in. 3078 * @bdev: Device from which the meta data should be read in.
2917 * 3079 *
2918 * Return 0 (NO_ERROR) on success, and an enum drbd_ret_code in case 3080 * Return NO_ERROR on success, and an enum drbd_ret_code in case
2919 * something goes wrong. 3081 * something goes wrong.
3082 *
3083 * Called exactly once during drbd_adm_attach(), while still being D_DISKLESS,
3084 * even before @bdev is assigned to @mdev->ldev.
2920 */ 3085 */
2921int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) 3086int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
2922{ 3087{
@@ -2924,12 +3089,17 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
2924 u32 magic, flags; 3089 u32 magic, flags;
2925 int i, rv = NO_ERROR; 3090 int i, rv = NO_ERROR;
2926 3091
2927 if (!get_ldev_if_state(mdev, D_ATTACHING)) 3092 if (mdev->state.disk != D_DISKLESS)
2928 return ERR_IO_MD_DISK; 3093 return ERR_DISK_CONFIGURED;
2929 3094
2930 buffer = drbd_md_get_buffer(mdev); 3095 buffer = drbd_md_get_buffer(mdev);
2931 if (!buffer) 3096 if (!buffer)
2932 goto out; 3097 return ERR_NOMEM;
3098
3099 /* First, figure out where our meta data superblock is located,
3100 * and read it. */
3101 bdev->md.meta_dev_idx = bdev->disk_conf->meta_dev_idx;
3102 bdev->md.md_offset = drbd_md_ss(bdev);
2933 3103
2934 if (drbd_md_sync_page_io(mdev, bdev, bdev->md.md_offset, READ)) { 3104 if (drbd_md_sync_page_io(mdev, bdev, bdev->md.md_offset, READ)) {
2935 /* NOTE: can't do normal error processing here as this is 3105 /* NOTE: can't do normal error processing here as this is
@@ -2948,45 +3118,51 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
2948 rv = ERR_MD_UNCLEAN; 3118 rv = ERR_MD_UNCLEAN;
2949 goto err; 3119 goto err;
2950 } 3120 }
3121
3122 rv = ERR_MD_INVALID;
2951 if (magic != DRBD_MD_MAGIC_08) { 3123 if (magic != DRBD_MD_MAGIC_08) {
2952 if (magic == DRBD_MD_MAGIC_07) 3124 if (magic == DRBD_MD_MAGIC_07)
2953 dev_err(DEV, "Found old (0.7) meta data magic. Did you \"drbdadm create-md\"?\n"); 3125 dev_err(DEV, "Found old (0.7) meta data magic. Did you \"drbdadm create-md\"?\n");
2954 else 3126 else
2955 dev_err(DEV, "Meta data magic not found. Did you \"drbdadm create-md\"?\n"); 3127 dev_err(DEV, "Meta data magic not found. Did you \"drbdadm create-md\"?\n");
2956 rv = ERR_MD_INVALID;
2957 goto err; 3128 goto err;
2958 } 3129 }
2959 if (be32_to_cpu(buffer->al_offset) != bdev->md.al_offset) { 3130
2960 dev_err(DEV, "unexpected al_offset: %d (expected %d)\n", 3131 if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) {
2961 be32_to_cpu(buffer->al_offset), bdev->md.al_offset); 3132 dev_err(DEV, "unexpected bm_bytes_per_bit: %u (expected %u)\n",
2962 rv = ERR_MD_INVALID; 3133 be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE);
2963 goto err; 3134 goto err;
2964 } 3135 }
3136
3137
3138 /* convert to in_core endian */
3139 bdev->md.la_size_sect = be64_to_cpu(buffer->la_size_sect);
3140 for (i = UI_CURRENT; i < UI_SIZE; i++)
3141 bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]);
3142 bdev->md.flags = be32_to_cpu(buffer->flags);
3143 bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
3144
3145 bdev->md.md_size_sect = be32_to_cpu(buffer->md_size_sect);
3146 bdev->md.al_offset = be32_to_cpu(buffer->al_offset);
3147 bdev->md.bm_offset = be32_to_cpu(buffer->bm_offset);
3148
3149 if (check_activity_log_stripe_size(mdev, buffer, &bdev->md))
3150 goto err;
3151 if (check_offsets_and_sizes(mdev, bdev))
3152 goto err;
3153
2965 if (be32_to_cpu(buffer->bm_offset) != bdev->md.bm_offset) { 3154 if (be32_to_cpu(buffer->bm_offset) != bdev->md.bm_offset) {
2966 dev_err(DEV, "unexpected bm_offset: %d (expected %d)\n", 3155 dev_err(DEV, "unexpected bm_offset: %d (expected %d)\n",
2967 be32_to_cpu(buffer->bm_offset), bdev->md.bm_offset); 3156 be32_to_cpu(buffer->bm_offset), bdev->md.bm_offset);
2968 rv = ERR_MD_INVALID;
2969 goto err; 3157 goto err;
2970 } 3158 }
2971 if (be32_to_cpu(buffer->md_size_sect) != bdev->md.md_size_sect) { 3159 if (be32_to_cpu(buffer->md_size_sect) != bdev->md.md_size_sect) {
2972 dev_err(DEV, "unexpected md_size: %u (expected %u)\n", 3160 dev_err(DEV, "unexpected md_size: %u (expected %u)\n",
2973 be32_to_cpu(buffer->md_size_sect), bdev->md.md_size_sect); 3161 be32_to_cpu(buffer->md_size_sect), bdev->md.md_size_sect);
2974 rv = ERR_MD_INVALID;
2975 goto err; 3162 goto err;
2976 } 3163 }
2977 3164
2978 if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) { 3165 rv = NO_ERROR;
2979 dev_err(DEV, "unexpected bm_bytes_per_bit: %u (expected %u)\n",
2980 be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE);
2981 rv = ERR_MD_INVALID;
2982 goto err;
2983 }
2984
2985 bdev->md.la_size_sect = be64_to_cpu(buffer->la_size);
2986 for (i = UI_CURRENT; i < UI_SIZE; i++)
2987 bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]);
2988 bdev->md.flags = be32_to_cpu(buffer->flags);
2989 bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
2990 3166
2991 spin_lock_irq(&mdev->tconn->req_lock); 3167 spin_lock_irq(&mdev->tconn->req_lock);
2992 if (mdev->state.conn < C_CONNECTED) { 3168 if (mdev->state.conn < C_CONNECTED) {
@@ -2999,8 +3175,6 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
2999 3175
3000 err: 3176 err:
3001 drbd_md_put_buffer(mdev); 3177 drbd_md_put_buffer(mdev);
3002 out:
3003 put_ldev(mdev);
3004 3178
3005 return rv; 3179 return rv;
3006} 3180}
@@ -3238,8 +3412,12 @@ static int w_go_diskless(struct drbd_work *w, int unused)
3238 * end up here after a failed attach, before ldev was even assigned. 3412 * end up here after a failed attach, before ldev was even assigned.
3239 */ 3413 */
3240 if (mdev->bitmap && mdev->ldev) { 3414 if (mdev->bitmap && mdev->ldev) {
3415 /* An interrupted resync or similar is allowed to recounts bits
3416 * while we detach.
3417 * Any modifications would not be expected anymore, though.
3418 */
3241 if (drbd_bitmap_io_from_worker(mdev, drbd_bm_write, 3419 if (drbd_bitmap_io_from_worker(mdev, drbd_bm_write,
3242 "detach", BM_LOCKED_MASK)) { 3420 "detach", BM_LOCKED_TEST_ALLOWED)) {
3243 if (test_bit(WAS_READ_ERROR, &mdev->flags)) { 3421 if (test_bit(WAS_READ_ERROR, &mdev->flags)) {
3244 drbd_md_set_flag(mdev, MDF_FULL_SYNC); 3422 drbd_md_set_flag(mdev, MDF_FULL_SYNC);
3245 drbd_md_sync(mdev); 3423 drbd_md_sync(mdev);
@@ -3251,13 +3429,6 @@ static int w_go_diskless(struct drbd_work *w, int unused)
3251 return 0; 3429 return 0;
3252} 3430}
3253 3431
3254void drbd_go_diskless(struct drbd_conf *mdev)
3255{
3256 D_ASSERT(mdev->state.disk == D_FAILED);
3257 if (!test_and_set_bit(GO_DISKLESS, &mdev->flags))
3258 drbd_queue_work(&mdev->tconn->sender_work, &mdev->go_diskless);
3259}
3260
3261/** 3432/**
3262 * drbd_queue_bitmap_io() - Queues an IO operation on the whole bitmap 3433 * drbd_queue_bitmap_io() - Queues an IO operation on the whole bitmap
3263 * @mdev: DRBD device. 3434 * @mdev: DRBD device.