mirror of
https://github.com/suyu-emu/horinux.git
synced 2026-09-21 14:15:21 -07:00
Merge tag 'for-linus-20180302' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe:
"A collection of fixes for this series. This is a little larger than
usual at this time, but that's mainly because I was out on vacation
last week. Nothing in here is major in any way, it's just two weeks of
fixes. This contains:
- NVMe pull from Keith, with a set of fixes from the usual suspects.
- mq-deadline zone unlock fix from Damien, fixing an issue with the
SMR zone locking added for 4.16.
- two bcache fixes sent in by Michael, with changes from Coly and
Tang.
- comment typo fix from Eric for blktrace.
- return-value error handling fix for nbd, from Gustavo.
- fix a direct-io case where we don't defer to a completion handler,
making us sleep from IRQ device completion. From Jan.
- a small series from Jan fixing up holes around handling of bdev
references.
- small set of regression fixes from Jiufei, mostly fixing problems
around the gendisk pointer -> partition index change.
- regression fix from Ming, fixing a boundary issue with the discard
page cache invalidation.
- two-patch series from Ming, fixing both a core blk-mq-sched and
kyber issue around token freeing on a requeue condition"
* tag 'for-linus-20180302' of git://git.kernel.dk/linux-block: (24 commits)
block: fix a typo
block: display the correct diskname for bio
block: fix the count of PGPGOUT for WRITE_SAME
mq-deadline: Make sure to always unlock zones
nvmet: fix PSDT field check in command format
nvme-multipath: fix sysfs dangerously created links
nbd: fix return value in error handling path
bcache: fix kcrashes with fio in RAID5 backend dev
bcache: correct flash only vols (check all uuids)
blktrace_api.h: fix comment for struct blk_user_trace_setup
blockdev: Avoid two active bdev inodes for one device
genhd: Fix BUG in blkdev_open()
genhd: Fix use after free in __blkdev_get()
genhd: Add helper put_disk_and_module()
genhd: Rename get_disk() to get_disk_and_module()
genhd: Fix leaked module reference for NVME devices
direct-io: Fix sleep in atomic due to sync AIO
nvme-pci: Fix nvme queue cleanup if IRQ setup fails
block: kyber: fix domain token leak during requeue
blk-mq: don't call io sched's .requeue_request when requeueing rq to ->dispatch
...
This commit is contained in:
+2
-9
@@ -812,7 +812,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
||||
struct gendisk *disk;
|
||||
struct request_queue *q;
|
||||
struct blkcg_gq *blkg;
|
||||
struct module *owner;
|
||||
unsigned int major, minor;
|
||||
int key_len, part, ret;
|
||||
char *body;
|
||||
@@ -904,9 +903,7 @@ fail_unlock:
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
rcu_read_unlock();
|
||||
fail:
|
||||
owner = disk->fops->owner;
|
||||
put_disk(disk);
|
||||
module_put(owner);
|
||||
put_disk_and_module(disk);
|
||||
/*
|
||||
* If queue was bypassing, we should retry. Do so after a
|
||||
* short msleep(). It isn't strictly necessary but queue
|
||||
@@ -931,13 +928,9 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
|
||||
void blkg_conf_finish(struct blkg_conf_ctx *ctx)
|
||||
__releases(ctx->disk->queue->queue_lock) __releases(rcu)
|
||||
{
|
||||
struct module *owner;
|
||||
|
||||
spin_unlock_irq(ctx->disk->queue->queue_lock);
|
||||
rcu_read_unlock();
|
||||
owner = ctx->disk->fops->owner;
|
||||
put_disk(ctx->disk);
|
||||
module_put(owner);
|
||||
put_disk_and_module(ctx->disk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkg_conf_finish);
|
||||
|
||||
|
||||
+1
-1
@@ -2434,7 +2434,7 @@ blk_qc_t submit_bio(struct bio *bio)
|
||||
unsigned int count;
|
||||
|
||||
if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
|
||||
count = queue_logical_block_size(bio->bi_disk->queue);
|
||||
count = queue_logical_block_size(bio->bi_disk->queue) >> 9;
|
||||
else
|
||||
count = bio_sectors(bio);
|
||||
|
||||
|
||||
+3
-1
@@ -712,7 +712,6 @@ static void __blk_mq_requeue_request(struct request *rq)
|
||||
|
||||
trace_block_rq_requeue(q, rq);
|
||||
wbt_requeue(q->rq_wb, &rq->issue_stat);
|
||||
blk_mq_sched_requeue_request(rq);
|
||||
|
||||
if (blk_mq_rq_state(rq) != MQ_RQ_IDLE) {
|
||||
blk_mq_rq_update_state(rq, MQ_RQ_IDLE);
|
||||
@@ -725,6 +724,9 @@ void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list)
|
||||
{
|
||||
__blk_mq_requeue_request(rq);
|
||||
|
||||
/* this request will be re-inserted to io scheduler queue */
|
||||
blk_mq_sched_requeue_request(rq);
|
||||
|
||||
BUG_ON(blk_queued_rq(rq));
|
||||
blk_mq_add_to_requeue_list(rq, true, kick_requeue_list);
|
||||
}
|
||||
|
||||
+40
-8
@@ -547,7 +547,7 @@ static int exact_lock(dev_t devt, void *data)
|
||||
{
|
||||
struct gendisk *p = data;
|
||||
|
||||
if (!get_disk(p))
|
||||
if (!get_disk_and_module(p))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@@ -717,6 +717,11 @@ void del_gendisk(struct gendisk *disk)
|
||||
blk_integrity_del(disk);
|
||||
disk_del_events(disk);
|
||||
|
||||
/*
|
||||
* Block lookups of the disk until all bdevs are unhashed and the
|
||||
* disk is marked as dead (GENHD_FL_UP cleared).
|
||||
*/
|
||||
down_write(&disk->lookup_sem);
|
||||
/* invalidate stuff */
|
||||
disk_part_iter_init(&piter, disk,
|
||||
DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE);
|
||||
@@ -731,6 +736,7 @@ void del_gendisk(struct gendisk *disk)
|
||||
bdev_unhash_inode(disk_devt(disk));
|
||||
set_capacity(disk, 0);
|
||||
disk->flags &= ~GENHD_FL_UP;
|
||||
up_write(&disk->lookup_sem);
|
||||
|
||||
if (!(disk->flags & GENHD_FL_HIDDEN))
|
||||
sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
|
||||
@@ -809,16 +815,28 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
|
||||
|
||||
spin_lock_bh(&ext_devt_lock);
|
||||
part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
|
||||
if (part && get_disk(part_to_disk(part))) {
|
||||
if (part && get_disk_and_module(part_to_disk(part))) {
|
||||
*partno = part->partno;
|
||||
disk = part_to_disk(part);
|
||||
}
|
||||
spin_unlock_bh(&ext_devt_lock);
|
||||
}
|
||||
|
||||
if (disk && unlikely(disk->flags & GENHD_FL_HIDDEN)) {
|
||||
put_disk(disk);
|
||||
if (!disk)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Synchronize with del_gendisk() to not return disk that is being
|
||||
* destroyed.
|
||||
*/
|
||||
down_read(&disk->lookup_sem);
|
||||
if (unlikely((disk->flags & GENHD_FL_HIDDEN) ||
|
||||
!(disk->flags & GENHD_FL_UP))) {
|
||||
up_read(&disk->lookup_sem);
|
||||
put_disk_and_module(disk);
|
||||
disk = NULL;
|
||||
} else {
|
||||
up_read(&disk->lookup_sem);
|
||||
}
|
||||
return disk;
|
||||
}
|
||||
@@ -1418,6 +1436,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
|
||||
kfree(disk);
|
||||
return NULL;
|
||||
}
|
||||
init_rwsem(&disk->lookup_sem);
|
||||
disk->node_id = node_id;
|
||||
if (disk_expand_part_tbl(disk, 0)) {
|
||||
free_part_stats(&disk->part0);
|
||||
@@ -1453,7 +1472,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
|
||||
}
|
||||
EXPORT_SYMBOL(__alloc_disk_node);
|
||||
|
||||
struct kobject *get_disk(struct gendisk *disk)
|
||||
struct kobject *get_disk_and_module(struct gendisk *disk)
|
||||
{
|
||||
struct module *owner;
|
||||
struct kobject *kobj;
|
||||
@@ -1471,17 +1490,30 @@ struct kobject *get_disk(struct gendisk *disk)
|
||||
return kobj;
|
||||
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(get_disk);
|
||||
EXPORT_SYMBOL(get_disk_and_module);
|
||||
|
||||
void put_disk(struct gendisk *disk)
|
||||
{
|
||||
if (disk)
|
||||
kobject_put(&disk_to_dev(disk)->kobj);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(put_disk);
|
||||
|
||||
/*
|
||||
* This is a counterpart of get_disk_and_module() and thus also of
|
||||
* get_gendisk().
|
||||
*/
|
||||
void put_disk_and_module(struct gendisk *disk)
|
||||
{
|
||||
if (disk) {
|
||||
struct module *owner = disk->fops->owner;
|
||||
|
||||
put_disk(disk);
|
||||
module_put(owner);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(put_disk_and_module);
|
||||
|
||||
static void set_disk_ro_uevent(struct gendisk *gd, int ro)
|
||||
{
|
||||
char event[] = "DISK_RO=1";
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
|
||||
|
||||
if (start + len > i_size_read(bdev->bd_inode))
|
||||
return -EINVAL;
|
||||
truncate_inode_pages_range(mapping, start, start + len);
|
||||
truncate_inode_pages_range(mapping, start, start + len - 1);
|
||||
return blkdev_issue_discard(bdev, start >> 9, len >> 9,
|
||||
GFP_KERNEL, flags);
|
||||
}
|
||||
|
||||
@@ -833,6 +833,7 @@ static struct elevator_type kyber_sched = {
|
||||
.limit_depth = kyber_limit_depth,
|
||||
.prepare_request = kyber_prepare_request,
|
||||
.finish_request = kyber_finish_request,
|
||||
.requeue_request = kyber_finish_request,
|
||||
.completed_request = kyber_completed_request,
|
||||
.dispatch_request = kyber_dispatch_request,
|
||||
.has_work = kyber_has_work,
|
||||
|
||||
+13
-3
@@ -535,13 +535,22 @@ static void dd_insert_requests(struct blk_mq_hw_ctx *hctx,
|
||||
spin_unlock(&dd->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Nothing to do here. This is defined only to ensure that .finish_request
|
||||
* method is called upon request completion.
|
||||
*/
|
||||
static void dd_prepare_request(struct request *rq, struct bio *bio)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* For zoned block devices, write unlock the target zone of
|
||||
* completed write requests. Do this while holding the zone lock
|
||||
* spinlock so that the zone is never unlocked while deadline_fifo_request()
|
||||
* while deadline_next_request() are executing.
|
||||
* or deadline_next_request() are executing. This function is called for
|
||||
* all requests, whether or not these requests complete successfully.
|
||||
*/
|
||||
static void dd_completed_request(struct request *rq)
|
||||
static void dd_finish_request(struct request *rq)
|
||||
{
|
||||
struct request_queue *q = rq->q;
|
||||
|
||||
@@ -756,7 +765,8 @@ static struct elevator_type mq_deadline = {
|
||||
.ops.mq = {
|
||||
.insert_requests = dd_insert_requests,
|
||||
.dispatch_request = dd_dispatch_request,
|
||||
.completed_request = dd_completed_request,
|
||||
.prepare_request = dd_prepare_request,
|
||||
.finish_request = dd_finish_request,
|
||||
.next_request = elv_rb_latter_request,
|
||||
.former_request = elv_rb_former_request,
|
||||
.bio_merge = dd_bio_merge,
|
||||
|
||||
@@ -51,6 +51,12 @@ const char *bdevname(struct block_device *bdev, char *buf)
|
||||
|
||||
EXPORT_SYMBOL(bdevname);
|
||||
|
||||
const char *bio_devname(struct bio *bio, char *buf)
|
||||
{
|
||||
return disk_name(bio->bi_disk, bio->bi_partno, buf);
|
||||
}
|
||||
EXPORT_SYMBOL(bio_devname);
|
||||
|
||||
/*
|
||||
* There's very little reason to use this, you should really
|
||||
* have a struct block_device just about everywhere and use
|
||||
|
||||
Reference in New Issue
Block a user