Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull block fixes from Jens Axboe:
 "Two fixes that should go into this release.

  One is an nvme regression fix from Keith, fixing a missing queue
  freeze if the controller is being reset. This causes the reset to
  hang.

  The other is a fix for a leak of the bio protection info, if smaller
  sized O_DIRECT is used. This fix should be more involved as we have
  other problematic paths in the kernel, but given as this isn't a
  regression in this series, we'll tackle those for 4.13"

* 'for-linus' of git://git.kernel.dk/linux-block:
  block: provide bio_uninit() free freeing integrity/task associations
  nvme/pci: Fix stuck nvme reset
  • Loading branch information
Linus Torvalds committed Jun 29, 2017
2 parents 6474924 + 9ae3b3f commit 374bf88
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 5 deletions.
12 changes: 9 additions & 3 deletions block/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,20 +240,21 @@ struct bio_vec *bvec_alloc(gfp_t gfp_mask, int nr, unsigned long *idx,
return bvl;
}

static void __bio_free(struct bio *bio)
void bio_uninit(struct bio *bio)
{
bio_disassociate_task(bio);

if (bio_integrity(bio))
bio_integrity_free(bio);
}
EXPORT_SYMBOL(bio_uninit);

static void bio_free(struct bio *bio)
{
struct bio_set *bs = bio->bi_pool;
void *p;

__bio_free(bio);
bio_uninit(bio);

if (bs) {
bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio));
Expand All @@ -271,6 +272,11 @@ static void bio_free(struct bio *bio)
}
}

/*
* Users of this function have their own bio allocation. Subsequently,
* they must remember to pair any call to bio_init() with bio_uninit()
* when IO has completed, or when the bio is released.
*/
void bio_init(struct bio *bio, struct bio_vec *table,
unsigned short max_vecs)
{
Expand All @@ -297,7 +303,7 @@ void bio_reset(struct bio *bio)
{
unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS);

__bio_free(bio);
bio_uninit(bio);

memset(bio, 0, BIO_RESET_BYTES);
bio->bi_flags = flags;
Expand Down
3 changes: 2 additions & 1 deletion drivers/nvme/host/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
if (pci_is_enabled(pdev)) {
u32 csts = readl(dev->bar + NVME_REG_CSTS);

if (dev->ctrl.state == NVME_CTRL_LIVE)
if (dev->ctrl.state == NVME_CTRL_LIVE ||
dev->ctrl.state == NVME_CTRL_RESETTING)
nvme_start_freeze(&dev->ctrl);
dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) ||
pdev->error_state != pci_channel_io_normal);
Expand Down
5 changes: 4 additions & 1 deletion fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
kfree(vecs);

if (unlikely(bio.bi_error))
return bio.bi_error;
ret = bio.bi_error;

bio_uninit(&bio);

return ret;
}

Expand Down
1 change: 1 addition & 0 deletions include/linux/bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ extern void bio_advance(struct bio *, unsigned);

extern void bio_init(struct bio *bio, struct bio_vec *table,
unsigned short max_vecs);
extern void bio_uninit(struct bio *);
extern void bio_reset(struct bio *);
void bio_chain(struct bio *, struct bio *);

Expand Down

0 comments on commit 374bf88

Please sign in to comment.