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

Commit af91805a authored by Mike Snitzer's avatar Mike Snitzer
Browse files

dm thin: return ENOSPC instead of EIO when error_if_no_space enabled



Update the DM thin provisioning target's allocation failure error to be
consistent with commit a9d6ceb8 ("[SCSI] return ENOSPC on thin
provisioning failure").

The DM thin target now returns -ENOSPC rather than -EIO when
block allocation fails due to the pool being out of data space (and
the 'error_if_no_space' thin-pool feature is enabled).

Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Acked-By: default avatarJoe Thornber <ejt@redhat.com>
parent e7a3e871
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -238,7 +238,7 @@ void dm_cell_release_no_holder(struct dm_bio_prison *prison,
EXPORT_SYMBOL_GPL(dm_cell_release_no_holder);

void dm_cell_error(struct dm_bio_prison *prison,
		   struct dm_bio_prison_cell *cell)
		   struct dm_bio_prison_cell *cell, int error)
{
	struct bio_list bios;
	struct bio *bio;
@@ -251,7 +251,7 @@ void dm_cell_error(struct dm_bio_prison *prison,
	spin_unlock_irqrestore(&prison->lock, flags);

	while ((bio = bio_list_pop(&bios)))
		bio_io_error(bio);
		bio_endio(bio, error);
}
EXPORT_SYMBOL_GPL(dm_cell_error);

+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ void dm_cell_release_no_holder(struct dm_bio_prison *prison,
			       struct dm_bio_prison_cell *cell,
			       struct bio_list *inmates);
void dm_cell_error(struct dm_bio_prison *prison,
		   struct dm_bio_prison_cell *cell);
		   struct dm_bio_prison_cell *cell, int error);

/*----------------------------------------------------------------*/

+24 −14
Original line number Diff line number Diff line
@@ -310,13 +310,18 @@ static void cell_defer_no_holder_no_free(struct thin_c *tc,
	wake_worker(pool);
}

static void cell_error(struct pool *pool,
		       struct dm_bio_prison_cell *cell)
static void cell_error_with_code(struct pool *pool,
				 struct dm_bio_prison_cell *cell, int error_code)
{
	dm_cell_error(pool->prison, cell);
	dm_cell_error(pool->prison, cell, error_code);
	dm_bio_prison_free_cell(pool->prison, cell);
}

static void cell_error(struct pool *pool, struct dm_bio_prison_cell *cell)
{
	cell_error_with_code(pool, cell, -EIO);
}

/*----------------------------------------------------------------*/

/*
@@ -1027,7 +1032,7 @@ static void retry_on_resume(struct bio *bio)
	spin_unlock_irqrestore(&tc->lock, flags);
}

static bool should_error_unserviceable_bio(struct pool *pool)
static int should_error_unserviceable_bio(struct pool *pool)
{
	enum pool_mode m = get_pool_mode(pool);

@@ -1035,25 +1040,27 @@ static bool should_error_unserviceable_bio(struct pool *pool)
	case PM_WRITE:
		/* Shouldn't get here */
		DMERR_LIMIT("bio unserviceable, yet pool is in PM_WRITE mode");
		return true;
		return -EIO;

	case PM_OUT_OF_DATA_SPACE:
		return pool->pf.error_if_no_space;
		return pool->pf.error_if_no_space ? -ENOSPC : 0;

	case PM_READ_ONLY:
	case PM_FAIL:
		return true;
		return -EIO;
	default:
		/* Shouldn't get here */
		DMERR_LIMIT("bio unserviceable, yet pool has an unknown mode");
		return true;
		return -EIO;
	}
}

static void handle_unserviceable_bio(struct pool *pool, struct bio *bio)
{
	if (should_error_unserviceable_bio(pool))
		bio_io_error(bio);
	int error = should_error_unserviceable_bio(pool);

	if (error)
		bio_endio(bio, error);
	else
		retry_on_resume(bio);
}
@@ -1062,18 +1069,21 @@ static void retry_bios_on_resume(struct pool *pool, struct dm_bio_prison_cell *c
{
	struct bio *bio;
	struct bio_list bios;
	int error;

	if (should_error_unserviceable_bio(pool)) {
		cell_error(pool, cell);
	error = should_error_unserviceable_bio(pool);
	if (error) {
		cell_error_with_code(pool, cell, error);
		return;
	}

	bio_list_init(&bios);
	cell_release(pool, cell, &bios);

	if (should_error_unserviceable_bio(pool))
	error = should_error_unserviceable_bio(pool);
	if (error)
		while ((bio = bio_list_pop(&bios)))
			bio_io_error(bio);
			bio_endio(bio, error);
	else
		while ((bio = bio_list_pop(&bios)))
			retry_on_resume(bio);