aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2013-08-22 09:56:18 -0400
committerMike Snitzer <snitzer@redhat.com>2013-09-05 20:46:06 -0400
commit94563badaf41f9291ff0bad94a443a4319b9e312 (patch)
tree6c9bf7f6aba642dd4a08035fe93ec683c3fdf5bf /drivers/md
parentf11c1c5693fac339d412b0b59b54693ddcb776ff (diff)
dm thin: always return -ENOSPC if no_free_space is set
If pool has 'no_free_space' set it means a previous allocation already determined the pool has no free space (and failed that allocation with -ENOSPC). By always returning -ENOSPC if 'no_free_space' is set, we do not allow the pool to oscillate between allocating blocks and then not. But a side-effect of this determinism is that if a user wants to be able to allocate new blocks they'll need to reload the pool's table (to clear the 'no_free_space' flag). This reload will happen automatically if the pool's data volume is resized. But if the user takes action to free a lot of space by deleting snapshot volumes, etc the pool will no longer allow data allocations to continue without an intervening table reload. Signed-off-by: Mike Snitzer <snitzer@redhat.com> Acked-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-thin.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 3aff1c27e5b4..ed063427d676 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -918,6 +918,13 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
918 unsigned long flags; 918 unsigned long flags;
919 struct pool *pool = tc->pool; 919 struct pool *pool = tc->pool;
920 920
921 /*
922 * Once no_free_space is set we must not allow allocation to succeed.
923 * Otherwise it is difficult to explain, debug, test and support.
924 */
925 if (pool->no_free_space)
926 return -ENOSPC;
927
921 r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); 928 r = dm_pool_get_free_block_count(pool->pmd, &free_blocks);
922 if (r) 929 if (r)
923 return r; 930 return r;
@@ -932,31 +939,30 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
932 } 939 }
933 940
934 if (!free_blocks) { 941 if (!free_blocks) {
935 if (pool->no_free_space) 942 /*
936 return -ENOSPC; 943 * Try to commit to see if that will free up some
937 else { 944 * more space.
938 /* 945 */
939 * Try to commit to see if that will free up some 946 (void) commit_or_fallback(pool);
940 * more space.
941 */
942 (void) commit_or_fallback(pool);
943 947
944 r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); 948 r = dm_pool_get_free_block_count(pool->pmd, &free_blocks);
945 if (r) 949 if (r)
946 return r; 950 return r;
947 951
948 /* 952 /*
949 * If we still have no space we set a flag to avoid 953 * If we still have no space we set a flag to avoid
950 * doing all this checking and return -ENOSPC. 954 * doing all this checking and return -ENOSPC. This
951 */ 955 * flag serves as a latch that disallows allocations from
952 if (!free_blocks) { 956 * this pool until the admin takes action (e.g. resize or
953 DMWARN("%s: no free space available.", 957 * table reload).
954 dm_device_name(pool->pool_md)); 958 */
955 spin_lock_irqsave(&pool->lock, flags); 959 if (!free_blocks) {
956 pool->no_free_space = 1; 960 DMWARN("%s: no free space available.",
957 spin_unlock_irqrestore(&pool->lock, flags); 961 dm_device_name(pool->pool_md));
958 return -ENOSPC; 962 spin_lock_irqsave(&pool->lock, flags);
959 } 963 pool->no_free_space = 1;
964 spin_unlock_irqrestore(&pool->lock, flags);
965 return -ENOSPC;
960 } 966 }
961 } 967 }
962 968
@@ -2695,7 +2701,7 @@ static struct target_type pool_target = {
2695 .name = "thin-pool", 2701 .name = "thin-pool",
2696 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | 2702 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
2697 DM_TARGET_IMMUTABLE, 2703 DM_TARGET_IMMUTABLE,
2698 .version = {1, 8, 0}, 2704 .version = {1, 9, 0},
2699 .module = THIS_MODULE, 2705 .module = THIS_MODULE,
2700 .ctr = pool_ctr, 2706 .ctr = pool_ctr,
2701 .dtr = pool_dtr, 2707 .dtr = pool_dtr,
@@ -2982,7 +2988,7 @@ static int thin_iterate_devices(struct dm_target *ti,
2982 2988
2983static struct target_type thin_target = { 2989static struct target_type thin_target = {
2984 .name = "thin", 2990 .name = "thin",
2985 .version = {1, 8, 0}, 2991 .version = {1, 9, 0},
2986 .module = THIS_MODULE, 2992 .module = THIS_MODULE,
2987 .ctr = thin_ctr, 2993 .ctr = thin_ctr,
2988 .dtr = thin_dtr, 2994 .dtr = thin_dtr,