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

Commit 1f3db25d authored by Mike Snitzer's avatar Mike Snitzer Committed by Alasdair G Kergon
Browse files

dm thin metadata: remove incorrect close_device on creation error paths



The __open_device() error paths in __create_thin() and __create_snap()
incorrectly call __close_device() even if td was not initialized by
__open_device().  Remove this.

Also document __open_device() return values, remove a redundant
td->changed = 1 in __create_thin(), and insert an additional
safeguard against creating an already-existing device.

Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Cc: stable@kernel.org
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 1212268f
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -789,6 +789,11 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
	return 0;
}

/*
 * __open_device: Returns @td corresponding to device with id @dev,
 * creating it if @create is set and incrementing @td->open_count.
 * On failure, @td is undefined.
 */
static int __open_device(struct dm_pool_metadata *pmd,
			 dm_thin_id dev, int create,
			 struct dm_thin_device **td)
@@ -799,10 +804,16 @@ static int __open_device(struct dm_pool_metadata *pmd,
	struct disk_device_details details_le;

	/*
	 * Check the device isn't already open.
	 * If the device is already open, return it.
	 */
	list_for_each_entry(td2, &pmd->thin_devices, list)
		if (td2->id == dev) {
			/*
			 * May not create an already-open device.
			 */
			if (create)
				return -EEXIST;

			td2->open_count++;
			*td = td2;
			return 0;
@@ -817,6 +828,9 @@ static int __open_device(struct dm_pool_metadata *pmd,
		if (r != -ENODATA || !create)
			return r;

		/*
		 * Create new device.
		 */
		changed = 1;
		details_le.mapped_blocks = 0;
		details_le.transaction_id = cpu_to_le64(pmd->trans_id);
@@ -882,12 +896,10 @@ static int __create_thin(struct dm_pool_metadata *pmd,

	r = __open_device(pmd, dev, 1, &td);
	if (r) {
		__close_device(td);
		dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root);
		dm_btree_del(&pmd->bl_info, dev_root);
		return r;
	}
	td->changed = 1;
	__close_device(td);

	return r;
@@ -967,14 +979,14 @@ static int __create_snap(struct dm_pool_metadata *pmd,
		goto bad;

	r = __set_snapshot_details(pmd, td, origin, pmd->time);
	__close_device(td);

	if (r)
		goto bad;

	__close_device(td);
	return 0;

bad:
	__close_device(td);
	dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root);
	dm_btree_remove(&pmd->details_info, pmd->details_root,
			&key, &pmd->details_root);