|
@@ -1110,15 +1110,16 @@ static int drbd_check_al_size(struct drbd_device *device, struct disk_conf *dc)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void drbd_setup_queue_param(struct drbd_device *device, unsigned int max_bio_size)
|
|
|
+static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backing_dev *bdev,
|
|
|
+ unsigned int max_bio_size)
|
|
|
{
|
|
|
struct request_queue * const q = device->rq_queue;
|
|
|
unsigned int max_hw_sectors = max_bio_size >> 9;
|
|
|
unsigned int max_segments = 0;
|
|
|
struct request_queue *b = NULL;
|
|
|
|
|
|
- if (get_ldev_if_state(device, D_ATTACHING)) {
|
|
|
- b = device->ldev->backing_bdev->bd_disk->queue;
|
|
|
+ if (bdev) {
|
|
|
+ b = bdev->backing_bdev->bd_disk->queue;
|
|
|
|
|
|
max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9);
|
|
|
rcu_read_lock();
|
|
@@ -1163,11 +1164,10 @@ static void drbd_setup_queue_param(struct drbd_device *device, unsigned int max_
|
|
|
b->backing_dev_info.ra_pages);
|
|
|
q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
|
|
|
}
|
|
|
- put_ldev(device);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void drbd_reconsider_max_bio_size(struct drbd_device *device)
|
|
|
+void drbd_reconsider_max_bio_size(struct drbd_device *device, struct drbd_backing_dev *bdev)
|
|
|
{
|
|
|
unsigned int now, new, local, peer;
|
|
|
|
|
@@ -1175,10 +1175,9 @@ void drbd_reconsider_max_bio_size(struct drbd_device *device)
|
|
|
local = device->local_max_bio_size; /* Eventually last known value, from volatile memory */
|
|
|
peer = device->peer_max_bio_size; /* Eventually last known value, from meta data */
|
|
|
|
|
|
- if (get_ldev_if_state(device, D_ATTACHING)) {
|
|
|
- local = queue_max_hw_sectors(device->ldev->backing_bdev->bd_disk->queue) << 9;
|
|
|
+ if (bdev) {
|
|
|
+ local = queue_max_hw_sectors(bdev->backing_bdev->bd_disk->queue) << 9;
|
|
|
device->local_max_bio_size = local;
|
|
|
- put_ldev(device);
|
|
|
}
|
|
|
local = min(local, DRBD_MAX_BIO_SIZE);
|
|
|
|
|
@@ -1211,7 +1210,7 @@ void drbd_reconsider_max_bio_size(struct drbd_device *device)
|
|
|
if (new != now)
|
|
|
drbd_info(device, "max BIO size = %u\n", new);
|
|
|
|
|
|
- drbd_setup_queue_param(device, new);
|
|
|
+ drbd_setup_queue_param(device, bdev, new);
|
|
|
}
|
|
|
|
|
|
/* Starts the worker thread */
|
|
@@ -1399,7 +1398,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
|
|
|
else
|
|
|
set_bit(MD_NO_FUA, &device->flags);
|
|
|
|
|
|
- drbd_bump_write_ordering(device->resource, WO_bdev_flush);
|
|
|
+ drbd_bump_write_ordering(device->resource, NULL, WO_bdev_flush);
|
|
|
|
|
|
drbd_md_sync(device);
|
|
|
|
|
@@ -1704,7 +1703,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
|
|
|
new_disk_conf = NULL;
|
|
|
new_plan = NULL;
|
|
|
|
|
|
- drbd_bump_write_ordering(device->resource, WO_bdev_flush);
|
|
|
+ drbd_bump_write_ordering(device->resource, device->ldev, WO_bdev_flush);
|
|
|
|
|
|
if (drbd_md_test_flag(device->ldev, MDF_CRASHED_PRIMARY))
|
|
|
set_bit(CRASHED_PRIMARY, &device->flags);
|
|
@@ -1720,7 +1719,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
|
|
|
device->read_cnt = 0;
|
|
|
device->writ_cnt = 0;
|
|
|
|
|
|
- drbd_reconsider_max_bio_size(device);
|
|
|
+ drbd_reconsider_max_bio_size(device, device->ldev);
|
|
|
|
|
|
/* If I am currently not R_PRIMARY,
|
|
|
* but meta data primary indicator is set,
|
|
@@ -2648,8 +2647,13 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (retcode != NO_ERROR)
|
|
|
goto out;
|
|
|
|
|
|
- mutex_lock(&adm_ctx.resource->adm_mutex);
|
|
|
device = adm_ctx.device;
|
|
|
+ if (!get_ldev(device)) {
|
|
|
+ retcode = ERR_NO_DISK;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_lock(&adm_ctx.resource->adm_mutex);
|
|
|
|
|
|
/* If there is still bitmap IO pending, probably because of a previous
|
|
|
* resync just being finished, wait for it before requesting a new resync.
|
|
@@ -2673,6 +2677,7 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
|
|
|
retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_T));
|
|
|
drbd_resume_io(device);
|
|
|
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
|
|
+ put_ldev(device);
|
|
|
out:
|
|
|
drbd_adm_finish(&adm_ctx, info, retcode);
|
|
|
return 0;
|
|
@@ -2698,7 +2703,7 @@ out:
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int drbd_bmio_set_susp_al(struct drbd_device *device)
|
|
|
+static int drbd_bmio_set_susp_al(struct drbd_device *device) __must_hold(local)
|
|
|
{
|
|
|
int rv;
|
|
|
|
|
@@ -2719,8 +2724,13 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (retcode != NO_ERROR)
|
|
|
goto out;
|
|
|
|
|
|
- mutex_lock(&adm_ctx.resource->adm_mutex);
|
|
|
device = adm_ctx.device;
|
|
|
+ if (!get_ldev(device)) {
|
|
|
+ retcode = ERR_NO_DISK;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_lock(&adm_ctx.resource->adm_mutex);
|
|
|
|
|
|
/* If there is still bitmap IO pending, probably because of a previous
|
|
|
* resync just being finished, wait for it before requesting a new resync.
|
|
@@ -2747,6 +2757,7 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
|
|
|
retcode = drbd_request_state(device, NS(conn, C_STARTING_SYNC_S));
|
|
|
drbd_resume_io(device);
|
|
|
mutex_unlock(&adm_ctx.resource->adm_mutex);
|
|
|
+ put_ldev(device);
|
|
|
out:
|
|
|
drbd_adm_finish(&adm_ctx, info, retcode);
|
|
|
return 0;
|