diff options
Diffstat (limited to 'drivers/block/drbd/drbd_nl.c')
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 93d150661f4b..28ef76bd5230 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -2215,9 +2215,9 @@ void drbd_bcast_ee(struct drbd_conf *mdev, | |||
2215 | { | 2215 | { |
2216 | struct cn_msg *cn_reply; | 2216 | struct cn_msg *cn_reply; |
2217 | struct drbd_nl_cfg_reply *reply; | 2217 | struct drbd_nl_cfg_reply *reply; |
2218 | struct bio_vec *bvec; | ||
2219 | unsigned short *tl; | 2218 | unsigned short *tl; |
2220 | int i; | 2219 | struct page *page; |
2220 | unsigned len; | ||
2221 | 2221 | ||
2222 | if (!e) | 2222 | if (!e) |
2223 | return; | 2223 | return; |
@@ -2255,11 +2255,15 @@ void drbd_bcast_ee(struct drbd_conf *mdev, | |||
2255 | put_unaligned(T_ee_data, tl++); | 2255 | put_unaligned(T_ee_data, tl++); |
2256 | put_unaligned(e->size, tl++); | 2256 | put_unaligned(e->size, tl++); |
2257 | 2257 | ||
2258 | __bio_for_each_segment(bvec, e->private_bio, i, 0) { | 2258 | len = e->size; |
2259 | void *d = kmap(bvec->bv_page); | 2259 | page = e->pages; |
2260 | memcpy(tl, d + bvec->bv_offset, bvec->bv_len); | 2260 | page_chain_for_each(page) { |
2261 | kunmap(bvec->bv_page); | 2261 | void *d = kmap_atomic(page, KM_USER0); |
2262 | tl=(unsigned short*)((char*)tl + bvec->bv_len); | 2262 | unsigned l = min_t(unsigned, len, PAGE_SIZE); |
2263 | memcpy(tl, d, l); | ||
2264 | kunmap_atomic(d, KM_USER0); | ||
2265 | tl = (unsigned short*)((char*)tl + l); | ||
2266 | len -= l; | ||
2263 | } | 2267 | } |
2264 | put_unaligned(TT_END, tl++); /* Close the tag list */ | 2268 | put_unaligned(TT_END, tl++); /* Close the tag list */ |
2265 | 2269 | ||