diff options
Diffstat (limited to 'drivers/block/drbd/drbd_receiver.c')
| -rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 21 |
1 files changed, 16 insertions, 5 deletions
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; |
