aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2013-12-06 16:21:43 -0500
committerMike Snitzer <snitzer@redhat.com>2014-01-07 10:14:30 -0500
commit787a996cb251e20f560e1615cd85693562541a7a (patch)
tree86cb09bf6a76217236469ec56b8f609f6141380f
parent8c0f0e8c9f07e6554b2281f86f00e769cf805fd9 (diff)
dm thin: add error_if_no_space feature
If the pool runs out of data or metadata space, the pool can either queue or error the IO destined to the data device. The default is to queue the IO until more space is added. An admin may now configure the pool to error IO when no space is available by setting the 'error_if_no_space' feature when loading the thin-pool table. Signed-off-by: Mike Snitzer <snitzer@redhat.com> Acked-by: Joe Thornber <ejt@redhat.com>
-rw-r--r--Documentation/device-mapper/thin-provisioning.txt7
-rw-r--r--drivers/md/dm-thin.c31
2 files changed, 32 insertions, 6 deletions
diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt
index 50c44cf79b0e..8a7a3d46e0da 100644
--- a/Documentation/device-mapper/thin-provisioning.txt
+++ b/Documentation/device-mapper/thin-provisioning.txt
@@ -235,6 +235,8 @@ i) Constructor
235 read_only: Don't allow any changes to be made to the pool 235 read_only: Don't allow any changes to be made to the pool
236 metadata. 236 metadata.
237 237
238 error_if_no_space: Error IOs, instead of queueing, if no space.
239
238 Data block size must be between 64KB (128 sectors) and 1GB 240 Data block size must be between 64KB (128 sectors) and 1GB
239 (2097152 sectors) inclusive. 241 (2097152 sectors) inclusive.
240 242
@@ -276,6 +278,11 @@ ii) Status
276 contain the string 'Fail'. The userspace recovery tools 278 contain the string 'Fail'. The userspace recovery tools
277 should then be used. 279 should then be used.
278 280
281 error_if_no_space|queue_if_no_space
282 If the pool runs out of data or metadata space, the pool will
283 either queue or error the IO destined to the data device. The
284 default is to queue the IO until more space is added.
285
279iii) Messages 286iii) Messages
280 287
281 create_thin <dev id> 288 create_thin <dev id>
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 53252d2af249..075c39edea21 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -144,6 +144,7 @@ struct pool_features {
144 bool zero_new_blocks:1; 144 bool zero_new_blocks:1;
145 bool discard_enabled:1; 145 bool discard_enabled:1;
146 bool discard_passdown:1; 146 bool discard_passdown:1;
147 bool error_if_no_space:1;
147}; 148};
148 149
149struct thin_c; 150struct thin_c;
@@ -1440,6 +1441,9 @@ static void set_no_free_space(struct pool *pool)
1440{ 1441{
1441 unsigned long flags; 1442 unsigned long flags;
1442 1443
1444 if (pool->pf.error_if_no_space)
1445 return;
1446
1443 spin_lock_irqsave(&pool->lock, flags); 1447 spin_lock_irqsave(&pool->lock, flags);
1444 pool->no_free_space = true; 1448 pool->no_free_space = true;
1445 spin_unlock_irqrestore(&pool->lock, flags); 1449 spin_unlock_irqrestore(&pool->lock, flags);
@@ -1723,6 +1727,7 @@ static void pool_features_init(struct pool_features *pf)
1723 pf->zero_new_blocks = true; 1727 pf->zero_new_blocks = true;
1724 pf->discard_enabled = true; 1728 pf->discard_enabled = true;
1725 pf->discard_passdown = true; 1729 pf->discard_passdown = true;
1730 pf->error_if_no_space = false;
1726} 1731}
1727 1732
1728static void __pool_destroy(struct pool *pool) 1733static void __pool_destroy(struct pool *pool)
@@ -1968,6 +1973,9 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
1968 else if (!strcasecmp(arg_name, "read_only")) 1973 else if (!strcasecmp(arg_name, "read_only"))
1969 pf->mode = PM_READ_ONLY; 1974 pf->mode = PM_READ_ONLY;
1970 1975
1976 else if (!strcasecmp(arg_name, "error_if_no_space"))
1977 pf->error_if_no_space = true;
1978
1971 else { 1979 else {
1972 ti->error = "Unrecognised pool feature requested"; 1980 ti->error = "Unrecognised pool feature requested";
1973 r = -EINVAL; 1981 r = -EINVAL;
@@ -2038,6 +2046,8 @@ static dm_block_t calc_metadata_threshold(struct pool_c *pt)
2038 * skip_block_zeroing: skips the zeroing of newly-provisioned blocks. 2046 * skip_block_zeroing: skips the zeroing of newly-provisioned blocks.
2039 * ignore_discard: disable discard 2047 * ignore_discard: disable discard
2040 * no_discard_passdown: don't pass discards down to the data device 2048 * no_discard_passdown: don't pass discards down to the data device
2049 * read_only: Don't allow any changes to be made to the pool metadata.
2050 * error_if_no_space: error IOs, instead of queueing, if no space.
2041 */ 2051 */
2042static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) 2052static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
2043{ 2053{
@@ -2555,7 +2565,8 @@ static void emit_flags(struct pool_features *pf, char *result,
2555 unsigned sz, unsigned maxlen) 2565 unsigned sz, unsigned maxlen)
2556{ 2566{
2557 unsigned count = !pf->zero_new_blocks + !pf->discard_enabled + 2567 unsigned count = !pf->zero_new_blocks + !pf->discard_enabled +
2558 !pf->discard_passdown + (pf->mode == PM_READ_ONLY); 2568 !pf->discard_passdown + (pf->mode == PM_READ_ONLY) +
2569 pf->error_if_no_space;
2559 DMEMIT("%u ", count); 2570 DMEMIT("%u ", count);
2560 2571
2561 if (!pf->zero_new_blocks) 2572 if (!pf->zero_new_blocks)
@@ -2569,6 +2580,9 @@ static void emit_flags(struct pool_features *pf, char *result,
2569 2580
2570 if (pf->mode == PM_READ_ONLY) 2581 if (pf->mode == PM_READ_ONLY)
2571 DMEMIT("read_only "); 2582 DMEMIT("read_only ");
2583
2584 if (pf->error_if_no_space)
2585 DMEMIT("error_if_no_space ");
2572} 2586}
2573 2587
2574/* 2588/*
@@ -2663,11 +2677,16 @@ static void pool_status(struct dm_target *ti, status_type_t type,
2663 DMEMIT("rw "); 2677 DMEMIT("rw ");
2664 2678
2665 if (!pool->pf.discard_enabled) 2679 if (!pool->pf.discard_enabled)
2666 DMEMIT("ignore_discard"); 2680 DMEMIT("ignore_discard ");
2667 else if (pool->pf.discard_passdown) 2681 else if (pool->pf.discard_passdown)
2668 DMEMIT("discard_passdown"); 2682 DMEMIT("discard_passdown ");
2683 else
2684 DMEMIT("no_discard_passdown ");
2685
2686 if (pool->pf.error_if_no_space)
2687 DMEMIT("error_if_no_space ");
2669 else 2688 else
2670 DMEMIT("no_discard_passdown"); 2689 DMEMIT("queue_if_no_space ");
2671 2690
2672 break; 2691 break;
2673 2692
@@ -2766,7 +2785,7 @@ static struct target_type pool_target = {
2766 .name = "thin-pool", 2785 .name = "thin-pool",
2767 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | 2786 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
2768 DM_TARGET_IMMUTABLE, 2787 DM_TARGET_IMMUTABLE,
2769 .version = {1, 9, 0}, 2788 .version = {1, 10, 0},
2770 .module = THIS_MODULE, 2789 .module = THIS_MODULE,
2771 .ctr = pool_ctr, 2790 .ctr = pool_ctr,
2772 .dtr = pool_dtr, 2791 .dtr = pool_dtr,
@@ -3053,7 +3072,7 @@ static int thin_iterate_devices(struct dm_target *ti,
3053 3072
3054static struct target_type thin_target = { 3073static struct target_type thin_target = {
3055 .name = "thin", 3074 .name = "thin",
3056 .version = {1, 9, 0}, 3075 .version = {1, 10, 0},
3057 .module = THIS_MODULE, 3076 .module = THIS_MODULE,
3058 .ctr = thin_ctr, 3077 .ctr = thin_ctr,
3059 .dtr = thin_dtr, 3078 .dtr = thin_dtr,