Commit efc1fd60 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'block-5.13-2021-06-12' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
 "A few fixes that should go into 5.13:

   - Fix a regression deadlock introduced in this release between open
     and remove of a bdev (Christoph)

   - Fix an async_xor md regression in this release (Xiao)

   - Fix bcache oversized read issue (Coly)"

* tag 'block-5.13-2021-06-12' of git://git.kernel.dk/linux-block:
  block: loop: fix deadlock between open and remove
  async_xor: check src_offs is not NULL before updating it
  bcache: avoid oversized read request in cache missing code path
  bcache: remove bcache device self-defined readahead
parents b2568eeb 85f3f17b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ async_xor_offs(struct page *dest, unsigned int offset,
		if (submit->flags & ASYNC_TX_XOR_DROP_DST) {
			src_cnt--;
			src_list++;
			if (src_offs)
				src_offs++;
		}

+7 −18
Original line number Diff line number Diff line
@@ -1879,29 +1879,18 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode,

static int lo_open(struct block_device *bdev, fmode_t mode)
{
	struct loop_device *lo;
	struct loop_device *lo = bdev->bd_disk->private_data;
	int err;

	/*
	 * take loop_ctl_mutex to protect lo pointer from race with
	 * loop_control_ioctl(LOOP_CTL_REMOVE), however, to reduce contention
	 * release it prior to updating lo->lo_refcnt.
	 */
	err = mutex_lock_killable(&loop_ctl_mutex);
	if (err)
		return err;
	lo = bdev->bd_disk->private_data;
	if (!lo) {
		mutex_unlock(&loop_ctl_mutex);
		return -ENXIO;
	}
	err = mutex_lock_killable(&lo->lo_mutex);
	mutex_unlock(&loop_ctl_mutex);
	if (err)
		return err;
	if (lo->lo_state == Lo_deleting)
		err = -ENXIO;
	else
		atomic_inc(&lo->lo_refcnt);
	mutex_unlock(&lo->lo_mutex);
	return 0;
	return err;
}

static void lo_release(struct gendisk *disk, fmode_t mode)
@@ -2285,7 +2274,7 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd,
			mutex_unlock(&lo->lo_mutex);
			break;
		}
		lo->lo_disk->private_data = NULL;
		lo->lo_state = Lo_deleting;
		mutex_unlock(&lo->lo_mutex);
		idr_remove(&loop_index_idr, lo->lo_number);
		loop_remove(lo);
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ enum {
	Lo_unbound,
	Lo_bound,
	Lo_rundown,
	Lo_deleting,
};

struct loop_func_table;
+0 −1
Original line number Diff line number Diff line
@@ -364,7 +364,6 @@ struct cached_dev {

	/* The rest of this all shows up in sysfs */
	unsigned int		sequential_cutoff;
	unsigned int		readahead;

	unsigned int		io_disable:1;
	unsigned int		verify:1;
+7 −13
Original line number Diff line number Diff line
@@ -880,9 +880,9 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
				 struct bio *bio, unsigned int sectors)
{
	int ret = MAP_CONTINUE;
	unsigned int reada = 0;
	struct cached_dev *dc = container_of(s->d, struct cached_dev, disk);
	struct bio *miss, *cache_bio;
	unsigned int size_limit;

	s->cache_missed = 1;

@@ -892,14 +892,10 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
		goto out_submit;
	}

	if (!(bio->bi_opf & REQ_RAHEAD) &&
	    !(bio->bi_opf & (REQ_META|REQ_PRIO)) &&
	    s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA)
		reada = min_t(sector_t, dc->readahead >> 9,
			      get_capacity(bio->bi_bdev->bd_disk) -
			      bio_end_sector(bio));

	s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada);
	/* Limitation for valid replace key size and cache_bio bvecs number */
	size_limit = min_t(unsigned int, BIO_MAX_VECS * PAGE_SECTORS,
			   (1 << KEY_SIZE_BITS) - 1);
	s->insert_bio_sectors = min3(size_limit, sectors, bio_sectors(bio));

	s->iop.replace_key = KEY(s->iop.inode,
				 bio->bi_iter.bi_sector + s->insert_bio_sectors,
@@ -911,7 +907,8 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,

	s->iop.replace = true;

	miss = bio_next_split(bio, sectors, GFP_NOIO, &s->d->bio_split);
	miss = bio_next_split(bio, s->insert_bio_sectors, GFP_NOIO,
			      &s->d->bio_split);

	/* btree_search_recurse()'s btree iterator is no good anymore */
	ret = miss == bio ? MAP_DONE : -EINTR;
@@ -933,9 +930,6 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s,
	if (bch_bio_alloc_pages(cache_bio, __GFP_NOWARN|GFP_NOIO))
		goto out_put;

	if (reada)
		bch_mark_cache_readahead(s->iop.c, s->d);

	s->cache_miss	= miss;
	s->iop.bio	= cache_bio;
	bio_get(cache_bio);
Loading