diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2012-06-25 13:15:38 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-07-24 09:14:28 -0400 |
commit | a73ff3231df59a4b92ccd0dd4e73897c5822489b (patch) | |
tree | b4a702fefd94689682a6be89773ef7c59f20db59 | |
parent | db141b2f42b485b700465fe2401fbe65c65b190c (diff) |
drbd: announce FLUSH/FUA capability to upper layers
Unconditionally announce FLUSH/FUA to upper layers.
If the lower layers on either node do not actually support this,
generic_make_request() will deal with it.
If this causes performance regressions on your setup,
make sure there are no volatile caches involved,
and mount -o nobarrier or equivalent.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 6 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 21 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 3 |
4 files changed, 23 insertions, 8 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 6ace11e9e5a1..3fbef018ce55 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -876,7 +876,11 @@ int __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size, | |||
876 | unsigned int enr, count = 0; | 876 | unsigned int enr, count = 0; |
877 | struct lc_element *e; | 877 | struct lc_element *e; |
878 | 878 | ||
879 | if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_BIO_SIZE) { | 879 | /* this should be an empty REQ_FLUSH */ |
880 | if (size == 0) | ||
881 | return 0; | ||
882 | |||
883 | if (size < 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_BIO_SIZE) { | ||
880 | dev_err(DEV, "sector: %llus, size: %d\n", | 884 | dev_err(DEV, "sector: %llus, size: %d\n", |
881 | (unsigned long long)sector, size); | 885 | (unsigned long long)sector, size); |
882 | return 0; | 886 | return 0; |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 1ee1404769c2..2e0e7fc1dbba 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -3636,6 +3636,7 @@ struct drbd_conf *drbd_new_device(unsigned int minor) | |||
3636 | q->backing_dev_info.congested_data = mdev; | 3636 | q->backing_dev_info.congested_data = mdev; |
3637 | 3637 | ||
3638 | blk_queue_make_request(q, drbd_make_request); | 3638 | blk_queue_make_request(q, drbd_make_request); |
3639 | blk_queue_flush(q, REQ_FLUSH | REQ_FUA); | ||
3639 | /* Setting the max_hw_sectors to an odd value of 8kibyte here | 3640 | /* Setting the max_hw_sectors to an odd value of 8kibyte here |
3640 | This triggers a max_bio_size message upon first attach or connect */ | 3641 | This triggers a max_bio_size message upon first attach or connect */ |
3641 | blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8); | 3642 | blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8); |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 83d99133f94b..c74ca2df7431 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -277,6 +277,9 @@ static void drbd_pp_free(struct drbd_conf *mdev, struct page *page, int is_net) | |||
277 | atomic_t *a = is_net ? &mdev->pp_in_use_by_net : &mdev->pp_in_use; | 277 | atomic_t *a = is_net ? &mdev->pp_in_use_by_net : &mdev->pp_in_use; |
278 | int i; | 278 | int i; |
279 | 279 | ||
280 | if (page == NULL) | ||
281 | return; | ||
282 | |||
280 | if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE)*minor_count) | 283 | if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE)*minor_count) |
281 | i = page_chain_free(page); | 284 | i = page_chain_free(page); |
282 | else { | 285 | else { |
@@ -316,7 +319,7 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, | |||
316 | gfp_t gfp_mask) __must_hold(local) | 319 | gfp_t gfp_mask) __must_hold(local) |
317 | { | 320 | { |
318 | struct drbd_epoch_entry *e; | 321 | struct drbd_epoch_entry *e; |
319 | struct page *page; | 322 | struct page *page = NULL; |
320 | unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT; | 323 | unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT; |
321 | 324 | ||
322 | if (drbd_insert_fault(mdev, DRBD_FAULT_AL_EE)) | 325 | if (drbd_insert_fault(mdev, DRBD_FAULT_AL_EE)) |
@@ -329,9 +332,11 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, | |||
329 | return NULL; | 332 | return NULL; |
330 | } | 333 | } |
331 | 334 | ||
332 | page = drbd_pp_alloc(mdev, nr_pages, (gfp_mask & __GFP_WAIT)); | 335 | if (data_size) { |
333 | if (!page) | 336 | page = drbd_pp_alloc(mdev, nr_pages, (gfp_mask & __GFP_WAIT)); |
334 | goto fail; | 337 | if (!page) |
338 | goto fail; | ||
339 | } | ||
335 | 340 | ||
336 | INIT_HLIST_NODE(&e->collision); | 341 | INIT_HLIST_NODE(&e->collision); |
337 | e->epoch = NULL; | 342 | e->epoch = NULL; |
@@ -1270,7 +1275,6 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ | |||
1270 | 1275 | ||
1271 | data_size -= dgs; | 1276 | data_size -= dgs; |
1272 | 1277 | ||
1273 | ERR_IF(data_size == 0) return NULL; | ||
1274 | ERR_IF(data_size & 0x1ff) return NULL; | 1278 | ERR_IF(data_size & 0x1ff) return NULL; |
1275 | ERR_IF(data_size > DRBD_MAX_BIO_SIZE) return NULL; | 1279 | ERR_IF(data_size > DRBD_MAX_BIO_SIZE) return NULL; |
1276 | 1280 | ||
@@ -1291,6 +1295,9 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ | |||
1291 | if (!e) | 1295 | if (!e) |
1292 | return NULL; | 1296 | return NULL; |
1293 | 1297 | ||
1298 | if (!data_size) | ||
1299 | return e; | ||
1300 | |||
1294 | ds = data_size; | 1301 | ds = data_size; |
1295 | page = e->pages; | 1302 | page = e->pages; |
1296 | page_chain_for_each(page) { | 1303 | page_chain_for_each(page) { |
@@ -1715,6 +1722,10 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned | |||
1715 | 1722 | ||
1716 | dp_flags = be32_to_cpu(p->dp_flags); | 1723 | dp_flags = be32_to_cpu(p->dp_flags); |
1717 | rw |= wire_flags_to_bio(mdev, dp_flags); | 1724 | rw |= wire_flags_to_bio(mdev, dp_flags); |
1725 | if (e->pages == NULL) { | ||
1726 | D_ASSERT(e->size == 0); | ||
1727 | D_ASSERT(dp_flags & DP_FLUSH); | ||
1728 | } | ||
1718 | 1729 | ||
1719 | if (dp_flags & DP_MAY_SET_IN_SYNC) | 1730 | if (dp_flags & DP_MAY_SET_IN_SYNC) |
1720 | e->flags |= EE_MAY_SET_IN_SYNC; | 1731 | e->flags |= EE_MAY_SET_IN_SYNC; |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 1f4b2dbb7d4a..910335c30927 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -1111,13 +1111,12 @@ void drbd_make_request(struct request_queue *q, struct bio *bio) | |||
1111 | /* | 1111 | /* |
1112 | * what we "blindly" assume: | 1112 | * what we "blindly" assume: |
1113 | */ | 1113 | */ |
1114 | D_ASSERT(bio->bi_size > 0); | ||
1115 | D_ASSERT((bio->bi_size & 0x1ff) == 0); | 1114 | D_ASSERT((bio->bi_size & 0x1ff) == 0); |
1116 | 1115 | ||
1117 | /* to make some things easier, force alignment of requests within the | 1116 | /* to make some things easier, force alignment of requests within the |
1118 | * granularity of our hash tables */ | 1117 | * granularity of our hash tables */ |
1119 | s_enr = bio->bi_sector >> HT_SHIFT; | 1118 | s_enr = bio->bi_sector >> HT_SHIFT; |
1120 | e_enr = (bio->bi_sector+(bio->bi_size>>9)-1) >> HT_SHIFT; | 1119 | e_enr = bio->bi_size ? (bio->bi_sector+(bio->bi_size>>9)-1) >> HT_SHIFT : s_enr; |
1121 | 1120 | ||
1122 | if (likely(s_enr == e_enr)) { | 1121 | if (likely(s_enr == e_enr)) { |
1123 | do { | 1122 | do { |