Commit c3adefb5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-6.0/dm-fixes' of...

Merge tag 'for-6.0/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:

 - A few fixes for the DM verity and bufio changes in this merge window

 - A smatch warning fix for DM writecache locking in writecache_map

* tag 'for-6.0/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm bufio: fix some cases where the code sleeps with spinlock held
  dm writecache: fix smatch warning about invalid return from writecache_map
  dm verity: fix verity_parse_opt_args parsing
  dm verity: fix DM_VERITY_OPTS_MAX value yet again
  dm bufio: simplify DM_BUFIO_CLIENT_NO_SLEEP locking
parents 7ce2aa6d e3a7c294
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
struct dm_bufio_client { struct dm_bufio_client {
struct mutex lock; struct mutex lock;
spinlock_t spinlock; spinlock_t spinlock;
unsigned long spinlock_flags; bool no_sleep;
struct list_head lru[LIST_SIZE]; struct list_head lru[LIST_SIZE];
unsigned long n_buffers[LIST_SIZE]; unsigned long n_buffers[LIST_SIZE];
...@@ -93,8 +93,6 @@ struct dm_bufio_client { ...@@ -93,8 +93,6 @@ struct dm_bufio_client {
s8 sectors_per_block_bits; s8 sectors_per_block_bits;
void (*alloc_callback)(struct dm_buffer *); void (*alloc_callback)(struct dm_buffer *);
void (*write_callback)(struct dm_buffer *); void (*write_callback)(struct dm_buffer *);
bool no_sleep;
struct kmem_cache *slab_buffer; struct kmem_cache *slab_buffer;
struct kmem_cache *slab_cache; struct kmem_cache *slab_cache;
struct dm_io_client *dm_io; struct dm_io_client *dm_io;
...@@ -174,7 +172,7 @@ static DEFINE_STATIC_KEY_FALSE(no_sleep_enabled); ...@@ -174,7 +172,7 @@ static DEFINE_STATIC_KEY_FALSE(no_sleep_enabled);
static void dm_bufio_lock(struct dm_bufio_client *c) static void dm_bufio_lock(struct dm_bufio_client *c)
{ {
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep) if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep)
spin_lock_irqsave_nested(&c->spinlock, c->spinlock_flags, dm_bufio_in_request()); spin_lock_bh(&c->spinlock);
else else
mutex_lock_nested(&c->lock, dm_bufio_in_request()); mutex_lock_nested(&c->lock, dm_bufio_in_request());
} }
...@@ -182,7 +180,7 @@ static void dm_bufio_lock(struct dm_bufio_client *c) ...@@ -182,7 +180,7 @@ static void dm_bufio_lock(struct dm_bufio_client *c)
static int dm_bufio_trylock(struct dm_bufio_client *c) static int dm_bufio_trylock(struct dm_bufio_client *c)
{ {
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep) if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep)
return spin_trylock_irqsave(&c->spinlock, c->spinlock_flags); return spin_trylock_bh(&c->spinlock);
else else
return mutex_trylock(&c->lock); return mutex_trylock(&c->lock);
} }
...@@ -190,7 +188,7 @@ static int dm_bufio_trylock(struct dm_bufio_client *c) ...@@ -190,7 +188,7 @@ static int dm_bufio_trylock(struct dm_bufio_client *c)
static void dm_bufio_unlock(struct dm_bufio_client *c) static void dm_bufio_unlock(struct dm_bufio_client *c)
{ {
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep) if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep)
spin_unlock_irqrestore(&c->spinlock, c->spinlock_flags); spin_unlock_bh(&c->spinlock);
else else
mutex_unlock(&c->lock); mutex_unlock(&c->lock);
} }
...@@ -817,6 +815,10 @@ static struct dm_buffer *__get_unclaimed_buffer(struct dm_bufio_client *c) ...@@ -817,6 +815,10 @@ static struct dm_buffer *__get_unclaimed_buffer(struct dm_bufio_client *c)
BUG_ON(test_bit(B_WRITING, &b->state)); BUG_ON(test_bit(B_WRITING, &b->state));
BUG_ON(test_bit(B_DIRTY, &b->state)); BUG_ON(test_bit(B_DIRTY, &b->state));
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep &&
unlikely(test_bit(B_READING, &b->state)))
continue;
if (!b->hold_count) { if (!b->hold_count) {
__make_buffer_clean(b); __make_buffer_clean(b);
__unlink_buffer(b); __unlink_buffer(b);
...@@ -825,6 +827,9 @@ static struct dm_buffer *__get_unclaimed_buffer(struct dm_bufio_client *c) ...@@ -825,6 +827,9 @@ static struct dm_buffer *__get_unclaimed_buffer(struct dm_bufio_client *c)
cond_resched(); cond_resched();
} }
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep)
return NULL;
list_for_each_entry_reverse(b, &c->lru[LIST_DIRTY], lru_list) { list_for_each_entry_reverse(b, &c->lru[LIST_DIRTY], lru_list) {
BUG_ON(test_bit(B_READING, &b->state)); BUG_ON(test_bit(B_READING, &b->state));
...@@ -1632,7 +1637,8 @@ static void drop_buffers(struct dm_bufio_client *c) ...@@ -1632,7 +1637,8 @@ static void drop_buffers(struct dm_bufio_client *c)
*/ */
static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp) static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp)
{ {
if (!(gfp & __GFP_FS)) { if (!(gfp & __GFP_FS) ||
(static_branch_unlikely(&no_sleep_enabled) && b->c->no_sleep)) {
if (test_bit(B_READING, &b->state) || if (test_bit(B_READING, &b->state) ||
test_bit(B_WRITING, &b->state) || test_bit(B_WRITING, &b->state) ||
test_bit(B_DIRTY, &b->state)) test_bit(B_DIRTY, &b->state))
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once"
#define DM_VERITY_OPT_TASKLET_VERIFY "try_verify_in_tasklet" #define DM_VERITY_OPT_TASKLET_VERIFY "try_verify_in_tasklet"
#define DM_VERITY_OPTS_MAX (3 + DM_VERITY_OPTS_FEC + \ #define DM_VERITY_OPTS_MAX (4 + DM_VERITY_OPTS_FEC + \
DM_VERITY_ROOT_HASH_VERIFICATION_OPTS) DM_VERITY_ROOT_HASH_VERIFICATION_OPTS)
static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;
...@@ -1053,7 +1053,7 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, ...@@ -1053,7 +1053,7 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
struct dm_verity_sig_opts *verify_args, struct dm_verity_sig_opts *verify_args,
bool only_modifier_opts) bool only_modifier_opts)
{ {
int r; int r = 0;
unsigned argc; unsigned argc;
struct dm_target *ti = v->ti; struct dm_target *ti = v->ti;
const char *arg_name; const char *arg_name;
...@@ -1123,8 +1123,18 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, ...@@ -1123,8 +1123,18 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
if (r) if (r)
return r; return r;
continue; continue;
} else if (only_modifier_opts) {
/*
* Ignore unrecognized opt, could easily be an extra
* argument to an option whose parsing was skipped.
* Normal parsing (@only_modifier_opts=false) will
* properly parse all options (and their extra args).
*/
continue;
} }
DMERR("Unrecognized verity feature request: %s", arg_name);
ti->error = "Unrecognized verity feature request"; ti->error = "Unrecognized verity feature request";
return -EINVAL; return -EINVAL;
} while (argc && !r); } while (argc && !r);
......
...@@ -1594,7 +1594,8 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) ...@@ -1594,7 +1594,8 @@ static int writecache_map(struct dm_target *ti, struct bio *bio)
default: default:
BUG(); BUG();
return -1; wc_unlock(wc);
return DM_MAPIO_KILL;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment