Skip to content

Commit

Permalink
Merge tag 'block-5.13-2021-06-12' 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 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
  • Loading branch information
Linus Torvalds committed Jun 12, 2021
2 parents b2568ee + 85f3f17 commit efc1fd6
Show file tree
Hide file tree
Showing 8 changed files with 17 additions and 52 deletions.
3 changes: 2 additions & 1 deletion crypto/async_tx/async_xor.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ async_xor_offs(struct page *dest, unsigned int offset,
if (submit->flags & ASYNC_TX_XOR_DROP_DST) {
src_cnt--;
src_list++;
src_offs++;
if (src_offs)
src_offs++;
}

/* wait for any prerequisite operations */
Expand Down
25 changes: 7 additions & 18 deletions drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
atomic_inc(&lo->lo_refcnt);
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)
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions drivers/block/loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum {
Lo_unbound,
Lo_bound,
Lo_rundown,
Lo_deleting,
};

struct loop_func_table;
Expand Down
1 change: 0 additions & 1 deletion drivers/md/bcache/bcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 7 additions & 13 deletions drivers/md/bcache/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
Expand All @@ -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;
Expand All @@ -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);
Expand Down
14 changes: 0 additions & 14 deletions drivers/md/bcache/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ read_attribute(cache_misses);
read_attribute(cache_bypass_hits);
read_attribute(cache_bypass_misses);
read_attribute(cache_hit_ratio);
read_attribute(cache_readaheads);
read_attribute(cache_miss_collisions);
read_attribute(bypassed);

Expand All @@ -64,7 +63,6 @@ SHOW(bch_stats)
DIV_SAFE(var(cache_hits) * 100,
var(cache_hits) + var(cache_misses)));

var_print(cache_readaheads);
var_print(cache_miss_collisions);
sysfs_hprint(bypassed, var(sectors_bypassed) << 9);
#undef var
Expand All @@ -86,7 +84,6 @@ static struct attribute *bch_stats_files[] = {
&sysfs_cache_bypass_hits,
&sysfs_cache_bypass_misses,
&sysfs_cache_hit_ratio,
&sysfs_cache_readaheads,
&sysfs_cache_miss_collisions,
&sysfs_bypassed,
NULL
Expand All @@ -113,7 +110,6 @@ void bch_cache_accounting_clear(struct cache_accounting *acc)
acc->total.cache_misses = 0;
acc->total.cache_bypass_hits = 0;
acc->total.cache_bypass_misses = 0;
acc->total.cache_readaheads = 0;
acc->total.cache_miss_collisions = 0;
acc->total.sectors_bypassed = 0;
}
Expand Down Expand Up @@ -145,7 +141,6 @@ static void scale_stats(struct cache_stats *stats, unsigned long rescale_at)
scale_stat(&stats->cache_misses);
scale_stat(&stats->cache_bypass_hits);
scale_stat(&stats->cache_bypass_misses);
scale_stat(&stats->cache_readaheads);
scale_stat(&stats->cache_miss_collisions);
scale_stat(&stats->sectors_bypassed);
}
Expand All @@ -168,7 +163,6 @@ static void scale_accounting(struct timer_list *t)
move_stat(cache_misses);
move_stat(cache_bypass_hits);
move_stat(cache_bypass_misses);
move_stat(cache_readaheads);
move_stat(cache_miss_collisions);
move_stat(sectors_bypassed);

Expand Down Expand Up @@ -209,14 +203,6 @@ void bch_mark_cache_accounting(struct cache_set *c, struct bcache_device *d,
mark_cache_stats(&c->accounting.collector, hit, bypass);
}

void bch_mark_cache_readahead(struct cache_set *c, struct bcache_device *d)
{
struct cached_dev *dc = container_of(d, struct cached_dev, disk);

atomic_inc(&dc->accounting.collector.cache_readaheads);
atomic_inc(&c->accounting.collector.cache_readaheads);
}

void bch_mark_cache_miss_collision(struct cache_set *c, struct bcache_device *d)
{
struct cached_dev *dc = container_of(d, struct cached_dev, disk);
Expand Down
1 change: 0 additions & 1 deletion drivers/md/bcache/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ struct cache_stat_collector {
atomic_t cache_misses;
atomic_t cache_bypass_hits;
atomic_t cache_bypass_misses;
atomic_t cache_readaheads;
atomic_t cache_miss_collisions;
atomic_t sectors_bypassed;
};
Expand Down
4 changes: 0 additions & 4 deletions drivers/md/bcache/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ rw_attribute(io_disable);
rw_attribute(discard);
rw_attribute(running);
rw_attribute(label);
rw_attribute(readahead);
rw_attribute(errors);
rw_attribute(io_error_limit);
rw_attribute(io_error_halflife);
Expand Down Expand Up @@ -260,7 +259,6 @@ SHOW(__bch_cached_dev)
var_printf(partial_stripes_expensive, "%u");

var_hprint(sequential_cutoff);
var_hprint(readahead);

sysfs_print(running, atomic_read(&dc->running));
sysfs_print(state, states[BDEV_STATE(&dc->sb)]);
Expand Down Expand Up @@ -365,7 +363,6 @@ STORE(__cached_dev)
sysfs_strtoul_clamp(sequential_cutoff,
dc->sequential_cutoff,
0, UINT_MAX);
d_strtoi_h(readahead);

if (attr == &sysfs_clear_stats)
bch_cache_accounting_clear(&dc->accounting);
Expand Down Expand Up @@ -538,7 +535,6 @@ static struct attribute *bch_cached_dev_files[] = {
&sysfs_running,
&sysfs_state,
&sysfs_label,
&sysfs_readahead,
#ifdef CONFIG_BCACHE_DEBUG
&sysfs_verify,
&sysfs_bypass_torture_test,
Expand Down

0 comments on commit efc1fd6

Please sign in to comment.