diff options
31 files changed, 94 insertions, 125 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index e17da947f6bd..0ac817b750db 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -822,7 +822,6 @@ static void blkcg_css_free(struct cgroup_subsys_state *css) | |||
822 | static struct cgroup_subsys_state * | 822 | static struct cgroup_subsys_state * |
823 | blkcg_css_alloc(struct cgroup_subsys_state *parent_css) | 823 | blkcg_css_alloc(struct cgroup_subsys_state *parent_css) |
824 | { | 824 | { |
825 | static atomic64_t id_seq = ATOMIC64_INIT(0); | ||
826 | struct blkcg *blkcg; | 825 | struct blkcg *blkcg; |
827 | 826 | ||
828 | if (!parent_css) { | 827 | if (!parent_css) { |
@@ -836,7 +835,6 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css) | |||
836 | 835 | ||
837 | blkcg->cfq_weight = CFQ_WEIGHT_DEFAULT; | 836 | blkcg->cfq_weight = CFQ_WEIGHT_DEFAULT; |
838 | blkcg->cfq_leaf_weight = CFQ_WEIGHT_DEFAULT; | 837 | blkcg->cfq_leaf_weight = CFQ_WEIGHT_DEFAULT; |
839 | blkcg->id = atomic64_inc_return(&id_seq); /* root is 0, start from 1 */ | ||
840 | done: | 838 | done: |
841 | spin_lock_init(&blkcg->lock); | 839 | spin_lock_init(&blkcg->lock); |
842 | INIT_RADIX_TREE(&blkcg->blkg_tree, GFP_ATOMIC); | 840 | INIT_RADIX_TREE(&blkcg->blkg_tree, GFP_ATOMIC); |
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h index d3fd7aa3d2a3..c567865b5f1d 100644 --- a/block/blk-cgroup.h +++ b/block/blk-cgroup.h | |||
@@ -50,9 +50,6 @@ struct blkcg { | |||
50 | struct blkcg_gq *blkg_hint; | 50 | struct blkcg_gq *blkg_hint; |
51 | struct hlist_head blkg_list; | 51 | struct hlist_head blkg_list; |
52 | 52 | ||
53 | /* for policies to test whether associated blkcg has changed */ | ||
54 | uint64_t id; | ||
55 | |||
56 | /* TODO: per-policy storage in blkcg */ | 53 | /* TODO: per-policy storage in blkcg */ |
57 | unsigned int cfq_weight; /* belongs to cfq */ | 54 | unsigned int cfq_weight; /* belongs to cfq */ |
58 | unsigned int cfq_leaf_weight; | 55 | unsigned int cfq_leaf_weight; |
diff --git a/block/blk-core.c b/block/blk-core.c index bf930f481d43..6946a4275e6f 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -83,18 +83,14 @@ void blk_queue_congestion_threshold(struct request_queue *q) | |||
83 | * @bdev: device | 83 | * @bdev: device |
84 | * | 84 | * |
85 | * Locates the passed device's request queue and returns the address of its | 85 | * Locates the passed device's request queue and returns the address of its |
86 | * backing_dev_info | 86 | * backing_dev_info. This function can only be called if @bdev is opened |
87 | * | 87 | * and the return value is never NULL. |
88 | * Will return NULL if the request queue cannot be located. | ||
89 | */ | 88 | */ |
90 | struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev) | 89 | struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev) |
91 | { | 90 | { |
92 | struct backing_dev_info *ret = NULL; | ||
93 | struct request_queue *q = bdev_get_queue(bdev); | 91 | struct request_queue *q = bdev_get_queue(bdev); |
94 | 92 | ||
95 | if (q) | 93 | return &q->backing_dev_info; |
96 | ret = &q->backing_dev_info; | ||
97 | return ret; | ||
98 | } | 94 | } |
99 | EXPORT_SYMBOL(blk_get_backing_dev_info); | 95 | EXPORT_SYMBOL(blk_get_backing_dev_info); |
100 | 96 | ||
@@ -933,9 +929,9 @@ static struct io_context *rq_ioc(struct bio *bio) | |||
933 | * Get a free request from @q. This function may fail under memory | 929 | * Get a free request from @q. This function may fail under memory |
934 | * pressure or if @q is dead. | 930 | * pressure or if @q is dead. |
935 | * | 931 | * |
936 | * Must be callled with @q->queue_lock held and, | 932 | * Must be called with @q->queue_lock held and, |
937 | * Returns %NULL on failure, with @q->queue_lock held. | 933 | * Returns ERR_PTR on failure, with @q->queue_lock held. |
938 | * Returns !%NULL on success, with @q->queue_lock *not held*. | 934 | * Returns request pointer on success, with @q->queue_lock *not held*. |
939 | */ | 935 | */ |
940 | static struct request *__get_request(struct request_list *rl, int rw_flags, | 936 | static struct request *__get_request(struct request_list *rl, int rw_flags, |
941 | struct bio *bio, gfp_t gfp_mask) | 937 | struct bio *bio, gfp_t gfp_mask) |
@@ -949,7 +945,7 @@ static struct request *__get_request(struct request_list *rl, int rw_flags, | |||
949 | int may_queue; | 945 | int may_queue; |
950 | 946 | ||
951 | if (unlikely(blk_queue_dying(q))) | 947 | if (unlikely(blk_queue_dying(q))) |
952 | return NULL; | 948 | return ERR_PTR(-ENODEV); |
953 | 949 | ||
954 | may_queue = elv_may_queue(q, rw_flags); | 950 | may_queue = elv_may_queue(q, rw_flags); |
955 | if (may_queue == ELV_MQUEUE_NO) | 951 | if (may_queue == ELV_MQUEUE_NO) |
@@ -974,7 +970,7 @@ static struct request *__get_request(struct request_list *rl, int rw_flags, | |||
974 | * process is not a "batcher", and not | 970 | * process is not a "batcher", and not |
975 | * exempted by the IO scheduler | 971 | * exempted by the IO scheduler |
976 | */ | 972 | */ |
977 | return NULL; | 973 | return ERR_PTR(-ENOMEM); |
978 | } | 974 | } |
979 | } | 975 | } |
980 | } | 976 | } |
@@ -992,7 +988,7 @@ static struct request *__get_request(struct request_list *rl, int rw_flags, | |||
992 | * allocated with any setting of ->nr_requests | 988 | * allocated with any setting of ->nr_requests |
993 | */ | 989 | */ |
994 | if (rl->count[is_sync] >= (3 * q->nr_requests / 2)) | 990 | if (rl->count[is_sync] >= (3 * q->nr_requests / 2)) |
995 | return NULL; | 991 | return ERR_PTR(-ENOMEM); |
996 | 992 | ||
997 | q->nr_rqs[is_sync]++; | 993 | q->nr_rqs[is_sync]++; |
998 | rl->count[is_sync]++; | 994 | rl->count[is_sync]++; |
@@ -1097,7 +1093,7 @@ fail_alloc: | |||
1097 | rq_starved: | 1093 | rq_starved: |
1098 | if (unlikely(rl->count[is_sync] == 0)) | 1094 | if (unlikely(rl->count[is_sync] == 0)) |
1099 | rl->starved[is_sync] = 1; | 1095 | rl->starved[is_sync] = 1; |
1100 | return NULL; | 1096 | return ERR_PTR(-ENOMEM); |
1101 | } | 1097 | } |
1102 | 1098 | ||
1103 | /** | 1099 | /** |
@@ -1110,9 +1106,9 @@ rq_starved: | |||
1110 | * Get a free request from @q. If %__GFP_WAIT is set in @gfp_mask, this | 1106 | * Get a free request from @q. If %__GFP_WAIT is set in @gfp_mask, this |
1111 | * function keeps retrying under memory pressure and fails iff @q is dead. | 1107 | * function keeps retrying under memory pressure and fails iff @q is dead. |
1112 | * | 1108 | * |
1113 | * Must be callled with @q->queue_lock held and, | 1109 | * Must be called with @q->queue_lock held and, |
1114 | * Returns %NULL on failure, with @q->queue_lock held. | 1110 | * Returns ERR_PTR on failure, with @q->queue_lock held. |
1115 | * Returns !%NULL on success, with @q->queue_lock *not held*. | 1111 | * Returns request pointer on success, with @q->queue_lock *not held*. |
1116 | */ | 1112 | */ |
1117 | static struct request *get_request(struct request_queue *q, int rw_flags, | 1113 | static struct request *get_request(struct request_queue *q, int rw_flags, |
1118 | struct bio *bio, gfp_t gfp_mask) | 1114 | struct bio *bio, gfp_t gfp_mask) |
@@ -1125,12 +1121,12 @@ static struct request *get_request(struct request_queue *q, int rw_flags, | |||
1125 | rl = blk_get_rl(q, bio); /* transferred to @rq on success */ | 1121 | rl = blk_get_rl(q, bio); /* transferred to @rq on success */ |
1126 | retry: | 1122 | retry: |
1127 | rq = __get_request(rl, rw_flags, bio, gfp_mask); | 1123 | rq = __get_request(rl, rw_flags, bio, gfp_mask); |
1128 | if (rq) | 1124 | if (!IS_ERR(rq)) |
1129 | return rq; | 1125 | return rq; |
1130 | 1126 | ||
1131 | if (!(gfp_mask & __GFP_WAIT) || unlikely(blk_queue_dying(q))) { | 1127 | if (!(gfp_mask & __GFP_WAIT) || unlikely(blk_queue_dying(q))) { |
1132 | blk_put_rl(rl); | 1128 | blk_put_rl(rl); |
1133 | return NULL; | 1129 | return rq; |
1134 | } | 1130 | } |
1135 | 1131 | ||
1136 | /* wait on @rl and retry */ | 1132 | /* wait on @rl and retry */ |
@@ -1167,7 +1163,7 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw, | |||
1167 | 1163 | ||
1168 | spin_lock_irq(q->queue_lock); | 1164 | spin_lock_irq(q->queue_lock); |
1169 | rq = get_request(q, rw, NULL, gfp_mask); | 1165 | rq = get_request(q, rw, NULL, gfp_mask); |
1170 | if (!rq) | 1166 | if (IS_ERR(rq)) |
1171 | spin_unlock_irq(q->queue_lock); | 1167 | spin_unlock_irq(q->queue_lock); |
1172 | /* q->queue_lock is unlocked at this point */ | 1168 | /* q->queue_lock is unlocked at this point */ |
1173 | 1169 | ||
@@ -1219,8 +1215,8 @@ struct request *blk_make_request(struct request_queue *q, struct bio *bio, | |||
1219 | { | 1215 | { |
1220 | struct request *rq = blk_get_request(q, bio_data_dir(bio), gfp_mask); | 1216 | struct request *rq = blk_get_request(q, bio_data_dir(bio), gfp_mask); |
1221 | 1217 | ||
1222 | if (unlikely(!rq)) | 1218 | if (IS_ERR(rq)) |
1223 | return ERR_PTR(-ENOMEM); | 1219 | return rq; |
1224 | 1220 | ||
1225 | blk_rq_set_block_pc(rq); | 1221 | blk_rq_set_block_pc(rq); |
1226 | 1222 | ||
@@ -1614,8 +1610,8 @@ get_rq: | |||
1614 | * Returns with the queue unlocked. | 1610 | * Returns with the queue unlocked. |
1615 | */ | 1611 | */ |
1616 | req = get_request(q, rw_flags, bio, GFP_NOIO); | 1612 | req = get_request(q, rw_flags, bio, GFP_NOIO); |
1617 | if (unlikely(!req)) { | 1613 | if (IS_ERR(req)) { |
1618 | bio_endio(bio, -ENODEV); /* @q is dead */ | 1614 | bio_endio(bio, PTR_ERR(req)); /* @q is dead */ |
1619 | goto out_unlock; | 1615 | goto out_unlock; |
1620 | } | 1616 | } |
1621 | 1617 | ||
diff --git a/block/blk-mq.c b/block/blk-mq.c index c88e6089746d..e743d28620b2 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -223,9 +223,11 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, | |||
223 | struct blk_mq_hw_ctx *hctx; | 223 | struct blk_mq_hw_ctx *hctx; |
224 | struct request *rq; | 224 | struct request *rq; |
225 | struct blk_mq_alloc_data alloc_data; | 225 | struct blk_mq_alloc_data alloc_data; |
226 | int ret; | ||
226 | 227 | ||
227 | if (blk_mq_queue_enter(q)) | 228 | ret = blk_mq_queue_enter(q); |
228 | return NULL; | 229 | if (ret) |
230 | return ERR_PTR(ret); | ||
229 | 231 | ||
230 | ctx = blk_mq_get_ctx(q); | 232 | ctx = blk_mq_get_ctx(q); |
231 | hctx = q->mq_ops->map_queue(q, ctx->cpu); | 233 | hctx = q->mq_ops->map_queue(q, ctx->cpu); |
@@ -245,6 +247,8 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, | |||
245 | ctx = alloc_data.ctx; | 247 | ctx = alloc_data.ctx; |
246 | } | 248 | } |
247 | blk_mq_put_ctx(ctx); | 249 | blk_mq_put_ctx(ctx); |
250 | if (!rq) | ||
251 | return ERR_PTR(-EWOULDBLOCK); | ||
248 | return rq; | 252 | return rq; |
249 | } | 253 | } |
250 | EXPORT_SYMBOL(blk_mq_alloc_request); | 254 | EXPORT_SYMBOL(blk_mq_alloc_request); |
diff --git a/block/bsg.c b/block/bsg.c index ff46addde5d8..276e869e686c 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -270,8 +270,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, | |||
270 | * map scatter-gather elements separately and string them to request | 270 | * map scatter-gather elements separately and string them to request |
271 | */ | 271 | */ |
272 | rq = blk_get_request(q, rw, GFP_KERNEL); | 272 | rq = blk_get_request(q, rw, GFP_KERNEL); |
273 | if (!rq) | 273 | if (IS_ERR(rq)) |
274 | return ERR_PTR(-ENOMEM); | 274 | return rq; |
275 | blk_rq_set_block_pc(rq); | 275 | blk_rq_set_block_pc(rq); |
276 | 276 | ||
277 | ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm); | 277 | ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm); |
@@ -285,8 +285,9 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, | |||
285 | } | 285 | } |
286 | 286 | ||
287 | next_rq = blk_get_request(q, READ, GFP_KERNEL); | 287 | next_rq = blk_get_request(q, READ, GFP_KERNEL); |
288 | if (!next_rq) { | 288 | if (IS_ERR(next_rq)) { |
289 | ret = -ENOMEM; | 289 | ret = PTR_ERR(next_rq); |
290 | next_rq = NULL; | ||
290 | goto out; | 291 | goto out; |
291 | } | 292 | } |
292 | rq->next_rq = next_rq; | 293 | rq->next_rq = next_rq; |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 3f31cf9508e6..6f2751d305de 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -299,7 +299,7 @@ struct cfq_io_cq { | |||
299 | struct cfq_ttime ttime; | 299 | struct cfq_ttime ttime; |
300 | int ioprio; /* the current ioprio */ | 300 | int ioprio; /* the current ioprio */ |
301 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | 301 | #ifdef CONFIG_CFQ_GROUP_IOSCHED |
302 | uint64_t blkcg_id; /* the current blkcg ID */ | 302 | uint64_t blkcg_serial_nr; /* the current blkcg serial */ |
303 | #endif | 303 | #endif |
304 | }; | 304 | }; |
305 | 305 | ||
@@ -3547,17 +3547,17 @@ static void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio) | |||
3547 | { | 3547 | { |
3548 | struct cfq_data *cfqd = cic_to_cfqd(cic); | 3548 | struct cfq_data *cfqd = cic_to_cfqd(cic); |
3549 | struct cfq_queue *sync_cfqq; | 3549 | struct cfq_queue *sync_cfqq; |
3550 | uint64_t id; | 3550 | uint64_t serial_nr; |
3551 | 3551 | ||
3552 | rcu_read_lock(); | 3552 | rcu_read_lock(); |
3553 | id = bio_blkcg(bio)->id; | 3553 | serial_nr = bio_blkcg(bio)->css.serial_nr; |
3554 | rcu_read_unlock(); | 3554 | rcu_read_unlock(); |
3555 | 3555 | ||
3556 | /* | 3556 | /* |
3557 | * Check whether blkcg has changed. The condition may trigger | 3557 | * Check whether blkcg has changed. The condition may trigger |
3558 | * spuriously on a newly created cic but there's no harm. | 3558 | * spuriously on a newly created cic but there's no harm. |
3559 | */ | 3559 | */ |
3560 | if (unlikely(!cfqd) || likely(cic->blkcg_id == id)) | 3560 | if (unlikely(!cfqd) || likely(cic->blkcg_serial_nr == serial_nr)) |
3561 | return; | 3561 | return; |
3562 | 3562 | ||
3563 | sync_cfqq = cic_to_cfqq(cic, 1); | 3563 | sync_cfqq = cic_to_cfqq(cic, 1); |
@@ -3571,7 +3571,7 @@ static void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio) | |||
3571 | cfq_put_queue(sync_cfqq); | 3571 | cfq_put_queue(sync_cfqq); |
3572 | } | 3572 | } |
3573 | 3573 | ||
3574 | cic->blkcg_id = id; | 3574 | cic->blkcg_serial_nr = serial_nr; |
3575 | } | 3575 | } |
3576 | #else | 3576 | #else |
3577 | static inline void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio) { } | 3577 | static inline void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio) { } |
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 18b282ce361e..f678c733df40 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
@@ -709,8 +709,6 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
709 | if (!arg) | 709 | if (!arg) |
710 | return -EINVAL; | 710 | return -EINVAL; |
711 | bdi = blk_get_backing_dev_info(bdev); | 711 | bdi = blk_get_backing_dev_info(bdev); |
712 | if (bdi == NULL) | ||
713 | return -ENOTTY; | ||
714 | return compat_put_long(arg, | 712 | return compat_put_long(arg, |
715 | (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); | 713 | (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); |
716 | case BLKROGET: /* compatible */ | 714 | case BLKROGET: /* compatible */ |
@@ -731,8 +729,6 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
731 | if (!capable(CAP_SYS_ADMIN)) | 729 | if (!capable(CAP_SYS_ADMIN)) |
732 | return -EACCES; | 730 | return -EACCES; |
733 | bdi = blk_get_backing_dev_info(bdev); | 731 | bdi = blk_get_backing_dev_info(bdev); |
734 | if (bdi == NULL) | ||
735 | return -ENOTTY; | ||
736 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; | 732 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; |
737 | return 0; | 733 | return 0; |
738 | case BLKGETSIZE: | 734 | case BLKGETSIZE: |
diff --git a/block/ioctl.c b/block/ioctl.c index d6cda8147c91..6c7bf903742f 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
@@ -356,8 +356,6 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
356 | if (!arg) | 356 | if (!arg) |
357 | return -EINVAL; | 357 | return -EINVAL; |
358 | bdi = blk_get_backing_dev_info(bdev); | 358 | bdi = blk_get_backing_dev_info(bdev); |
359 | if (bdi == NULL) | ||
360 | return -ENOTTY; | ||
361 | return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); | 359 | return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); |
362 | case BLKROGET: | 360 | case BLKROGET: |
363 | return put_int(arg, bdev_read_only(bdev) != 0); | 361 | return put_int(arg, bdev_read_only(bdev) != 0); |
@@ -386,8 +384,6 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
386 | if(!capable(CAP_SYS_ADMIN)) | 384 | if(!capable(CAP_SYS_ADMIN)) |
387 | return -EACCES; | 385 | return -EACCES; |
388 | bdi = blk_get_backing_dev_info(bdev); | 386 | bdi = blk_get_backing_dev_info(bdev); |
389 | if (bdi == NULL) | ||
390 | return -ENOTTY; | ||
391 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; | 387 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; |
392 | return 0; | 388 | return 0; |
393 | case BLKBSZSET: | 389 | case BLKBSZSET: |
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 9b8eaeca6a79..abb2e65b24cc 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -316,8 +316,8 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, | |||
316 | 316 | ||
317 | ret = -ENOMEM; | 317 | ret = -ENOMEM; |
318 | rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); | 318 | rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); |
319 | if (!rq) | 319 | if (IS_ERR(rq)) |
320 | goto out; | 320 | return PTR_ERR(rq); |
321 | blk_rq_set_block_pc(rq); | 321 | blk_rq_set_block_pc(rq); |
322 | 322 | ||
323 | if (hdr->cmd_len > BLK_MAX_CDB) { | 323 | if (hdr->cmd_len > BLK_MAX_CDB) { |
@@ -387,7 +387,6 @@ out_free_cdb: | |||
387 | kfree(rq->cmd); | 387 | kfree(rq->cmd); |
388 | out_put_request: | 388 | out_put_request: |
389 | blk_put_request(rq); | 389 | blk_put_request(rq); |
390 | out: | ||
391 | return ret; | 390 | return ret; |
392 | } | 391 | } |
393 | 392 | ||
@@ -457,8 +456,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, | |||
457 | } | 456 | } |
458 | 457 | ||
459 | rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT); | 458 | rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT); |
460 | if (!rq) { | 459 | if (IS_ERR(rq)) { |
461 | err = -ENOMEM; | 460 | err = PTR_ERR(rq); |
462 | goto error; | 461 | goto error; |
463 | } | 462 | } |
464 | blk_rq_set_block_pc(rq); | 463 | blk_rq_set_block_pc(rq); |
@@ -548,6 +547,8 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, | |||
548 | int err; | 547 | int err; |
549 | 548 | ||
550 | rq = blk_get_request(q, WRITE, __GFP_WAIT); | 549 | rq = blk_get_request(q, WRITE, __GFP_WAIT); |
550 | if (IS_ERR(rq)) | ||
551 | return PTR_ERR(rq); | ||
551 | blk_rq_set_block_pc(rq); | 552 | blk_rq_set_block_pc(rq); |
552 | rq->timeout = BLK_DEFAULT_SG_TIMEOUT; | 553 | rq->timeout = BLK_DEFAULT_SG_TIMEOUT; |
553 | rq->cmd[0] = cmd; | 554 | rq->cmd[0] = cmd; |
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index fea7e76a00de..d48715b287e6 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c | |||
@@ -722,6 +722,8 @@ static int pd_special_command(struct pd_unit *disk, | |||
722 | int err = 0; | 722 | int err = 0; |
723 | 723 | ||
724 | rq = blk_get_request(disk->gd->queue, READ, __GFP_WAIT); | 724 | rq = blk_get_request(disk->gd->queue, READ, __GFP_WAIT); |
725 | if (IS_ERR(rq)) | ||
726 | return PTR_ERR(rq); | ||
725 | 727 | ||
726 | rq->cmd_type = REQ_TYPE_SPECIAL; | 728 | rq->cmd_type = REQ_TYPE_SPECIAL; |
727 | rq->special = func; | 729 | rq->special = func; |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 758ac442c5b5..09e628dafd9d 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -704,6 +704,8 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * | |||
704 | 704 | ||
705 | rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? | 705 | rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? |
706 | WRITE : READ, __GFP_WAIT); | 706 | WRITE : READ, __GFP_WAIT); |
707 | if (IS_ERR(rq)) | ||
708 | return PTR_ERR(rq); | ||
707 | blk_rq_set_block_pc(rq); | 709 | blk_rq_set_block_pc(rq); |
708 | 710 | ||
709 | if (cgc->buflen) { | 711 | if (cgc->buflen) { |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index d5e2d12b9d9e..5d552857de41 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
@@ -568,7 +568,7 @@ static struct carm_request *carm_get_special(struct carm_host *host) | |||
568 | return NULL; | 568 | return NULL; |
569 | 569 | ||
570 | rq = blk_get_request(host->oob_q, WRITE /* bogus */, GFP_KERNEL); | 570 | rq = blk_get_request(host->oob_q, WRITE /* bogus */, GFP_KERNEL); |
571 | if (!rq) { | 571 | if (IS_ERR(rq)) { |
572 | spin_lock_irqsave(&host->lock, flags); | 572 | spin_lock_irqsave(&host->lock, flags); |
573 | carm_put_request(host, crq); | 573 | carm_put_request(host, crq); |
574 | spin_unlock_irqrestore(&host->lock, flags); | 574 | spin_unlock_irqrestore(&host->lock, flags); |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 898b84bba28a..5d28a45d2960 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -2180,8 +2180,8 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, | |||
2180 | len = nr * CD_FRAMESIZE_RAW; | 2180 | len = nr * CD_FRAMESIZE_RAW; |
2181 | 2181 | ||
2182 | rq = blk_get_request(q, READ, GFP_KERNEL); | 2182 | rq = blk_get_request(q, READ, GFP_KERNEL); |
2183 | if (!rq) { | 2183 | if (IS_ERR(rq)) { |
2184 | ret = -ENOMEM; | 2184 | ret = PTR_ERR(rq); |
2185 | break; | 2185 | break; |
2186 | } | 2186 | } |
2187 | blk_rq_set_block_pc(rq); | 2187 | blk_rq_set_block_pc(rq); |
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index f41558a0bcd1..ca958604cda2 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c | |||
@@ -46,7 +46,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) | |||
46 | * timeout has expired, so power management will be reenabled. | 46 | * timeout has expired, so power management will be reenabled. |
47 | */ | 47 | */ |
48 | rq = blk_get_request(q, READ, GFP_NOWAIT); | 48 | rq = blk_get_request(q, READ, GFP_NOWAIT); |
49 | if (unlikely(!rq)) | 49 | if (IS_ERR(rq)) |
50 | goto out; | 50 | goto out; |
51 | 51 | ||
52 | rq->cmd[0] = REQ_UNPARK_HEADS; | 52 | rq->cmd[0] = REQ_UNPARK_HEADS; |
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7bcf67eec921..e99507ed0e3c 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -115,7 +115,7 @@ static struct request *get_alua_req(struct scsi_device *sdev, | |||
115 | 115 | ||
116 | rq = blk_get_request(q, rw, GFP_NOIO); | 116 | rq = blk_get_request(q, rw, GFP_NOIO); |
117 | 117 | ||
118 | if (!rq) { | 118 | if (IS_ERR(rq)) { |
119 | sdev_printk(KERN_INFO, sdev, | 119 | sdev_printk(KERN_INFO, sdev, |
120 | "%s: blk_get_request failed\n", __func__); | 120 | "%s: blk_get_request failed\n", __func__); |
121 | return NULL; | 121 | return NULL; |
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 6f07f7fe3aa1..84765384c47c 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -275,7 +275,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, | |||
275 | 275 | ||
276 | rq = blk_get_request(sdev->request_queue, | 276 | rq = blk_get_request(sdev->request_queue, |
277 | (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO); | 277 | (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO); |
278 | if (!rq) { | 278 | if (IS_ERR(rq)) { |
279 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); | 279 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); |
280 | return NULL; | 280 | return NULL; |
281 | } | 281 | } |
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index e9d9fea9e272..4ee2759f5299 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c | |||
@@ -117,7 +117,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) | |||
117 | 117 | ||
118 | retry: | 118 | retry: |
119 | req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); | 119 | req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); |
120 | if (!req) | 120 | if (IS_ERR(req)) |
121 | return SCSI_DH_RES_TEMP_UNAVAIL; | 121 | return SCSI_DH_RES_TEMP_UNAVAIL; |
122 | 122 | ||
123 | blk_rq_set_block_pc(req); | 123 | blk_rq_set_block_pc(req); |
@@ -247,7 +247,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h) | |||
247 | struct request *req; | 247 | struct request *req; |
248 | 248 | ||
249 | req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC); | 249 | req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC); |
250 | if (!req) | 250 | if (IS_ERR(req)) |
251 | return SCSI_DH_RES_TEMP_UNAVAIL; | 251 | return SCSI_DH_RES_TEMP_UNAVAIL; |
252 | 252 | ||
253 | blk_rq_set_block_pc(req); | 253 | blk_rq_set_block_pc(req); |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 826069db9848..1b5bc9293e37 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
@@ -274,7 +274,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev, | |||
274 | 274 | ||
275 | rq = blk_get_request(q, rw, GFP_NOIO); | 275 | rq = blk_get_request(q, rw, GFP_NOIO); |
276 | 276 | ||
277 | if (!rq) { | 277 | if (IS_ERR(rq)) { |
278 | sdev_printk(KERN_INFO, sdev, | 278 | sdev_printk(KERN_INFO, sdev, |
279 | "get_rdac_req: blk_get_request failed.\n"); | 279 | "get_rdac_req: blk_get_request failed.\n"); |
280 | return NULL; | 280 | return NULL; |
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 5f4cbf0c4759..fd19fd8468ac 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -1567,8 +1567,8 @@ static struct request *_make_request(struct request_queue *q, bool has_write, | |||
1567 | struct request *req; | 1567 | struct request *req; |
1568 | 1568 | ||
1569 | req = blk_get_request(q, has_write ? WRITE : READ, flags); | 1569 | req = blk_get_request(q, has_write ? WRITE : READ, flags); |
1570 | if (unlikely(!req)) | 1570 | if (IS_ERR(req)) |
1571 | return ERR_PTR(-ENOMEM); | 1571 | return req; |
1572 | 1572 | ||
1573 | blk_rq_set_block_pc(req); | 1573 | blk_rq_set_block_pc(req); |
1574 | return req; | 1574 | return req; |
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 0727ea7cc387..dff37a250d79 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c | |||
@@ -362,7 +362,7 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd, | |||
362 | int write = (data_direction == DMA_TO_DEVICE); | 362 | int write = (data_direction == DMA_TO_DEVICE); |
363 | 363 | ||
364 | req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL); | 364 | req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL); |
365 | if (!req) | 365 | if (IS_ERR(req)) |
366 | return DRIVER_ERROR << 24; | 366 | return DRIVER_ERROR << 24; |
367 | 367 | ||
368 | blk_rq_set_block_pc(req); | 368 | blk_rq_set_block_pc(req); |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 5db8454474ee..a2c3d3d255a1 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1960,6 +1960,8 @@ static void scsi_eh_lock_door(struct scsi_device *sdev) | |||
1960 | * request becomes available | 1960 | * request becomes available |
1961 | */ | 1961 | */ |
1962 | req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL); | 1962 | req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL); |
1963 | if (IS_ERR(req)) | ||
1964 | return; | ||
1963 | 1965 | ||
1964 | blk_rq_set_block_pc(req); | 1966 | blk_rq_set_block_pc(req); |
1965 | 1967 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d837dc180522..1f2bae475cb7 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -221,7 +221,7 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, | |||
221 | int ret = DRIVER_ERROR << 24; | 221 | int ret = DRIVER_ERROR << 24; |
222 | 222 | ||
223 | req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); | 223 | req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); |
224 | if (!req) | 224 | if (IS_ERR(req)) |
225 | return ret; | 225 | return ret; |
226 | blk_rq_set_block_pc(req); | 226 | blk_rq_set_block_pc(req); |
227 | 227 | ||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 01cf88888797..60354449d9ed 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1711,9 +1711,9 @@ sg_start_req(Sg_request *srp, unsigned char *cmd) | |||
1711 | } | 1711 | } |
1712 | 1712 | ||
1713 | rq = blk_get_request(q, rw, GFP_ATOMIC); | 1713 | rq = blk_get_request(q, rw, GFP_ATOMIC); |
1714 | if (!rq) { | 1714 | if (IS_ERR(rq)) { |
1715 | kfree(long_cmdp); | 1715 | kfree(long_cmdp); |
1716 | return -ENOMEM; | 1716 | return PTR_ERR(rq); |
1717 | } | 1717 | } |
1718 | 1718 | ||
1719 | blk_rq_set_block_pc(rq); | 1719 | blk_rq_set_block_pc(rq); |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index aff9689de0f7..59db5bfc11db 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -490,7 +490,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd, | |||
490 | 490 | ||
491 | req = blk_get_request(SRpnt->stp->device->request_queue, write, | 491 | req = blk_get_request(SRpnt->stp->device->request_queue, write, |
492 | GFP_KERNEL); | 492 | GFP_KERNEL); |
493 | if (!req) | 493 | if (IS_ERR(req)) |
494 | return DRIVER_ERROR << 24; | 494 | return DRIVER_ERROR << 24; |
495 | 495 | ||
496 | blk_rq_set_block_pc(req); | 496 | blk_rq_set_block_pc(req); |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 943b1dbe859a..70d9f6dabba0 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -1050,7 +1050,7 @@ pscsi_execute_cmd(struct se_cmd *cmd) | |||
1050 | req = blk_get_request(pdv->pdv_sd->request_queue, | 1050 | req = blk_get_request(pdv->pdv_sd->request_queue, |
1051 | (data_direction == DMA_TO_DEVICE), | 1051 | (data_direction == DMA_TO_DEVICE), |
1052 | GFP_KERNEL); | 1052 | GFP_KERNEL); |
1053 | if (!req) { | 1053 | if (IS_ERR(req)) { |
1054 | pr_err("PSCSI: blk_get_request() failed\n"); | 1054 | pr_err("PSCSI: blk_get_request() failed\n"); |
1055 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1055 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1056 | goto fail; | 1056 | goto fail; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 6d7274619bf9..cc8d68ac29aa 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -50,32 +50,22 @@ inline struct block_device *I_BDEV(struct inode *inode) | |||
50 | EXPORT_SYMBOL(I_BDEV); | 50 | EXPORT_SYMBOL(I_BDEV); |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Move the inode from its current bdi to a new bdi. If the inode is dirty we | 53 | * Move the inode from its current bdi to a new bdi. Make sure the inode |
54 | * need to move it onto the dirty list of @dst so that the inode is always on | 54 | * is clean before moving so that it doesn't linger on the old bdi. |
55 | * the right list. | ||
56 | */ | 55 | */ |
57 | static void bdev_inode_switch_bdi(struct inode *inode, | 56 | static void bdev_inode_switch_bdi(struct inode *inode, |
58 | struct backing_dev_info *dst) | 57 | struct backing_dev_info *dst) |
59 | { | 58 | { |
60 | struct backing_dev_info *old = inode->i_data.backing_dev_info; | 59 | while (true) { |
61 | bool wakeup_bdi = false; | 60 | spin_lock(&inode->i_lock); |
62 | 61 | if (!(inode->i_state & I_DIRTY)) { | |
63 | if (unlikely(dst == old)) /* deadlock avoidance */ | 62 | inode->i_data.backing_dev_info = dst; |
64 | return; | 63 | spin_unlock(&inode->i_lock); |
65 | bdi_lock_two(&old->wb, &dst->wb); | 64 | return; |
66 | spin_lock(&inode->i_lock); | 65 | } |
67 | inode->i_data.backing_dev_info = dst; | 66 | spin_unlock(&inode->i_lock); |
68 | if (inode->i_state & I_DIRTY) { | 67 | WARN_ON_ONCE(write_inode_now(inode, true)); |
69 | if (bdi_cap_writeback_dirty(dst) && !wb_has_dirty_io(&dst->wb)) | ||
70 | wakeup_bdi = true; | ||
71 | list_move(&inode->i_wb_list, &dst->wb.b_dirty); | ||
72 | } | 68 | } |
73 | spin_unlock(&inode->i_lock); | ||
74 | spin_unlock(&old->wb.list_lock); | ||
75 | spin_unlock(&dst->wb.list_lock); | ||
76 | |||
77 | if (wakeup_bdi) | ||
78 | bdi_wakeup_thread_delayed(dst); | ||
79 | } | 69 | } |
80 | 70 | ||
81 | /* Kill _all_ buffers and pagecache , dirty or not.. */ | 71 | /* Kill _all_ buffers and pagecache , dirty or not.. */ |
@@ -1173,8 +1163,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1173 | if (!ret) { | 1163 | if (!ret) { |
1174 | bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); | 1164 | bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); |
1175 | bdi = blk_get_backing_dev_info(bdev); | 1165 | bdi = blk_get_backing_dev_info(bdev); |
1176 | if (bdi == NULL) | ||
1177 | bdi = &default_backing_dev_info; | ||
1178 | bdev_inode_switch_bdi(bdev->bd_inode, bdi); | 1166 | bdev_inode_switch_bdi(bdev->bd_inode, bdi); |
1179 | } | 1167 | } |
1180 | 1168 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index a1d36e62179c..7e221b090308 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1699,7 +1699,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
1699 | if (!device->bdev) | 1699 | if (!device->bdev) |
1700 | continue; | 1700 | continue; |
1701 | bdi = blk_get_backing_dev_info(device->bdev); | 1701 | bdi = blk_get_backing_dev_info(device->bdev); |
1702 | if (bdi && bdi_congested(bdi, bdi_bits)) { | 1702 | if (bdi_congested(bdi, bdi_bits)) { |
1703 | ret = 1; | 1703 | ret = 1; |
1704 | break; | 1704 | break; |
1705 | } | 1705 | } |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index cd7b8ca9b064..497fcde381d7 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1678,8 +1678,6 @@ xfs_alloc_buftarg( | |||
1678 | btp->bt_dev = bdev->bd_dev; | 1678 | btp->bt_dev = bdev->bd_dev; |
1679 | btp->bt_bdev = bdev; | 1679 | btp->bt_bdev = bdev; |
1680 | btp->bt_bdi = blk_get_backing_dev_info(bdev); | 1680 | btp->bt_bdi = blk_get_backing_dev_info(bdev); |
1681 | if (!btp->bt_bdi) | ||
1682 | goto error; | ||
1683 | 1681 | ||
1684 | if (xfs_setsize_buftarg_early(btp, bdev)) | 1682 | if (xfs_setsize_buftarg_early(btp, bdev)) |
1685 | goto error; | 1683 | goto error; |
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index e488e9459a93..5da6012b7a14 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h | |||
@@ -28,12 +28,10 @@ struct dentry; | |||
28 | * Bits in backing_dev_info.state | 28 | * Bits in backing_dev_info.state |
29 | */ | 29 | */ |
30 | enum bdi_state { | 30 | enum bdi_state { |
31 | BDI_wb_alloc, /* Default embedded wb allocated */ | ||
32 | BDI_async_congested, /* The async (write) queue is getting full */ | 31 | BDI_async_congested, /* The async (write) queue is getting full */ |
33 | BDI_sync_congested, /* The sync queue is getting full */ | 32 | BDI_sync_congested, /* The sync queue is getting full */ |
34 | BDI_registered, /* bdi_register() was done */ | 33 | BDI_registered, /* bdi_register() was done */ |
35 | BDI_writeback_running, /* Writeback is in progress */ | 34 | BDI_writeback_running, /* Writeback is in progress */ |
36 | BDI_unused, /* Available bits start here */ | ||
37 | }; | 35 | }; |
38 | 36 | ||
39 | typedef int (congested_fn)(void *, int); | 37 | typedef int (congested_fn)(void *, int); |
@@ -50,7 +48,6 @@ enum bdi_stat_item { | |||
50 | 48 | ||
51 | struct bdi_writeback { | 49 | struct bdi_writeback { |
52 | struct backing_dev_info *bdi; /* our parent bdi */ | 50 | struct backing_dev_info *bdi; /* our parent bdi */ |
53 | unsigned int nr; | ||
54 | 51 | ||
55 | unsigned long last_old_flush; /* last old data flush */ | 52 | unsigned long last_old_flush; /* last old data flush */ |
56 | 53 | ||
@@ -124,7 +121,6 @@ void bdi_start_background_writeback(struct backing_dev_info *bdi); | |||
124 | void bdi_writeback_workfn(struct work_struct *work); | 121 | void bdi_writeback_workfn(struct work_struct *work); |
125 | int bdi_has_dirty_io(struct backing_dev_info *bdi); | 122 | int bdi_has_dirty_io(struct backing_dev_info *bdi); |
126 | void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi); | 123 | void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi); |
127 | void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2); | ||
128 | 124 | ||
129 | extern spinlock_t bdi_lock; | 125 | extern spinlock_t bdi_lock; |
130 | extern struct list_head bdi_list; | 126 | extern struct list_head bdi_list; |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 518b46555b80..e267bf0db559 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -865,7 +865,7 @@ extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, | |||
865 | 865 | ||
866 | static inline struct request_queue *bdev_get_queue(struct block_device *bdev) | 866 | static inline struct request_queue *bdev_get_queue(struct block_device *bdev) |
867 | { | 867 | { |
868 | return bdev->bd_disk->queue; | 868 | return bdev->bd_disk->queue; /* this is never NULL */ |
869 | } | 869 | } |
870 | 870 | ||
871 | /* | 871 | /* |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 1706cbbdf5f0..7d63d5e9d3de 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -40,7 +40,7 @@ LIST_HEAD(bdi_list); | |||
40 | /* bdi_wq serves all asynchronous writeback tasks */ | 40 | /* bdi_wq serves all asynchronous writeback tasks */ |
41 | struct workqueue_struct *bdi_wq; | 41 | struct workqueue_struct *bdi_wq; |
42 | 42 | ||
43 | void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2) | 43 | static void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2) |
44 | { | 44 | { |
45 | if (wb1 < wb2) { | 45 | if (wb1 < wb2) { |
46 | spin_lock(&wb1->list_lock); | 46 | spin_lock(&wb1->list_lock); |
@@ -376,13 +376,7 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) | |||
376 | mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0); | 376 | mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0); |
377 | flush_delayed_work(&bdi->wb.dwork); | 377 | flush_delayed_work(&bdi->wb.dwork); |
378 | WARN_ON(!list_empty(&bdi->work_list)); | 378 | WARN_ON(!list_empty(&bdi->work_list)); |
379 | 379 | WARN_ON(delayed_work_pending(&bdi->wb.dwork)); | |
380 | /* | ||
381 | * This shouldn't be necessary unless @bdi for some reason has | ||
382 | * unflushed dirty IO after work_list is drained. Do it anyway | ||
383 | * just in case. | ||
384 | */ | ||
385 | cancel_delayed_work_sync(&bdi->wb.dwork); | ||
386 | } | 380 | } |
387 | 381 | ||
388 | /* | 382 | /* |
@@ -402,21 +396,15 @@ static void bdi_prune_sb(struct backing_dev_info *bdi) | |||
402 | 396 | ||
403 | void bdi_unregister(struct backing_dev_info *bdi) | 397 | void bdi_unregister(struct backing_dev_info *bdi) |
404 | { | 398 | { |
405 | struct device *dev = bdi->dev; | 399 | if (bdi->dev) { |
406 | |||
407 | if (dev) { | ||
408 | bdi_set_min_ratio(bdi, 0); | 400 | bdi_set_min_ratio(bdi, 0); |
409 | trace_writeback_bdi_unregister(bdi); | 401 | trace_writeback_bdi_unregister(bdi); |
410 | bdi_prune_sb(bdi); | 402 | bdi_prune_sb(bdi); |
411 | 403 | ||
412 | bdi_wb_shutdown(bdi); | 404 | bdi_wb_shutdown(bdi); |
413 | bdi_debug_unregister(bdi); | 405 | bdi_debug_unregister(bdi); |
414 | 406 | device_unregister(bdi->dev); | |
415 | spin_lock_bh(&bdi->wb_lock); | ||
416 | bdi->dev = NULL; | 407 | bdi->dev = NULL; |
417 | spin_unlock_bh(&bdi->wb_lock); | ||
418 | |||
419 | device_unregister(dev); | ||
420 | } | 408 | } |
421 | } | 409 | } |
422 | EXPORT_SYMBOL(bdi_unregister); | 410 | EXPORT_SYMBOL(bdi_unregister); |
@@ -487,8 +475,17 @@ void bdi_destroy(struct backing_dev_info *bdi) | |||
487 | int i; | 475 | int i; |
488 | 476 | ||
489 | /* | 477 | /* |
490 | * Splice our entries to the default_backing_dev_info, if this | 478 | * Splice our entries to the default_backing_dev_info. This |
491 | * bdi disappears | 479 | * condition shouldn't happen. @wb must be empty at this point and |
480 | * dirty inodes on it might cause other issues. This workaround is | ||
481 | * added by ce5f8e779519 ("writeback: splice dirty inode entries to | ||
482 | * default bdi on bdi_destroy()") without root-causing the issue. | ||
483 | * | ||
484 | * http://lkml.kernel.org/g/1253038617-30204-11-git-send-email-jens.axboe@oracle.com | ||
485 | * http://thread.gmane.org/gmane.linux.file-systems/35341/focus=35350 | ||
486 | * | ||
487 | * We should probably add WARN_ON() to find out whether it still | ||
488 | * happens and track it down if so. | ||
492 | */ | 489 | */ |
493 | if (bdi_has_dirty_io(bdi)) { | 490 | if (bdi_has_dirty_io(bdi)) { |
494 | struct bdi_writeback *dst = &default_backing_dev_info.wb; | 491 | struct bdi_writeback *dst = &default_backing_dev_info.wb; |
@@ -503,12 +500,7 @@ void bdi_destroy(struct backing_dev_info *bdi) | |||
503 | 500 | ||
504 | bdi_unregister(bdi); | 501 | bdi_unregister(bdi); |
505 | 502 | ||
506 | /* | 503 | WARN_ON(delayed_work_pending(&bdi->wb.dwork)); |
507 | * If bdi_unregister() had already been called earlier, the dwork | ||
508 | * could still be pending because bdi_prune_sb() can race with the | ||
509 | * bdi_wakeup_thread_delayed() calls from __mark_inode_dirty(). | ||
510 | */ | ||
511 | cancel_delayed_work_sync(&bdi->wb.dwork); | ||
512 | 504 | ||
513 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) | 505 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) |
514 | percpu_counter_destroy(&bdi->bdi_stat[i]); | 506 | percpu_counter_destroy(&bdi->bdi_stat[i]); |