diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2012-07-30 03:00:54 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-09 08:05:44 -0500 |
commit | 81a3537a9730116dfaafeed728f2d460c872c0d5 (patch) | |
tree | 44d6e0672f13830aa4a468818a0c2ce425a1cfac /drivers/block/drbd/drbd_receiver.c | |
parent | 58ffa580a748dd16b1e5ab260bea39cdbd1e94ef (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>
Diffstat (limited to 'drivers/block/drbd/drbd_receiver.c')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 22 |
1 files changed, 16 insertions, 6 deletions
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; |