Commit 94563badaf41f9291ff0bad94a443a4319b9e312
1 parent
f11c1c5693
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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>
Showing 1 changed file with 31 additions and 25 deletions Side-by-side Diff
drivers/md/dm-thin.c
... | ... | @@ -918,6 +918,13 @@ |
918 | 918 | unsigned long flags; |
919 | 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 | 928 | r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); |
922 | 929 | if (r) |
923 | 930 | return r; |
924 | 931 | |
925 | 932 | |
... | ... | @@ -932,31 +939,30 @@ |
932 | 939 | } |
933 | 940 | |
934 | 941 | if (!free_blocks) { |
935 | - if (pool->no_free_space) | |
936 | - return -ENOSPC; | |
937 | - else { | |
938 | - /* | |
939 | - * Try to commit to see if that will free up some | |
940 | - * more space. | |
941 | - */ | |
942 | - (void) commit_or_fallback(pool); | |
942 | + /* | |
943 | + * Try to commit to see if that will free up some | |
944 | + * more space. | |
945 | + */ | |
946 | + (void) commit_or_fallback(pool); | |
943 | 947 | |
944 | - r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); | |
945 | - if (r) | |
946 | - return r; | |
948 | + r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); | |
949 | + if (r) | |
950 | + return r; | |
947 | 951 | |
948 | - /* | |
949 | - * If we still have no space we set a flag to avoid | |
950 | - * doing all this checking and return -ENOSPC. | |
951 | - */ | |
952 | - if (!free_blocks) { | |
953 | - DMWARN("%s: no free space available.", | |
954 | - dm_device_name(pool->pool_md)); | |
955 | - spin_lock_irqsave(&pool->lock, flags); | |
956 | - pool->no_free_space = 1; | |
957 | - spin_unlock_irqrestore(&pool->lock, flags); | |
958 | - return -ENOSPC; | |
959 | - } | |
952 | + /* | |
953 | + * If we still have no space we set a flag to avoid | |
954 | + * doing all this checking and return -ENOSPC. This | |
955 | + * flag serves as a latch that disallows allocations from | |
956 | + * this pool until the admin takes action (e.g. resize or | |
957 | + * table reload). | |
958 | + */ | |
959 | + if (!free_blocks) { | |
960 | + DMWARN("%s: no free space available.", | |
961 | + dm_device_name(pool->pool_md)); | |
962 | + spin_lock_irqsave(&pool->lock, flags); | |
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 @@ |
2695 | 2701 | .name = "thin-pool", |
2696 | 2702 | .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | |
2697 | 2703 | DM_TARGET_IMMUTABLE, |
2698 | - .version = {1, 8, 0}, | |
2704 | + .version = {1, 9, 0}, | |
2699 | 2705 | .module = THIS_MODULE, |
2700 | 2706 | .ctr = pool_ctr, |
2701 | 2707 | .dtr = pool_dtr, |
... | ... | @@ -2982,7 +2988,7 @@ |
2982 | 2988 | |
2983 | 2989 | static struct target_type thin_target = { |
2984 | 2990 | .name = "thin", |
2985 | - .version = {1, 8, 0}, | |
2991 | + .version = {1, 9, 0}, | |
2986 | 2992 | .module = THIS_MODULE, |
2987 | 2993 | .ctr = thin_ctr, |
2988 | 2994 | .dtr = thin_dtr, |