Commit 5556a78c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-6.1/dm-fixes-2' of...

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

Pull device mapper fixes from Mike Snitzer:

 - Fix misbehavior if list_versions DM ioctl races with module loading

 - Fix missing decrement of no_sleep_enabled if dm_bufio_client_create
   failed

 - Allow DM integrity devices to be activated in read-only mode

* tag 'for-6.1/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm integrity: clear the journal on suspend
  dm integrity: flush the journal on suspend
  dm bufio: Fix missing decrement of no_sleep_enabled if dm_bufio_client_create failed
  dm ioctl: fix misbehavior if list_versions races with module loading
parents 950a9f56 984bf2cc
...@@ -1858,6 +1858,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign ...@@ -1858,6 +1858,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
dm_io_client_destroy(c->dm_io); dm_io_client_destroy(c->dm_io);
bad_dm_io: bad_dm_io:
mutex_destroy(&c->lock); mutex_destroy(&c->lock);
if (c->no_sleep)
static_branch_dec(&no_sleep_enabled);
kfree(c); kfree(c);
bad_client: bad_client:
return ERR_PTR(r); return ERR_PTR(r);
......
...@@ -263,6 +263,7 @@ struct dm_integrity_c { ...@@ -263,6 +263,7 @@ struct dm_integrity_c {
struct completion crypto_backoff; struct completion crypto_backoff;
bool wrote_to_journal;
bool journal_uptodate; bool journal_uptodate;
bool just_formatted; bool just_formatted;
bool recalculate_flag; bool recalculate_flag;
...@@ -2375,6 +2376,8 @@ static void integrity_commit(struct work_struct *w) ...@@ -2375,6 +2376,8 @@ static void integrity_commit(struct work_struct *w)
if (!commit_sections) if (!commit_sections)
goto release_flush_bios; goto release_flush_bios;
ic->wrote_to_journal = true;
i = commit_start; i = commit_start;
for (n = 0; n < commit_sections; n++) { for (n = 0; n < commit_sections; n++) {
for (j = 0; j < ic->journal_section_entries; j++) { for (j = 0; j < ic->journal_section_entries; j++) {
...@@ -2591,10 +2594,6 @@ static void integrity_writer(struct work_struct *w) ...@@ -2591,10 +2594,6 @@ static void integrity_writer(struct work_struct *w)
unsigned prev_free_sectors; unsigned prev_free_sectors;
/* the following test is not needed, but it tests the replay code */
if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev)
return;
spin_lock_irq(&ic->endio_wait.lock); spin_lock_irq(&ic->endio_wait.lock);
write_start = ic->committed_section; write_start = ic->committed_section;
write_sections = ic->n_committed_sections; write_sections = ic->n_committed_sections;
...@@ -3101,10 +3100,17 @@ static void dm_integrity_postsuspend(struct dm_target *ti) ...@@ -3101,10 +3100,17 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
drain_workqueue(ic->commit_wq); drain_workqueue(ic->commit_wq);
if (ic->mode == 'J') { if (ic->mode == 'J') {
if (ic->meta_dev) queue_work(ic->writer_wq, &ic->writer_work);
queue_work(ic->writer_wq, &ic->writer_work);
drain_workqueue(ic->writer_wq); drain_workqueue(ic->writer_wq);
dm_integrity_flush_buffers(ic, true); dm_integrity_flush_buffers(ic, true);
if (ic->wrote_to_journal) {
init_journal(ic, ic->free_section,
ic->journal_sections - ic->free_section, ic->commit_seq);
if (ic->free_section) {
init_journal(ic, 0, ic->free_section,
next_commit_seq(ic->commit_seq));
}
}
} }
if (ic->mode == 'B') { if (ic->mode == 'B') {
...@@ -3132,6 +3138,8 @@ static void dm_integrity_resume(struct dm_target *ti) ...@@ -3132,6 +3138,8 @@ static void dm_integrity_resume(struct dm_target *ti)
DEBUG_print("resume\n"); DEBUG_print("resume\n");
ic->wrote_to_journal = false;
if (ic->provided_data_sectors != old_provided_data_sectors) { if (ic->provided_data_sectors != old_provided_data_sectors) {
if (ic->provided_data_sectors > old_provided_data_sectors && if (ic->provided_data_sectors > old_provided_data_sectors &&
ic->mode == 'B' && ic->mode == 'B' &&
......
...@@ -655,7 +655,7 @@ static void list_version_get_needed(struct target_type *tt, void *needed_param) ...@@ -655,7 +655,7 @@ static void list_version_get_needed(struct target_type *tt, void *needed_param)
size_t *needed = needed_param; size_t *needed = needed_param;
*needed += sizeof(struct dm_target_versions); *needed += sizeof(struct dm_target_versions);
*needed += strlen(tt->name); *needed += strlen(tt->name) + 1;
*needed += ALIGN_MASK; *needed += ALIGN_MASK;
} }
...@@ -720,7 +720,7 @@ static int __list_versions(struct dm_ioctl *param, size_t param_size, const char ...@@ -720,7 +720,7 @@ static int __list_versions(struct dm_ioctl *param, size_t param_size, const char
iter_info.old_vers = NULL; iter_info.old_vers = NULL;
iter_info.vers = vers; iter_info.vers = vers;
iter_info.flags = 0; iter_info.flags = 0;
iter_info.end = (char *)vers+len; iter_info.end = (char *)vers + needed;
/* /*
* Now loop through filling out the names & versions. * Now loop through filling out the names & versions.
......
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