Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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

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

Pull device mapper fixes from Mike Snitzer:

 - Revert a DM bufio change from during the 5.3 merge window now that a
   proper fix has been made to the block loopback driver.

 - Fix DM kcopyd to wakeup so failed subjobs get completed.

 - Various fixes to DM zoned target to address error handling, and other
   small tweaks (SPDX license identifiers and fix typos).

 - Fix DM integrity range locking race by tracking whether journal has
   changed.

 - Fix DM dust target to detect reads of badblocks beyond the first 512b
   sector (applicable if blocksize is larger than 512b).

 - Fix DM persistent-data issue in both the DM btree and DM
   space-map-metadata interfaces.

 - Fix out of bounds memory access with certain DM table configurations.

* tag 'for-5.3/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm table: fix invalid memory accesses with too high sector number
  dm space map metadata: fix missing store of apply_bops() return value
  dm btree: fix order of block initialization in btree_split_beneath
  dm raid: add missing cleanup in raid_ctr()
  dm zoned: fix potential NULL dereference in dmz_do_reclaim()
  dm dust: use dust block size for badblocklist index
  dm integrity: fix a crash due to BUG_ON in __journal_read_write()
  dm zoned: fix a few typos
  dm zoned: add SPDX license identifiers
  dm zoned: properly handle backing device failure
  dm zoned: improve error handling in i/o map code
  dm zoned: improve error handling in reclaim
  dm kcopyd: always complete failed jobs
  Revert "dm bufio: fix deadlock with loop device"
parents f576518c 1cfd5d33
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1599,7 +1599,9 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
	unsigned long freed;

	c = container_of(shrink, struct dm_bufio_client, shrinker);
	if (!dm_bufio_trylock(c))
	if (sc->gfp_mask & __GFP_FS)
		dm_bufio_lock(c);
	else if (!dm_bufio_trylock(c))
		return SHRINK_STOP;

	freed  = __scan(c, sc->nr_to_scan, sc->gfp_mask);
+8 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ struct dust_device {
	unsigned long long badblock_count;
	spinlock_t dust_lock;
	unsigned int blksz;
	int sect_per_block_shift;
	unsigned int sect_per_block;
	sector_t start;
	bool fail_read_on_bb:1;
@@ -79,7 +80,7 @@ static int dust_remove_block(struct dust_device *dd, unsigned long long block)
	unsigned long flags;

	spin_lock_irqsave(&dd->dust_lock, flags);
	bblock = dust_rb_search(&dd->badblocklist, block * dd->sect_per_block);
	bblock = dust_rb_search(&dd->badblocklist, block);

	if (bblock == NULL) {
		if (!dd->quiet_mode) {
@@ -113,7 +114,7 @@ static int dust_add_block(struct dust_device *dd, unsigned long long block)
	}

	spin_lock_irqsave(&dd->dust_lock, flags);
	bblock->bb = block * dd->sect_per_block;
	bblock->bb = block;
	if (!dust_rb_insert(&dd->badblocklist, bblock)) {
		if (!dd->quiet_mode) {
			DMERR("%s: block %llu already in badblocklist",
@@ -138,7 +139,7 @@ static int dust_query_block(struct dust_device *dd, unsigned long long block)
	unsigned long flags;

	spin_lock_irqsave(&dd->dust_lock, flags);
	bblock = dust_rb_search(&dd->badblocklist, block * dd->sect_per_block);
	bblock = dust_rb_search(&dd->badblocklist, block);
	if (bblock != NULL)
		DMINFO("%s: block %llu found in badblocklist", __func__, block);
	else
@@ -165,6 +166,7 @@ static int dust_map_read(struct dust_device *dd, sector_t thisblock,
	int ret = DM_MAPIO_REMAPPED;

	if (fail_read_on_bb) {
		thisblock >>= dd->sect_per_block_shift;
		spin_lock_irqsave(&dd->dust_lock, flags);
		ret = __dust_map_read(dd, thisblock);
		spin_unlock_irqrestore(&dd->dust_lock, flags);
@@ -195,6 +197,7 @@ static int dust_map_write(struct dust_device *dd, sector_t thisblock,
	unsigned long flags;

	if (fail_read_on_bb) {
		thisblock >>= dd->sect_per_block_shift;
		spin_lock_irqsave(&dd->dust_lock, flags);
		__dust_map_write(dd, thisblock);
		spin_unlock_irqrestore(&dd->dust_lock, flags);
@@ -331,6 +334,8 @@ static int dust_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	dd->blksz = blksz;
	dd->start = tmp;

	dd->sect_per_block_shift = __ffs(sect_per_block);

	/*
	 * Whether to fail a read on a "bad" block.
	 * Defaults to false; enabled later by message.
+15 −0
Original line number Diff line number Diff line
@@ -1943,7 +1943,22 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
			queue_work(ic->wait_wq, &dio->work);
			return;
		}
		if (journal_read_pos != NOT_FOUND)
			dio->range.n_sectors = ic->sectors_per_block;
		wait_and_add_new_range(ic, &dio->range);
		/*
		 * wait_and_add_new_range drops the spinlock, so the journal
		 * may have been changed arbitrarily. We need to recheck.
		 * To simplify the code, we restrict I/O size to just one block.
		 */
		if (journal_read_pos != NOT_FOUND) {
			sector_t next_sector;
			unsigned new_pos = find_journal_node(ic, dio->range.logical_sector, &next_sector);
			if (unlikely(new_pos != journal_read_pos)) {
				remove_range_unlocked(ic, &dio->range);
				goto retry;
			}
		}
	}
	spin_unlock_irq(&ic->endio_wait.lock);

+4 −1
Original line number Diff line number Diff line
@@ -566,8 +566,10 @@ static int run_io_job(struct kcopyd_job *job)
	 * no point in continuing.
	 */
	if (test_bit(DM_KCOPYD_WRITE_SEQ, &job->flags) &&
	    job->master_job->write_err)
	    job->master_job->write_err) {
		job->write_err = job->master_job->write_err;
		return -EIO;
	}

	io_job_start(job->kc->throttle);

@@ -619,6 +621,7 @@ static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc,
			else
				job->read_err = 1;
			push(&kc->complete_jobs, job);
			wake(kc);
			break;
		}

+1 −1
Original line number Diff line number Diff line
@@ -3194,7 +3194,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
			  */
			r = rs_prepare_reshape(rs);
			if (r)
				return r;
				goto bad;

			/* Reshaping ain't recovery, so disable recovery */
			rs_setup_recovery(rs, MaxSector);
Loading