Commit 1a45dcfe2525e9432cb4aba461d4994fc2befe42

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block

* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  cfq-iosched: Do not idle on async queues
  blk-cgroup: Fix potential deadlock in blk-cgroup
  block: fix bugs in bio-integrity mempool usage
  block: fix bio_add_page for non trivial merge_bvec_fn case
  drbd: null dereference bug
  drbd: fix max_segment_size initialization

Showing 6 changed files Side-by-side Diff

... ... @@ -147,16 +147,16 @@
147 147 return -EINVAL;
148 148  
149 149 blkcg = cgroup_to_blkio_cgroup(cgroup);
  150 + spin_lock(&blkio_list_lock);
150 151 spin_lock_irq(&blkcg->lock);
151 152 blkcg->weight = (unsigned int)val;
152 153 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
153   - spin_lock(&blkio_list_lock);
154 154 list_for_each_entry(blkiop, &blkio_list, list)
155 155 blkiop->ops.blkio_update_group_weight_fn(blkg,
156 156 blkcg->weight);
157   - spin_unlock(&blkio_list_lock);
158 157 }
159 158 spin_unlock_irq(&blkcg->lock);
  159 + spin_unlock(&blkio_list_lock);
160 160 return 0;
161 161 }
162 162  
... ... @@ -1803,7 +1803,7 @@
1803 1803 * Otherwise, we do only if they are the last ones
1804 1804 * in their service tree.
1805 1805 */
1806   - return service_tree->count == 1;
  1806 + return service_tree->count == 1 && cfq_cfqq_sync(cfqq);
1807 1807 }
1808 1808  
1809 1809 static void cfq_arm_slice_timer(struct cfq_data *cfqd)
drivers/block/drbd/drbd_main.c
... ... @@ -2973,7 +2973,6 @@
2973 2973 goto out_no_q;
2974 2974 mdev->rq_queue = q;
2975 2975 q->queuedata = mdev;
2976   - blk_queue_max_segment_size(q, DRBD_MAX_SEGMENT_SIZE);
2977 2976  
2978 2977 disk = alloc_disk(1);
2979 2978 if (!disk)
... ... @@ -2997,6 +2996,7 @@
2997 2996 q->backing_dev_info.congested_data = mdev;
2998 2997  
2999 2998 blk_queue_make_request(q, drbd_make_request_26);
  2999 + blk_queue_max_segment_size(q, DRBD_MAX_SEGMENT_SIZE);
3000 3000 blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
3001 3001 blk_queue_merge_bvec(q, drbd_merge_bvec);
3002 3002 q->queue_lock = &mdev->req_lock; /* needed since we use */
drivers/block/drbd/drbd_receiver.c
... ... @@ -1224,7 +1224,7 @@
1224 1224 epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
1225 1225 if (!epoch) {
1226 1226 dev_warn(DEV, "Allocation of an epoch failed, slowing down\n");
1227   - issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags);
  1227 + issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags);
1228 1228 drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
1229 1229 if (issue_flush) {
1230 1230 rv = drbd_flush_after_epoch(mdev, mdev->current_epoch);
... ... @@ -61,7 +61,7 @@
61 61  
62 62 static inline int use_bip_pool(unsigned int idx)
63 63 {
64   - if (idx == BIOVEC_NR_POOLS)
  64 + if (idx == BIOVEC_MAX_IDX)
65 65 return 1;
66 66  
67 67 return 0;
... ... @@ -95,6 +95,7 @@
95 95  
96 96 /* Use mempool if lower order alloc failed or max vecs were requested */
97 97 if (bip == NULL) {
  98 + idx = BIOVEC_MAX_IDX; /* so we free the payload properly later */
98 99 bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
99 100  
100 101 if (unlikely(bip == NULL)) {
... ... @@ -542,13 +542,18 @@
542 542  
543 543 if (page == prev->bv_page &&
544 544 offset == prev->bv_offset + prev->bv_len) {
  545 + unsigned int prev_bv_len = prev->bv_len;
545 546 prev->bv_len += len;
546 547  
547 548 if (q->merge_bvec_fn) {
548 549 struct bvec_merge_data bvm = {
  550 + /* prev_bvec is already charged in
  551 + bi_size, discharge it in order to
  552 + simulate merging updated prev_bvec
  553 + as new bvec. */
549 554 .bi_bdev = bio->bi_bdev,
550 555 .bi_sector = bio->bi_sector,
551   - .bi_size = bio->bi_size,
  556 + .bi_size = bio->bi_size - prev_bv_len,
552 557 .bi_rw = bio->bi_rw,
553 558 };
554 559