aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-07-30 03:00:54 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-09 08:05:44 -0500
commit81a3537a9730116dfaafeed728f2d460c872c0d5 (patch)
tree44d6e0672f13830aa4a468818a0c2ce425a1cfac
parent58ffa580a748dd16b1e5ab260bea39cdbd1e94ef (diff)
drbd: announce FLUSH/FUA capability to upper layers
In 8.4, we may have bios spanning two activity log extents. Fixup drbd_al_begin_io() and drbd_al_complete_io() to deal with zero sized bios. 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.c12
-rw-r--r--drivers/block/drbd/drbd_main.c1
-rw-r--r--drivers/block/drbd/drbd_receiver.c22
-rw-r--r--drivers/block/drbd/drbd_req.c1
4 files changed, 26 insertions, 10 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 209b2e063b92..e81085795ec4 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -248,11 +248,12 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i)
248 /* for bios crossing activity log extent boundaries, 248 /* for bios crossing activity log extent boundaries,
249 * we may need to activate two extents in one go */ 249 * we may need to activate two extents in one go */
250 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); 250 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
251 unsigned last = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); 251 unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
252 unsigned enr; 252 unsigned enr;
253 bool locked = false; 253 bool locked = false;
254 254
255 255
256 D_ASSERT(first <= last);
256 D_ASSERT(atomic_read(&mdev->local_cnt) > 0); 257 D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
257 258
258 for (enr = first; enr <= last; enr++) 259 for (enr = first; enr <= last; enr++)
@@ -305,11 +306,12 @@ void drbd_al_complete_io(struct drbd_conf *mdev, struct drbd_interval *i)
305 /* for bios crossing activity log extent boundaries, 306 /* for bios crossing activity log extent boundaries,
306 * we may need to activate two extents in one go */ 307 * we may need to activate two extents in one go */
307 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); 308 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
308 unsigned last = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); 309 unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
309 unsigned enr; 310 unsigned enr;
310 struct lc_element *extent; 311 struct lc_element *extent;
311 unsigned long flags; 312 unsigned long flags;
312 313
314 D_ASSERT(first <= last);
313 spin_lock_irqsave(&mdev->al_lock, flags); 315 spin_lock_irqsave(&mdev->al_lock, flags);
314 316
315 for (enr = first; enr <= last; enr++) { 317 for (enr = first; enr <= last; enr++) {
@@ -756,7 +758,11 @@ int __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size,
756 unsigned int enr, count = 0; 758 unsigned int enr, count = 0;
757 struct lc_element *e; 759 struct lc_element *e;
758 760
759 if (size <= 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) { 761 /* this should be an empty REQ_FLUSH */
762 if (size == 0)
763 return 0;
764
765 if (size < 0 || !IS_ALIGNED(size, 512) || size > DRBD_MAX_BIO_SIZE) {
760 dev_err(DEV, "sector: %llus, size: %d\n", 766 dev_err(DEV, "sector: %llus, size: %d\n",
761 (unsigned long long)sector, size); 767 (unsigned long long)sector, size);
762 return 0; 768 return 0;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index f2af74d06860..85d95ec405ef 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2640,6 +2640,7 @@ enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor,
2640 q->backing_dev_info.congested_data = mdev; 2640 q->backing_dev_info.congested_data = mdev;
2641 2641
2642 blk_queue_make_request(q, drbd_make_request); 2642 blk_queue_make_request(q, drbd_make_request);
2643 blk_queue_flush(q, REQ_FLUSH | REQ_FUA);
2643 /* Setting the max_hw_sectors to an odd value of 8kibyte here 2644 /* Setting the max_hw_sectors to an odd value of 8kibyte here
2644 This triggers a max_bio_size message upon first attach or connect */ 2645 This triggers a max_bio_size message upon first attach or connect */
2645 blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8); 2646 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 8fddec96dfbe..a6f0b2938363 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -295,6 +295,9 @@ static void drbd_free_pages(struct drbd_conf *mdev, struct page *page, int is_ne
295 atomic_t *a = is_net ? &mdev->pp_in_use_by_net : &mdev->pp_in_use; 295 atomic_t *a = is_net ? &mdev->pp_in_use_by_net : &mdev->pp_in_use;
296 int i; 296 int i;
297 297
298 if (page == NULL)
299 return;
300
298 if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count) 301 if (drbd_pp_vacant > (DRBD_MAX_BIO_SIZE/PAGE_SIZE) * minor_count)
299 i = page_chain_free(page); 302 i = page_chain_free(page);
300 else { 303 else {
@@ -331,7 +334,7 @@ drbd_alloc_peer_req(struct drbd_conf *mdev, u64 id, sector_t sector,
331 unsigned int data_size, gfp_t gfp_mask) __must_hold(local) 334 unsigned int data_size, gfp_t gfp_mask) __must_hold(local)
332{ 335{
333 struct drbd_peer_request *peer_req; 336 struct drbd_peer_request *peer_req;
334 struct page *page; 337 struct page *page = NULL;
335 unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT; 338 unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT;
336 339
337 if (drbd_insert_fault(mdev, DRBD_FAULT_AL_EE)) 340 if (drbd_insert_fault(mdev, DRBD_FAULT_AL_EE))
@@ -344,9 +347,11 @@ drbd_alloc_peer_req(struct drbd_conf *mdev, u64 id, sector_t sector,
344 return NULL; 347 return NULL;
345 } 348 }
346 349
347 page = drbd_alloc_pages(mdev, nr_pages, (gfp_mask & __GFP_WAIT)); 350 if (data_size) {
348 if (!page) 351 page = drbd_alloc_pages(mdev, nr_pages, (gfp_mask & __GFP_WAIT));
349 goto fail; 352 if (!page)
353 goto fail;
354 }
350 355
351 drbd_clear_interval(&peer_req->i); 356 drbd_clear_interval(&peer_req->i);
352 peer_req->i.size = data_size; 357 peer_req->i.size = data_size;
@@ -1513,8 +1518,6 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
1513 data_size -= dgs; 1518 data_size -= dgs;
1514 } 1519 }
1515 1520
1516 if (!expect(data_size != 0))
1517 return NULL;
1518 if (!expect(IS_ALIGNED(data_size, 512))) 1521 if (!expect(IS_ALIGNED(data_size, 512)))
1519 return NULL; 1522 return NULL;
1520 if (!expect(data_size <= DRBD_MAX_BIO_SIZE)) 1523 if (!expect(data_size <= DRBD_MAX_BIO_SIZE))
@@ -1537,6 +1540,9 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector,
1537 if (!peer_req) 1540 if (!peer_req)
1538 return NULL; 1541 return NULL;
1539 1542
1543 if (!data_size)
1544 return peer_req;
1545
1540 ds = data_size; 1546 ds = data_size;
1541 page = peer_req->pages; 1547 page = peer_req->pages;
1542 page_chain_for_each(page) { 1548 page_chain_for_each(page) {
@@ -2199,6 +2205,10 @@ static int receive_Data(struct drbd_tconn *tconn, struct packet_info *pi)
2199 2205
2200 dp_flags = be32_to_cpu(p->dp_flags); 2206 dp_flags = be32_to_cpu(p->dp_flags);
2201 rw |= wire_flags_to_bio(mdev, dp_flags); 2207 rw |= wire_flags_to_bio(mdev, dp_flags);
2208 if (peer_req->pages == NULL) {
2209 D_ASSERT(peer_req->i.size == 0);
2210 D_ASSERT(dp_flags & DP_FLUSH);
2211 }
2202 2212
2203 if (dp_flags & DP_MAY_SET_IN_SYNC) 2213 if (dp_flags & DP_MAY_SET_IN_SYNC)
2204 peer_req->flags |= EE_MAY_SET_IN_SYNC; 2214 peer_req->flags |= EE_MAY_SET_IN_SYNC;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index e215dce4c694..8323449fbbab 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -1097,7 +1097,6 @@ int drbd_make_request(struct request_queue *q, struct bio *bio)
1097 /* 1097 /*
1098 * what we "blindly" assume: 1098 * what we "blindly" assume:
1099 */ 1099 */
1100 D_ASSERT(bio->bi_size > 0);
1101 D_ASSERT(IS_ALIGNED(bio->bi_size, 512)); 1100 D_ASSERT(IS_ALIGNED(bio->bi_size, 512));
1102 1101
1103 inc_ap_bio(mdev); 1102 inc_ap_bio(mdev);