Skip to content

Commit

Permalink
Merge tag 'for-linus-20180302' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
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
  ...
  • Loading branch information
torvalds committed Mar 2, 2018
2 parents ff06b55 + 158e618 commit fb6d47a
Show file tree
Hide file tree
Showing 32 changed files with 145 additions and 82 deletions.
11 changes: 2 additions & 9 deletions block/blk-cgroup.c
Expand Up @@ -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;
Expand Down Expand Up @@ -904,9 +903,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
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
Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion block/blk-core.c
Expand Up @@ -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);

Expand Down
4 changes: 3 additions & 1 deletion block/blk-mq.c
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
48 changes: 40 additions & 8 deletions block/genhd.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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");
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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";
Expand Down
2 changes: 1 addition & 1 deletion block/ioctl.c
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions block/kyber-iosched.c
Expand Up @@ -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,
Expand Down
16 changes: 13 additions & 3 deletions block/mq-deadline.c
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions block/partition-generic.c
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/amiflop.c
Expand Up @@ -1758,7 +1758,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
if (unit[drive].type->code == FD_NODRIVE)
return NULL;
*part = 0;
return get_disk(unit[drive].gendisk);
return get_disk_and_module(unit[drive].gendisk);
}

static int __init amiga_floppy_probe(struct platform_device *pdev)
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/ataflop.c
Expand Up @@ -1917,7 +1917,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
return NULL;
*part = 0;
return get_disk(unit[drive].disk);
return get_disk_and_module(unit[drive].disk);
}

static int __init atari_floppy_init (void)
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/brd.c
Expand Up @@ -456,7 +456,7 @@ static struct kobject *brd_probe(dev_t dev, int *part, void *data)

mutex_lock(&brd_devices_mutex);
brd = brd_init_one(MINOR(dev) / max_part, &new);
kobj = brd ? get_disk(brd->brd_disk) : NULL;
kobj = brd ? get_disk_and_module(brd->brd_disk) : NULL;
mutex_unlock(&brd_devices_mutex);

if (new)
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/floppy.c
Expand Up @@ -4505,7 +4505,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
return NULL;
*part = 0;
return get_disk(disks[drive]);
return get_disk_and_module(disks[drive]);
}

static int __init do_floppy_init(void)
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/loop.c
Expand Up @@ -1922,7 +1922,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)
if (err < 0)
kobj = NULL;
else
kobj = get_disk(lo->lo_disk);
kobj = get_disk_and_module(lo->lo_disk);
mutex_unlock(&loop_index_mutex);

*part = 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/nbd.c
Expand Up @@ -1591,7 +1591,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
if (new_index < 0) {
mutex_unlock(&nbd_index_mutex);
printk(KERN_ERR "nbd: failed to add new device\n");
return ret;
return new_index;
}
nbd = idr_find(&nbd_index_idr, new_index);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/pktcdvd.c
Expand Up @@ -1122,7 +1122,7 @@ static int pkt_start_recovery(struct packet_data *pkt)
pkt->sector = new_sector;

bio_reset(pkt->bio);
bio_set_set(pkt->bio, pd->bdev);
bio_set_dev(pkt->bio, pd->bdev);
bio_set_op_attrs(pkt->bio, REQ_OP_WRITE, 0);
pkt->bio->bi_iter.bi_sector = new_sector;
pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE;
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/swim.c
Expand Up @@ -799,7 +799,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
return NULL;

*part = 0;
return get_disk(swd->unit[drive].disk);
return get_disk_and_module(swd->unit[drive].disk);
}

static int swim_add_floppy(struct swim_priv *swd, enum drive_location location)
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/z2ram.c
Expand Up @@ -332,7 +332,7 @@ static const struct block_device_operations z2_fops =
static struct kobject *z2_find(dev_t dev, int *part, void *data)
{
*part = 0;
return get_disk(z2ram_gendisk);
return get_disk_and_module(z2ram_gendisk);
}

static struct request_queue *z2_queue;
Expand Down
2 changes: 1 addition & 1 deletion drivers/ide/ide-probe.c
Expand Up @@ -928,7 +928,7 @@ static int exact_lock(dev_t dev, void *data)
{
struct gendisk *p = data;

if (!get_disk(p))
if (!get_disk_and_module(p))
return -1;
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/md/bcache/request.c
Expand Up @@ -659,11 +659,11 @@ static void do_bio_hook(struct search *s, struct bio *orig_bio)
static void search_free(struct closure *cl)
{
struct search *s = container_of(cl, struct search, cl);
bio_complete(s);

if (s->iop.bio)
bio_put(s->iop.bio);

bio_complete(s);
closure_debug_destroy(cl);
mempool_free(s, s->d->c->search);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/md/bcache/super.c
Expand Up @@ -1274,7 +1274,7 @@ static int flash_devs_run(struct cache_set *c)
struct uuid_entry *u;

for (u = c->uuids;
u < c->uuids + c->devices_max_used && !ret;
u < c->uuids + c->nr_uuids && !ret;
u++)
if (UUID_FLASH_ONLY(u))
ret = flash_dev_run(c, u);
Expand Down

0 comments on commit fb6d47a

Please sign in to comment.