Skip to content

Commit 1286bb8

Browse files
adam900710kdave
authored andcommitted
btrfs: raid56: move sector_ptr::uptodate into a dedicated bitmap
The uptodate boolean member can be extracted into a bitmap, which will save us some space (1 bit in a byte vs 8 bits in a byte). Furthermore we do not need to record the uptodate bitmap for bio sectors, as if bio_sectors[].paddr is valid it means there is a bio and will be uptodate. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 5931c3d commit 1286bb8

File tree

2 files changed

+36
-35
lines changed

2 files changed

+36
-35
lines changed

fs/btrfs/raid56.c

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ struct sector_ptr {
151151
* If it's INVALID_PADDR then it's not set.
152152
*/
153153
phys_addr_t paddr;
154-
bool uptodate;
155154
};
156155

157156
static void rmw_rbio_work(struct work_struct *work);
@@ -277,13 +276,13 @@ static void cache_rbio_pages(struct btrfs_raid_bio *rbio)
277276
* read from disk.
278277
*/
279278
if (i < rbio->nr_data * rbio->stripe_nsectors)
280-
ASSERT(rbio->stripe_sectors[i].uptodate);
279+
ASSERT(test_bit(i, rbio->stripe_uptodate_bitmap));
281280
continue;
282281
}
283282

284283
memcpy_sectors(&rbio->stripe_sectors[i], &rbio->bio_sectors[i],
285284
rbio->bioc->fs_info->sectorsize);
286-
rbio->stripe_sectors[i].uptodate = 1;
285+
set_bit(i, rbio->stripe_uptodate_bitmap);
287286
}
288287
set_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
289288
}
@@ -318,7 +317,7 @@ static __maybe_unused bool full_page_sectors_uptodate(struct btrfs_raid_bio *rbi
318317
for (i = sectors_per_page * page_nr;
319318
i < sectors_per_page * page_nr + sectors_per_page;
320319
i++) {
321-
if (!rbio->stripe_sectors[i].uptodate)
320+
if (!test_bit(i, rbio->stripe_uptodate_bitmap))
322321
return false;
323322
}
324323
return true;
@@ -353,17 +352,14 @@ static void steal_rbio_page(struct btrfs_raid_bio *src,
353352
{
354353
const u32 sectorsize = src->bioc->fs_info->sectorsize;
355354
const u32 sectors_per_page = PAGE_SIZE / sectorsize;
356-
int i;
357355

358356
if (dest->stripe_pages[page_nr])
359357
__free_page(dest->stripe_pages[page_nr]);
360358
dest->stripe_pages[page_nr] = src->stripe_pages[page_nr];
361359
src->stripe_pages[page_nr] = NULL;
362360

363-
/* Also update the sector->uptodate bits. */
364-
for (i = sectors_per_page * page_nr;
365-
i < sectors_per_page * page_nr + sectors_per_page; i++)
366-
dest->stripe_sectors[i].uptodate = true;
361+
/* Also update the stripe_uptodate_bitmap bits. */
362+
bitmap_set(dest->stripe_uptodate_bitmap, sectors_per_page * page_nr, sectors_per_page);
367363
}
368364

369365
static bool is_data_stripe_page(struct btrfs_raid_bio *rbio, int page_nr)
@@ -1031,9 +1027,10 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
10311027
GFP_NOFS);
10321028
rbio->finish_pointers = kcalloc(real_stripes, sizeof(void *), GFP_NOFS);
10331029
rbio->error_bitmap = bitmap_zalloc(num_sectors, GFP_NOFS);
1030+
rbio->stripe_uptodate_bitmap = bitmap_zalloc(num_sectors, GFP_NOFS);
10341031

10351032
if (!rbio->stripe_pages || !rbio->bio_sectors || !rbio->stripe_sectors ||
1036-
!rbio->finish_pointers || !rbio->error_bitmap) {
1033+
!rbio->finish_pointers || !rbio->error_bitmap || !rbio->stripe_uptodate_bitmap) {
10371034
free_raid_bio_pointers(rbio);
10381035
kfree(rbio);
10391036
return ERR_PTR(-ENOMEM);
@@ -1331,7 +1328,8 @@ static void generate_pq_vertical(struct btrfs_raid_bio *rbio, int sectornr)
13311328

13321329
/* Then add the parity stripe */
13331330
sector = rbio_pstripe_sector(rbio, sectornr);
1334-
sector->uptodate = 1;
1331+
set_bit(rbio_stripe_sector_index(rbio, rbio->nr_data, sectornr),
1332+
rbio->stripe_uptodate_bitmap);
13351333
pointers[stripe++] = kmap_local_sector(sector);
13361334

13371335
if (has_qstripe) {
@@ -1340,7 +1338,8 @@ static void generate_pq_vertical(struct btrfs_raid_bio *rbio, int sectornr)
13401338
* to fill in our p/q
13411339
*/
13421340
sector = rbio_qstripe_sector(rbio, sectornr);
1343-
sector->uptodate = 1;
1341+
set_bit(rbio_stripe_sector_index(rbio, rbio->nr_data + 1, sectornr),
1342+
rbio->stripe_uptodate_bitmap);
13441343
pointers[stripe++] = kmap_local_sector(sector);
13451344

13461345
assert_rbio(rbio);
@@ -1496,21 +1495,19 @@ static void set_rbio_range_error(struct btrfs_raid_bio *rbio, struct bio *bio)
14961495
}
14971496

14981497
/*
1499-
* For subpage case, we can no longer set page Up-to-date directly for
1500-
* stripe_pages[], thus we need to locate the sector.
1498+
* Return the index inside the rbio->stripe_sectors[] array.
1499+
*
1500+
* Return -1 if not found.
15011501
*/
1502-
static struct sector_ptr *find_stripe_sector(struct btrfs_raid_bio *rbio,
1503-
phys_addr_t paddr)
1502+
static int find_stripe_sector_nr(struct btrfs_raid_bio *rbio, phys_addr_t paddr)
15041503
{
1505-
int i;
1506-
1507-
for (i = 0; i < rbio->nr_sectors; i++) {
1504+
for (int i = 0; i < rbio->nr_sectors; i++) {
15081505
struct sector_ptr *sector = &rbio->stripe_sectors[i];
15091506

15101507
if (sector->paddr == paddr)
1511-
return sector;
1508+
return i;
15121509
}
1513-
return NULL;
1510+
return -1;
15141511
}
15151512

15161513
/*
@@ -1525,11 +1522,11 @@ static void set_bio_pages_uptodate(struct btrfs_raid_bio *rbio, struct bio *bio)
15251522
ASSERT(!bio_flagged(bio, BIO_CLONED));
15261523

15271524
btrfs_bio_for_each_block_all(paddr, bio, blocksize) {
1528-
struct sector_ptr *sector = find_stripe_sector(rbio, paddr);
1525+
int sector_nr = find_stripe_sector_nr(rbio, paddr);
15291526

1530-
ASSERT(sector);
1531-
if (sector)
1532-
sector->uptodate = 1;
1527+
ASSERT(sector_nr >= 0);
1528+
if (sector_nr >= 0)
1529+
set_bit(sector_nr, rbio->stripe_uptodate_bitmap);
15331530
}
15341531
}
15351532

@@ -1963,15 +1960,17 @@ static int recover_vertical(struct btrfs_raid_bio *rbio, int sector_nr,
19631960
goto cleanup;
19641961

19651962
sector = rbio_stripe_sector(rbio, faila, sector_nr);
1966-
sector->uptodate = 1;
1963+
set_bit(rbio_stripe_sector_index(rbio, faila, sector_nr),
1964+
rbio->stripe_uptodate_bitmap);
19671965
}
19681966
if (failb >= 0) {
19691967
ret = verify_one_sector(rbio, failb, sector_nr);
19701968
if (ret < 0)
19711969
goto cleanup;
19721970

19731971
sector = rbio_stripe_sector(rbio, failb, sector_nr);
1974-
sector->uptodate = 1;
1972+
set_bit(rbio_stripe_sector_index(rbio, failb, sector_nr),
1973+
rbio->stripe_uptodate_bitmap);
19751974
}
19761975

19771976
cleanup:
@@ -2325,7 +2324,8 @@ static bool need_read_stripe_sectors(struct btrfs_raid_bio *rbio)
23252324
* thus this rbio can not be cached one, as cached one must
23262325
* have all its data sectors present and uptodate.
23272326
*/
2328-
if (sector->paddr == INVALID_PADDR || !sector->uptodate)
2327+
if (sector->paddr == INVALID_PADDR ||
2328+
!test_bit(i, rbio->stripe_uptodate_bitmap))
23292329
return true;
23302330
}
23312331
return false;
@@ -2551,7 +2551,6 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
25512551
if (!page)
25522552
return -ENOMEM;
25532553
p_sector.paddr = page_to_phys(page);
2554-
p_sector.uptodate = 1;
25552554
page = NULL;
25562555

25572556
if (has_qstripe) {
@@ -2563,7 +2562,6 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
25632562
return -ENOMEM;
25642563
}
25652564
q_sector.paddr = page_to_phys(page);
2566-
q_sector.uptodate = 1;
25672565
page = NULL;
25682566
pointers[rbio->real_stripes - 1] = kmap_local_sector(&q_sector);
25692567
}
@@ -2781,7 +2779,8 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
27812779
* The bio cache may have handed us an uptodate sector. If so,
27822780
* use it.
27832781
*/
2784-
if (sector->uptodate)
2782+
if (test_bit(rbio_stripe_sector_index(rbio, stripe, sectornr),
2783+
rbio->stripe_uptodate_bitmap))
27852784
continue;
27862785

27872786
ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
@@ -2899,8 +2898,7 @@ void raid56_parity_cache_data_folios(struct btrfs_raid_bio *rbio,
28992898
foffset = 0;
29002899
}
29012900
}
2902-
for (unsigned int sector_nr = offset_in_full_stripe >> fs_info->sectorsize_bits;
2903-
sector_nr < (offset_in_full_stripe + BTRFS_STRIPE_LEN) >> fs_info->sectorsize_bits;
2904-
sector_nr++)
2905-
rbio->stripe_sectors[sector_nr].uptodate = true;
2901+
bitmap_set(rbio->stripe_uptodate_bitmap,
2902+
offset_in_full_stripe >> fs_info->sectorsize_bits,
2903+
BTRFS_STRIPE_LEN >> fs_info->sectorsize_bits);
29062904
}

fs/btrfs/raid56.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ struct btrfs_raid_bio {
124124
*/
125125
struct sector_ptr *stripe_sectors;
126126

127+
/* Each set bit means the corresponding sector in stripe_sectors[] is uptodate. */
128+
unsigned long *stripe_uptodate_bitmap;
129+
127130
/* Allocated with real_stripes-many pointers for finish_*() calls */
128131
void **finish_pointers;
129132

0 commit comments

Comments
 (0)