dm thin: return ENOSPC instead of EIO when error_if_no_space enabled
authorMike Snitzer <snitzer@redhat.com>
Thu, 22 May 2014 18:32:51 +0000 (14:32 -0400)
committerMike Snitzer <snitzer@redhat.com>
Tue, 3 Jun 2014 17:44:08 +0000 (13:44 -0400)
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: Mike Snitzer <snitzer@redhat.com>
Acked-By: Joe Thornber <ejt@redhat.com>
drivers/md/dm-bio-prison.c
drivers/md/dm-bio-prison.h
drivers/md/dm-thin.c

index 85f0b7074257b02aa53cb62f464a163ed6a56469..71434382cb6479faf96b09e2e5d20230a20d313b 100644 (file)
@@ -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);
 
index 3f833190eadf6b3a275951a71558a583811d37ad..6805a142b750ee594d5ca2bda987d49a09787b39 100644 (file)
@@ -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);
 
 /*----------------------------------------------------------------*/
 
index 7694988fb806a72919110525878b0ee3725d5c88..a0bdd562e0267ae5aed58cb1913e1b3edc6f6488 100644 (file)
@@ -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);
This page took 0.028704 seconds and 5 git commands to generate.