aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2011-08-05 05:32:35 -0400
committerChris Mason <chris.mason@oracle.com>2011-08-16 21:09:31 -0400
commitbb3ac5a4dfc8eeb881206c77d9f925e320d9c41a (patch)
treeae5cb912cdc3a36a0aa7d43a554658821e0a6161 /fs
parentf4ac904c411b55e58bb240f332f93db2455f0010 (diff)
Btrfs: fix wrong free space information
Btrfs subtracted the size of the allocated space twice when it allocated the space from the bitmap in the cluster, it broke the free space information and led to oops finally. And this patch also fixes the bug that ctl->free_space was subtracted without lock. Reported-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/free-space-cache.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 6377713f639c..6a265b9f85f2 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -1168,9 +1168,9 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl)
1168 div64_u64(extent_bytes, (sizeof(struct btrfs_free_space))); 1168 div64_u64(extent_bytes, (sizeof(struct btrfs_free_space)));
1169} 1169}
1170 1170
1171static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, 1171static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
1172 struct btrfs_free_space *info, u64 offset, 1172 struct btrfs_free_space *info,
1173 u64 bytes) 1173 u64 offset, u64 bytes)
1174{ 1174{
1175 unsigned long start, count; 1175 unsigned long start, count;
1176 1176
@@ -1181,6 +1181,13 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
1181 bitmap_clear(info->bitmap, start, count); 1181 bitmap_clear(info->bitmap, start, count);
1182 1182
1183 info->bytes -= bytes; 1183 info->bytes -= bytes;
1184}
1185
1186static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
1187 struct btrfs_free_space *info, u64 offset,
1188 u64 bytes)
1189{
1190 __bitmap_clear_bits(ctl, info, offset, bytes);
1184 ctl->free_space -= bytes; 1191 ctl->free_space -= bytes;
1185} 1192}
1186 1193
@@ -1984,7 +1991,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
1984 return 0; 1991 return 0;
1985 1992
1986 ret = search_start; 1993 ret = search_start;
1987 bitmap_clear_bits(ctl, entry, ret, bytes); 1994 __bitmap_clear_bits(ctl, entry, ret, bytes);
1988 1995
1989 return ret; 1996 return ret;
1990} 1997}
@@ -2039,7 +2046,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
2039 continue; 2046 continue;
2040 } 2047 }
2041 } else { 2048 } else {
2042
2043 ret = entry->offset; 2049 ret = entry->offset;
2044 2050
2045 entry->offset += bytes; 2051 entry->offset += bytes;