Skip to content

Commit 5931c3d

Browse files
adam900710kdave
authored andcommitted
btrfs: raid56: remove sector_ptr::has_paddr member
We can use paddr -1 as an indicator for unset/uninitialized paddr. We can not use 0 paddr, unlike virtual address 0 which is never mapped thus will always trigger a page fault, physical address 0 may be a valid page. So here we follow swiotlb to use (paddr)-1 as a special indicator for invalid/unset physical address. Even if the PFN may still be valid, our usage of the physical address should always be aligned to fs block size (or page size for bs > ps cases), thus such -1 paddr should never be a valid one. With this special -1 paddr, we can get rid of has_paddr member and save 1 byte for sector_ptr structure. 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 f69241d commit 5931c3d

File tree

1 file changed

+26
-20
lines changed

1 file changed

+26
-20
lines changed

fs/btrfs/raid56.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ struct btrfs_stripe_hash_table {
133133
struct btrfs_stripe_hash table[];
134134
};
135135

136+
/*
137+
* The PFN may still be valid, but our paddrs should always be block size
138+
* aligned, thus such -1 paddr is definitely not a valid one.
139+
*/
140+
#define INVALID_PADDR (~(phys_addr_t)0)
141+
136142
/*
137143
* A structure to present a sector inside a page, the length is fixed to
138144
* sectorsize;
@@ -141,9 +147,10 @@ struct sector_ptr {
141147
/*
142148
* Blocks from the bio list can still be highmem.
143149
* So here we use physical address to present a page and the offset inside it.
150+
*
151+
* If it's INVALID_PADDR then it's not set.
144152
*/
145153
phys_addr_t paddr;
146-
bool has_paddr;
147154
bool uptodate;
148155
};
149156

@@ -263,7 +270,7 @@ static void cache_rbio_pages(struct btrfs_raid_bio *rbio)
263270

264271
for (i = 0; i < rbio->nr_sectors; i++) {
265272
/* Some range not covered by bio (partial write), skip it */
266-
if (!rbio->bio_sectors[i].has_paddr) {
273+
if (rbio->bio_sectors[i].paddr == INVALID_PADDR) {
267274
/*
268275
* Even if the sector is not covered by bio, if it is
269276
* a data sector it should still be uptodate as it is
@@ -335,7 +342,6 @@ static void index_stripe_sectors(struct btrfs_raid_bio *rbio)
335342
if (!rbio->stripe_pages[page_index])
336343
continue;
337344

338-
rbio->stripe_sectors[i].has_paddr = true;
339345
rbio->stripe_sectors[i].paddr =
340346
page_to_phys(rbio->stripe_pages[page_index]) +
341347
offset_in_page(offset);
@@ -972,9 +978,9 @@ static struct sector_ptr *sector_in_rbio(struct btrfs_raid_bio *rbio,
972978

973979
spin_lock(&rbio->bio_list_lock);
974980
sector = &rbio->bio_sectors[index];
975-
if (sector->has_paddr || bio_list_only) {
981+
if (sector->paddr != INVALID_PADDR || bio_list_only) {
976982
/* Don't return sector without a valid page pointer */
977-
if (!sector->has_paddr)
983+
if (sector->paddr == INVALID_PADDR)
978984
sector = NULL;
979985
spin_unlock(&rbio->bio_list_lock);
980986
return sector;
@@ -1032,6 +1038,10 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
10321038
kfree(rbio);
10331039
return ERR_PTR(-ENOMEM);
10341040
}
1041+
for (int i = 0; i < num_sectors; i++) {
1042+
rbio->stripe_sectors[i].paddr = INVALID_PADDR;
1043+
rbio->bio_sectors[i].paddr = INVALID_PADDR;
1044+
}
10351045

10361046
bio_list_init(&rbio->bio_list);
10371047
init_waitqueue_head(&rbio->io_wait);
@@ -1152,7 +1162,7 @@ static int rbio_add_io_sector(struct btrfs_raid_bio *rbio,
11521162
rbio, stripe_nr);
11531163
ASSERT_RBIO_SECTOR(sector_nr >= 0 && sector_nr < rbio->stripe_nsectors,
11541164
rbio, sector_nr);
1155-
ASSERT(sector->has_paddr);
1165+
ASSERT(sector->paddr != INVALID_PADDR);
11561166

11571167
stripe = &rbio->bioc->stripes[stripe_nr];
11581168
disk_start = stripe->physical + sector_nr * sectorsize;
@@ -1216,7 +1226,6 @@ static void index_one_bio(struct btrfs_raid_bio *rbio, struct bio *bio)
12161226
unsigned int index = (offset >> sectorsize_bits);
12171227
struct sector_ptr *sector = &rbio->bio_sectors[index];
12181228

1219-
sector->has_paddr = true;
12201229
sector->paddr = paddr;
12211230
offset += sectorsize;
12221231
}
@@ -1299,7 +1308,7 @@ static void assert_rbio(struct btrfs_raid_bio *rbio)
12991308
static inline void *kmap_local_sector(const struct sector_ptr *sector)
13001309
{
13011310
/* The sector pointer must have a page mapped to it. */
1302-
ASSERT(sector->has_paddr);
1311+
ASSERT(sector->paddr != INVALID_PADDR);
13031312

13041313
return kmap_local_page(phys_to_page(sector->paddr)) +
13051314
offset_in_page(sector->paddr);
@@ -1498,7 +1507,7 @@ static struct sector_ptr *find_stripe_sector(struct btrfs_raid_bio *rbio,
14981507
for (i = 0; i < rbio->nr_sectors; i++) {
14991508
struct sector_ptr *sector = &rbio->stripe_sectors[i];
15001509

1501-
if (sector->has_paddr && sector->paddr == paddr)
1510+
if (sector->paddr == paddr)
15021511
return sector;
15031512
}
15041513
return NULL;
@@ -1532,8 +1541,7 @@ static int get_bio_sector_nr(struct btrfs_raid_bio *rbio, struct bio *bio)
15321541
for (i = 0; i < rbio->nr_sectors; i++) {
15331542
if (rbio->stripe_sectors[i].paddr == bvec_paddr)
15341543
break;
1535-
if (rbio->bio_sectors[i].has_paddr &&
1536-
rbio->bio_sectors[i].paddr == bvec_paddr)
1544+
if (rbio->bio_sectors[i].paddr == bvec_paddr)
15371545
break;
15381546
}
15391547
ASSERT(i < rbio->nr_sectors);
@@ -2317,7 +2325,7 @@ static bool need_read_stripe_sectors(struct btrfs_raid_bio *rbio)
23172325
* thus this rbio can not be cached one, as cached one must
23182326
* have all its data sectors present and uptodate.
23192327
*/
2320-
if (!sector->has_paddr || !sector->uptodate)
2328+
if (sector->paddr == INVALID_PADDR || !sector->uptodate)
23212329
return true;
23222330
}
23232331
return false;
@@ -2508,8 +2516,8 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
25082516
int sectornr;
25092517
bool has_qstripe;
25102518
struct page *page;
2511-
struct sector_ptr p_sector = { 0 };
2512-
struct sector_ptr q_sector = { 0 };
2519+
struct sector_ptr p_sector = { .paddr = INVALID_PADDR };
2520+
struct sector_ptr q_sector = { .paddr = INVALID_PADDR };
25132521
struct bio_list bio_list;
25142522
int is_replace = 0;
25152523
int ret;
@@ -2542,7 +2550,6 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
25422550
page = alloc_page(GFP_NOFS);
25432551
if (!page)
25442552
return -ENOMEM;
2545-
p_sector.has_paddr = true;
25462553
p_sector.paddr = page_to_phys(page);
25472554
p_sector.uptodate = 1;
25482555
page = NULL;
@@ -2552,10 +2559,9 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
25522559
page = alloc_page(GFP_NOFS);
25532560
if (!page) {
25542561
__free_page(phys_to_page(p_sector.paddr));
2555-
p_sector.has_paddr = false;
2562+
p_sector.paddr = INVALID_PADDR;
25562563
return -ENOMEM;
25572564
}
2558-
q_sector.has_paddr = true;
25592565
q_sector.paddr = page_to_phys(page);
25602566
q_sector.uptodate = 1;
25612567
page = NULL;
@@ -2604,10 +2610,10 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
26042610

26052611
kunmap_local(pointers[nr_data]);
26062612
__free_page(phys_to_page(p_sector.paddr));
2607-
p_sector.has_paddr = false;
2608-
if (q_sector.has_paddr) {
2613+
p_sector.paddr = INVALID_PADDR;
2614+
if (q_sector.paddr != INVALID_PADDR) {
26092615
__free_page(phys_to_page(q_sector.paddr));
2610-
q_sector.has_paddr = false;
2616+
q_sector.paddr = INVALID_PADDR;
26112617
}
26122618

26132619
/*

0 commit comments

Comments
 (0)