diff options
-rw-r--r-- | Documentation/device-mapper/thin-provisioning.txt | 7 | ||||
-rw-r--r-- | drivers/md/dm-thin.c | 31 |
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 | |||
279 | iii) Messages | 286 | iii) 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 | ||
149 | struct thin_c; | 150 | struct 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 | ||
1728 | static void __pool_destroy(struct pool *pool) | 1733 | static 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 | */ |
2042 | static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | 2052 | static 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 | ||
3054 | static struct target_type thin_target = { | 3073 | static 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, |