Commit 381b9b4c authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba

btrfs: use integrated bitmaps for scrub_parity::dbitmap and ebitmap

Previously we use "unsigned long *" for those two bitmaps.

But since we only support fixed stripe length (64KiB, already checked in
tree-checker), "unsigned long *" is really a waste of memory, while we
can just use "unsigned long".

This saves us 8 bytes in total for scrub_parity.

To be extra safe, add an ASSERT() making sure calclulated @nsectors is
always smaller than BITS_PER_LONG.
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent c67c68eb
...@@ -135,15 +135,13 @@ struct scrub_parity { ...@@ -135,15 +135,13 @@ struct scrub_parity {
struct work_struct work; struct work_struct work;
/* Mark the parity blocks which have data */ /* Mark the parity blocks which have data */
unsigned long *dbitmap; unsigned long dbitmap;
/* /*
* Mark the parity blocks which have data, but errors happen when * Mark the parity blocks which have data, but errors happen when
* read data or check data * read data or check data
*/ */
unsigned long *ebitmap; unsigned long ebitmap;
unsigned long bitmap[];
}; };
struct scrub_ctx { struct scrub_ctx {
...@@ -2406,13 +2404,13 @@ static inline void __scrub_mark_bitmap(struct scrub_parity *sparity, ...@@ -2406,13 +2404,13 @@ static inline void __scrub_mark_bitmap(struct scrub_parity *sparity,
static inline void scrub_parity_mark_sectors_error(struct scrub_parity *sparity, static inline void scrub_parity_mark_sectors_error(struct scrub_parity *sparity,
u64 start, u32 len) u64 start, u32 len)
{ {
__scrub_mark_bitmap(sparity, sparity->ebitmap, start, len); __scrub_mark_bitmap(sparity, &sparity->ebitmap, start, len);
} }
static inline void scrub_parity_mark_sectors_data(struct scrub_parity *sparity, static inline void scrub_parity_mark_sectors_data(struct scrub_parity *sparity,
u64 start, u32 len) u64 start, u32 len)
{ {
__scrub_mark_bitmap(sparity, sparity->dbitmap, start, len); __scrub_mark_bitmap(sparity, &sparity->dbitmap, start, len);
} }
static void scrub_block_complete(struct scrub_block *sblock) static void scrub_block_complete(struct scrub_block *sblock)
...@@ -2763,7 +2761,7 @@ static void scrub_free_parity(struct scrub_parity *sparity) ...@@ -2763,7 +2761,7 @@ static void scrub_free_parity(struct scrub_parity *sparity)
struct scrub_sector *curr, *next; struct scrub_sector *curr, *next;
int nbits; int nbits;
nbits = bitmap_weight(sparity->ebitmap, sparity->nsectors); nbits = bitmap_weight(&sparity->ebitmap, sparity->nsectors);
if (nbits) { if (nbits) {
spin_lock(&sctx->stat_lock); spin_lock(&sctx->stat_lock);
sctx->stat.read_errors += nbits; sctx->stat.read_errors += nbits;
...@@ -2795,8 +2793,8 @@ static void scrub_parity_bio_endio(struct bio *bio) ...@@ -2795,8 +2793,8 @@ static void scrub_parity_bio_endio(struct bio *bio)
struct btrfs_fs_info *fs_info = sparity->sctx->fs_info; struct btrfs_fs_info *fs_info = sparity->sctx->fs_info;
if (bio->bi_status) if (bio->bi_status)
bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap, bitmap_or(&sparity->ebitmap, &sparity->ebitmap,
sparity->nsectors); &sparity->dbitmap, sparity->nsectors);
bio_put(bio); bio_put(bio);
...@@ -2814,8 +2812,8 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity) ...@@ -2814,8 +2812,8 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
u64 length; u64 length;
int ret; int ret;
if (!bitmap_andnot(sparity->dbitmap, sparity->dbitmap, sparity->ebitmap, if (!bitmap_andnot(&sparity->dbitmap, &sparity->dbitmap,
sparity->nsectors)) &sparity->ebitmap, sparity->nsectors))
goto out; goto out;
length = sparity->logic_end - sparity->logic_start; length = sparity->logic_end - sparity->logic_start;
...@@ -2833,7 +2831,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity) ...@@ -2833,7 +2831,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
rbio = raid56_parity_alloc_scrub_rbio(bio, bioc, length, rbio = raid56_parity_alloc_scrub_rbio(bio, bioc, length,
sparity->scrub_dev, sparity->scrub_dev,
sparity->dbitmap, &sparity->dbitmap,
sparity->nsectors); sparity->nsectors);
if (!rbio) if (!rbio)
goto rbio_out; goto rbio_out;
...@@ -2847,7 +2845,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity) ...@@ -2847,7 +2845,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
bioc_out: bioc_out:
btrfs_bio_counter_dec(fs_info); btrfs_bio_counter_dec(fs_info);
btrfs_put_bioc(bioc); btrfs_put_bioc(bioc);
bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap, bitmap_or(&sparity->ebitmap, &sparity->ebitmap, &sparity->dbitmap,
sparity->nsectors); sparity->nsectors);
spin_lock(&sctx->stat_lock); spin_lock(&sctx->stat_lock);
sctx->stat.malloc_errors++; sctx->stat.malloc_errors++;
...@@ -2856,11 +2854,6 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity) ...@@ -2856,11 +2854,6 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
scrub_free_parity(sparity); scrub_free_parity(sparity);
} }
static inline int scrub_calc_parity_bitmap_len(int nsectors)
{
return DIV_ROUND_UP(nsectors, BITS_PER_LONG) * sizeof(long);
}
static void scrub_parity_get(struct scrub_parity *sparity) static void scrub_parity_get(struct scrub_parity *sparity)
{ {
refcount_inc(&sparity->refs); refcount_inc(&sparity->refs);
...@@ -3131,7 +3124,6 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx, ...@@ -3131,7 +3124,6 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx,
int ret; int ret;
struct scrub_parity *sparity; struct scrub_parity *sparity;
int nsectors; int nsectors;
int bitmap_len;
path = btrfs_alloc_path(); path = btrfs_alloc_path();
if (!path) { if (!path) {
...@@ -3145,9 +3137,8 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx, ...@@ -3145,9 +3137,8 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx,
ASSERT(map->stripe_len <= U32_MAX); ASSERT(map->stripe_len <= U32_MAX);
nsectors = map->stripe_len >> fs_info->sectorsize_bits; nsectors = map->stripe_len >> fs_info->sectorsize_bits;
bitmap_len = scrub_calc_parity_bitmap_len(nsectors); ASSERT(nsectors <= BITS_PER_LONG);
sparity = kzalloc(sizeof(struct scrub_parity) + 2 * bitmap_len, sparity = kzalloc(sizeof(struct scrub_parity), GFP_NOFS);
GFP_NOFS);
if (!sparity) { if (!sparity) {
spin_lock(&sctx->stat_lock); spin_lock(&sctx->stat_lock);
sctx->stat.malloc_errors++; sctx->stat.malloc_errors++;
...@@ -3165,8 +3156,6 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx, ...@@ -3165,8 +3156,6 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx,
sparity->logic_end = logic_end; sparity->logic_end = logic_end;
refcount_set(&sparity->refs, 1); refcount_set(&sparity->refs, 1);
INIT_LIST_HEAD(&sparity->sectors_list); INIT_LIST_HEAD(&sparity->sectors_list);
sparity->dbitmap = sparity->bitmap;
sparity->ebitmap = (void *)sparity->bitmap + bitmap_len;
ret = 0; ret = 0;
for (cur_logical = logic_start; cur_logical < logic_end; for (cur_logical = logic_start; cur_logical < logic_end;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment