Commit 68e71d19 authored by Linus Torvalds's avatar 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:
  backing-dev: ensure that a removed bdi no longer has super_block referencing it
  block: use after free bug in __blkdev_get
  block: silently error unsupported empty barriers too
parents 066455d4 592b09a4
...@@ -1161,7 +1161,7 @@ static int __make_request(struct request_queue *q, struct bio *bio) ...@@ -1161,7 +1161,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK; const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK;
int rw_flags; int rw_flags;
if (bio_rw_flagged(bio, BIO_RW_BARRIER) && bio_has_data(bio) && if (bio_rw_flagged(bio, BIO_RW_BARRIER) &&
(q->next_ordered == QUEUE_ORDERED_NONE)) { (q->next_ordered == QUEUE_ORDERED_NONE)) {
bio_endio(bio, -EOPNOTSUPP); bio_endio(bio, -EOPNOTSUPP);
return 0; return 0;
......
...@@ -1248,8 +1248,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) ...@@ -1248,8 +1248,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
} }
} else { } else {
put_disk(disk);
module_put(disk->fops->owner); module_put(disk->fops->owner);
put_disk(disk);
disk = NULL; disk = NULL;
if (bdev->bd_contains == bdev) { if (bdev->bd_contains == bdev) {
if (bdev->bd_disk->fops->open) { if (bdev->bd_disk->fops->open) {
......
...@@ -610,6 +610,21 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) ...@@ -610,6 +610,21 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
kthread_stop(wb->task); kthread_stop(wb->task);
} }
/*
* This bdi is going away now, make sure that no super_blocks point to it
*/
static void bdi_prune_sb(struct backing_dev_info *bdi)
{
struct super_block *sb;
spin_lock(&sb_lock);
list_for_each_entry(sb, &super_blocks, s_list) {
if (sb->s_bdi == bdi)
sb->s_bdi = NULL;
}
spin_unlock(&sb_lock);
}
void bdi_unregister(struct backing_dev_info *bdi) void bdi_unregister(struct backing_dev_info *bdi)
{ {
if (bdi->dev) { if (bdi->dev) {
...@@ -682,6 +697,7 @@ void bdi_destroy(struct backing_dev_info *bdi) ...@@ -682,6 +697,7 @@ void bdi_destroy(struct backing_dev_info *bdi)
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
} }
bdi_prune_sb(bdi);
bdi_unregister(bdi); bdi_unregister(bdi);
for (i = 0; i < NR_BDI_STAT_ITEMS; i++) for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment