Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ee54061 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull block layer fixes from Jens Axboe:
 "A small collection of fixes for the current series. It contains:

   - A fix for a use-after-free of a request in blk-mq.  From Ming Lei

   - A fix for a blk-mq bug that could attempt to dereference a NULL rq
     if allocation failed

   - Two xen-blkfront small fixes

   - Cleanup of submit_bio_wait() type uses in the kernel, unifying
     that.  From Kent

   - A fix for 32-bit blkg_rwstat reading.  I apologize for this one
     looking mangled in the shortlog, it's entirely my fault for missing
     an empty line between the description and body of the text"

* 'for-linus' of git://git.kernel.dk/linux-block:
  blk-mq: fix use-after-free of request
  blk-mq: fix dereference of rq->mq_ctx if allocation fails
  block: xen-blkfront: Fix possible NULL ptr dereference
  xen-blkfront: Silence pfn maybe-uninitialized warning
  block: submit_bio_wait() conversions
  Update of blkg_stat and blkg_rwstat may happen in bh context
parents 29be6345 0d11e6ac
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -435,9 +435,9 @@ static inline uint64_t blkg_stat_read(struct blkg_stat *stat)
	uint64_t v;

	do {
		start = u64_stats_fetch_begin(&stat->syncp);
		start = u64_stats_fetch_begin_bh(&stat->syncp);
		v = stat->cnt;
	} while (u64_stats_fetch_retry(&stat->syncp, start));
	} while (u64_stats_fetch_retry_bh(&stat->syncp, start));

	return v;
}
@@ -508,9 +508,9 @@ static inline struct blkg_rwstat blkg_rwstat_read(struct blkg_rwstat *rwstat)
	struct blkg_rwstat tmp;

	do {
		start = u64_stats_fetch_begin(&rwstat->syncp);
		start = u64_stats_fetch_begin_bh(&rwstat->syncp);
		tmp = *rwstat;
	} while (u64_stats_fetch_retry(&rwstat->syncp, start));
	} while (u64_stats_fetch_retry_bh(&rwstat->syncp, start));

	return tmp;
}
+1 −18
Original line number Diff line number Diff line
@@ -502,15 +502,6 @@ void blk_abort_flushes(struct request_queue *q)
	}
}

static void bio_end_flush(struct bio *bio, int err)
{
	if (err)
		clear_bit(BIO_UPTODATE, &bio->bi_flags);
	if (bio->bi_private)
		complete(bio->bi_private);
	bio_put(bio);
}

/**
 * blkdev_issue_flush - queue a flush
 * @bdev:	blockdev to issue flush for
@@ -526,7 +517,6 @@ static void bio_end_flush(struct bio *bio, int err)
int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
		sector_t *error_sector)
{
	DECLARE_COMPLETION_ONSTACK(wait);
	struct request_queue *q;
	struct bio *bio;
	int ret = 0;
@@ -548,13 +538,9 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
		return -ENXIO;

	bio = bio_alloc(gfp_mask, 0);
	bio->bi_end_io = bio_end_flush;
	bio->bi_bdev = bdev;
	bio->bi_private = &wait;

	bio_get(bio);
	submit_bio(WRITE_FLUSH, bio);
	wait_for_completion_io(&wait);
	ret = submit_bio_wait(WRITE_FLUSH, bio);

	/*
	 * The driver must store the error location in ->bi_sector, if
@@ -564,9 +550,6 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
	if (error_sector)
		*error_sector = bio->bi_sector;

	if (!bio_flagged(bio, BIO_UPTODATE))
		ret = -EIO;

	bio_put(bio);
	return ret;
}
+10 −6
Original line number Diff line number Diff line
@@ -202,10 +202,12 @@ static struct request *blk_mq_alloc_request_pinned(struct request_queue *q,
		if (rq) {
			blk_mq_rq_ctx_init(q, ctx, rq, rw);
			break;
		} else if (!(gfp & __GFP_WAIT))
			break;
		}

		blk_mq_put_ctx(ctx);
		if (!(gfp & __GFP_WAIT))
			break;

		__blk_mq_run_hw_queue(hctx);
		blk_mq_wait_for_tags(hctx->tags);
	} while (1);
@@ -222,6 +224,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
		return NULL;

	rq = blk_mq_alloc_request_pinned(q, rw, gfp, reserved);
	if (rq)
		blk_mq_put_ctx(rq->mq_ctx);
	return rq;
}
@@ -235,6 +238,7 @@ struct request *blk_mq_alloc_reserved_request(struct request_queue *q, int rw,
		return NULL;

	rq = blk_mq_alloc_request_pinned(q, rw, gfp, true);
	if (rq)
		blk_mq_put_ctx(rq->mq_ctx);
	return rq;
}
@@ -308,12 +312,12 @@ void blk_mq_complete_request(struct request *rq, int error)

	blk_account_io_completion(rq, bytes);

	blk_account_io_done(rq);

	if (rq->end_io)
		rq->end_io(rq, error);
	else
		blk_mq_free_request(rq);

	blk_account_io_done(rq);
}

void __blk_mq_end_io(struct request *rq, int error)
+6 −1
Original line number Diff line number Diff line
@@ -489,7 +489,7 @@ static int blkif_queue_request(struct request *req)

			if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
			    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
				unsigned long pfn;
				unsigned long uninitialized_var(pfn);

				if (segments)
					kunmap_atomic(segments);
@@ -2011,6 +2011,10 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)

	bdev = bdget_disk(disk, 0);

	if (!bdev) {
		WARN(1, "Block device %s yanked out from us!\n", disk->disk_name);
		goto out_mutex;
	}
	if (bdev->bd_openers)
		goto out;

@@ -2041,6 +2045,7 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)

out:
	bdput(bdev);
out_mutex:
	mutex_unlock(&blkfront_mutex);
}

+1 −11
Original line number Diff line number Diff line
@@ -776,16 +776,10 @@ void md_super_wait(struct mddev *mddev)
	finish_wait(&mddev->sb_wait, &wq);
}

static void bi_complete(struct bio *bio, int error)
{
	complete((struct completion*)bio->bi_private);
}

int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
		 struct page *page, int rw, bool metadata_op)
{
	struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev);
	struct completion event;
	int ret;

	rw |= REQ_SYNC;
@@ -801,11 +795,7 @@ int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
	else
		bio->bi_sector = sector + rdev->data_offset;
	bio_add_page(bio, page, size, 0);
	init_completion(&event);
	bio->bi_private = &event;
	bio->bi_end_io = bi_complete;
	submit_bio(rw, bio);
	wait_for_completion(&event);
	submit_bio_wait(rw, bio);

	ret = test_bit(BIO_UPTODATE, &bio->bi_flags);
	bio_put(bio);
Loading