aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,