Skip to content

Commit d048b9c

Browse files
weiny2torvalds
authored andcommitted
btrfs: use memzero_page() instead of open coded kmap pattern
There are many places where kmap/memset/kunmap patterns occur. Use the newly lifted memzero_page() to eliminate direct uses of kmap and leverage the new core functions use of kmap_local_page(). The development of this patch was aided by the following coccinelle script: // <smpl> // SPDX-License-Identifier: GPL-2.0-only // Find kmap/memset/kunmap pattern and replace with memset*page calls // // NOTE: Offsets and other expressions may be more complex than what the script // will automatically generate. Therefore a catchall rule is provided to find // the pattern which then must be evaluated by hand. // // Confidence: Low // Copyright: (C) 2021 Intel Corporation // URL: http://coccinelle.lip6.fr/ // Comments: // Options: // // Then the memset pattern // @ memset_rule1 @ expression page, V, L, Off; identifier ptr; type VP; @@ ( -VP ptr = kmap(page); | -ptr = kmap(page); | -VP ptr = kmap_atomic(page); | -ptr = kmap_atomic(page); ) <+... ( -memset(ptr, 0, L); +memzero_page(page, 0, L); | -memset(ptr + Off, 0, L); +memzero_page(page, Off, L); | -memset(ptr, V, L); +memset_page(page, V, 0, L); | -memset(ptr + Off, V, L); +memset_page(page, V, Off, L); ) ...+> ( -kunmap(page); | -kunmap_atomic(ptr); ) // Remove any pointers left unused @ depends on memset_rule1 @ identifier memset_rule1.ptr; type VP, VP1; @@ -VP ptr; ... when != ptr; ? VP1 ptr; // // Catch all // @ memset_rule2 @ expression page; identifier ptr; expression GenTo, GenSize, GenValue; type VP; @@ ( -VP ptr = kmap(page); | -ptr = kmap(page); | -VP ptr = kmap_atomic(page); | -ptr = kmap_atomic(page); ) <+... ( // // Some call sites have complex expressions within the memset/memcpy // The follow are catch alls which need to be evaluated by hand. // -memset(GenTo, 0, GenSize); +memzero_pageExtra(page, GenTo, GenSize); | -memset(GenTo, GenValue, GenSize); +memset_pageExtra(page, GenValue, GenTo, GenSize); ) ...+> ( -kunmap(page); | -kunmap_atomic(ptr); ) // Remove any pointers left unused @ depends on memset_rule2 @ identifier memset_rule2.ptr; type VP, VP1; @@ -VP ptr; ... when != ptr; ? VP1 ptr; // </smpl> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ira Weiny <[email protected]> Reviewed-by: David Sterba <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Chaitanya Kulkarni <[email protected]> Cc: Chris Mason <[email protected]> Cc: Josef Bacik <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 2896199 commit d048b9c

File tree

6 files changed

+18
-58
lines changed

6 files changed

+18
-58
lines changed

fs/btrfs/compression.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,16 +591,13 @@ static noinline int add_ra_bio_pages(struct inode *inode,
591591
free_extent_map(em);
592592

593593
if (page->index == end_index) {
594-
char *userpage;
595594
size_t zero_offset = offset_in_page(isize);
596595

597596
if (zero_offset) {
598597
int zeros;
599598
zeros = PAGE_SIZE - zero_offset;
600-
userpage = kmap_atomic(page);
601-
memset(userpage + zero_offset, 0, zeros);
599+
memzero_page(page, zero_offset, zeros);
602600
flush_dcache_page(page);
603-
kunmap_atomic(userpage);
604601
}
605602
}
606603

fs/btrfs/extent_io.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3421,15 +3421,12 @@ int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
34213421
}
34223422

34233423
if (page->index == last_byte >> PAGE_SHIFT) {
3424-
char *userpage;
34253424
size_t zero_offset = offset_in_page(last_byte);
34263425

34273426
if (zero_offset) {
34283427
iosize = PAGE_SIZE - zero_offset;
3429-
userpage = kmap_atomic(page);
3430-
memset(userpage + zero_offset, 0, iosize);
3428+
memzero_page(page, zero_offset, iosize);
34313429
flush_dcache_page(page);
3432-
kunmap_atomic(userpage);
34333430
}
34343431
}
34353432
begin_page_read(fs_info, page);
@@ -3438,14 +3435,11 @@ int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
34383435
u64 disk_bytenr;
34393436

34403437
if (cur >= last_byte) {
3441-
char *userpage;
34423438
struct extent_state *cached = NULL;
34433439

34443440
iosize = PAGE_SIZE - pg_offset;
3445-
userpage = kmap_atomic(page);
3446-
memset(userpage + pg_offset, 0, iosize);
3441+
memzero_page(page, pg_offset, iosize);
34473442
flush_dcache_page(page);
3448-
kunmap_atomic(userpage);
34493443
set_extent_uptodate(tree, cur, cur + iosize - 1,
34503444
&cached, GFP_NOFS);
34513445
unlock_extent_cached(tree, cur,
@@ -3528,13 +3522,10 @@ int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
35283522

35293523
/* we've found a hole, just zero and go on */
35303524
if (block_start == EXTENT_MAP_HOLE) {
3531-
char *userpage;
35323525
struct extent_state *cached = NULL;
35333526

3534-
userpage = kmap_atomic(page);
3535-
memset(userpage + pg_offset, 0, iosize);
3527+
memzero_page(page, pg_offset, iosize);
35363528
flush_dcache_page(page);
3537-
kunmap_atomic(userpage);
35383529

35393530
set_extent_uptodate(tree, cur, cur + iosize - 1,
35403531
&cached, GFP_NOFS);
@@ -3845,12 +3836,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
38453836
}
38463837

38473838
if (page->index == end_index) {
3848-
char *userpage;
3849-
3850-
userpage = kmap_atomic(page);
3851-
memset(userpage + pg_offset, 0,
3852-
PAGE_SIZE - pg_offset);
3853-
kunmap_atomic(userpage);
3839+
memzero_page(page, pg_offset, PAGE_SIZE - pg_offset);
38543840
flush_dcache_page(page);
38553841
}
38563842

fs/btrfs/inode.c

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -646,17 +646,12 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
646646
if (!ret) {
647647
unsigned long offset = offset_in_page(total_compressed);
648648
struct page *page = pages[nr_pages - 1];
649-
char *kaddr;
650649

651650
/* zero the tail end of the last page, we might be
652651
* sending it down to disk
653652
*/
654-
if (offset) {
655-
kaddr = kmap_atomic(page);
656-
memset(kaddr + offset, 0,
657-
PAGE_SIZE - offset);
658-
kunmap_atomic(kaddr);
659-
}
653+
if (offset)
654+
memzero_page(page, offset, PAGE_SIZE - offset);
660655
will_compress = 1;
661656
}
662657
}
@@ -4833,7 +4828,6 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len,
48334828
struct btrfs_ordered_extent *ordered;
48344829
struct extent_state *cached_state = NULL;
48354830
struct extent_changeset *data_reserved = NULL;
4836-
char *kaddr;
48374831
bool only_release_metadata = false;
48384832
u32 blocksize = fs_info->sectorsize;
48394833
pgoff_t index = from >> PAGE_SHIFT;
@@ -4925,15 +4919,13 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len,
49254919
if (offset != blocksize) {
49264920
if (!len)
49274921
len = blocksize - offset;
4928-
kaddr = kmap(page);
49294922
if (front)
4930-
memset(kaddr + (block_start - page_offset(page)),
4931-
0, offset);
4923+
memzero_page(page, (block_start - page_offset(page)),
4924+
offset);
49324925
else
4933-
memset(kaddr + (block_start - page_offset(page)) + offset,
4934-
0, len);
4926+
memzero_page(page, (block_start - page_offset(page)) + offset,
4927+
len);
49354928
flush_dcache_page(page);
4936-
kunmap(page);
49374929
}
49384930
ClearPageChecked(page);
49394931
set_page_dirty(page);
@@ -6832,11 +6824,9 @@ static noinline int uncompress_inline(struct btrfs_path *path,
68326824
* cover that region here.
68336825
*/
68346826

6835-
if (max_size + pg_offset < PAGE_SIZE) {
6836-
char *map = kmap(page);
6837-
memset(map + pg_offset + max_size, 0, PAGE_SIZE - max_size - pg_offset);
6838-
kunmap(page);
6839-
}
6827+
if (max_size + pg_offset < PAGE_SIZE)
6828+
memzero_page(page, pg_offset + max_size,
6829+
PAGE_SIZE - max_size - pg_offset);
68406830
kfree(tmp);
68416831
return ret;
68426832
}
@@ -8506,7 +8496,6 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
85068496
struct btrfs_ordered_extent *ordered;
85078497
struct extent_state *cached_state = NULL;
85088498
struct extent_changeset *data_reserved = NULL;
8509-
char *kaddr;
85108499
unsigned long zero_start;
85118500
loff_t size;
85128501
vm_fault_t ret;
@@ -8620,10 +8609,8 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
86208609
zero_start = PAGE_SIZE;
86218610

86228611
if (zero_start != PAGE_SIZE) {
8623-
kaddr = kmap(page);
8624-
memset(kaddr + zero_start, 0, PAGE_SIZE - zero_start);
8612+
memzero_page(page, zero_start, PAGE_SIZE - zero_start);
86258613
flush_dcache_page(page);
8626-
kunmap(page);
86278614
}
86288615
ClearPageChecked(page);
86298616
set_page_dirty(page);

fs/btrfs/reflink.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,8 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
129129
* So what's in the range [500, 4095] corresponds to zeroes.
130130
*/
131131
if (datal < block_size) {
132-
char *map;
133-
134-
map = kmap(page);
135-
memset(map + datal, 0, block_size - datal);
132+
memzero_page(page, datal, block_size - datal);
136133
flush_dcache_page(page);
137-
kunmap(page);
138134
}
139135

140136
SetPageUptodate(page);

fs/btrfs/zlib.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ int zlib_decompress(struct list_head *ws, unsigned char *data_in,
375375
unsigned long bytes_left;
376376
unsigned long total_out = 0;
377377
unsigned long pg_offset = 0;
378-
char *kaddr;
379378

380379
destlen = min_t(unsigned long, destlen, PAGE_SIZE);
381380
bytes_left = destlen;
@@ -455,9 +454,7 @@ int zlib_decompress(struct list_head *ws, unsigned char *data_in,
455454
* end of the inline extent (destlen) to the end of the page
456455
*/
457456
if (pg_offset < destlen) {
458-
kaddr = kmap_atomic(dest_page);
459-
memset(kaddr + pg_offset, 0, destlen - pg_offset);
460-
kunmap_atomic(kaddr);
457+
memzero_page(dest_page, pg_offset, destlen - pg_offset);
461458
}
462459
return ret;
463460
}

fs/btrfs/zstd.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,6 @@ int zstd_decompress(struct list_head *ws, unsigned char *data_in,
631631
size_t ret2;
632632
unsigned long total_out = 0;
633633
unsigned long pg_offset = 0;
634-
char *kaddr;
635634

636635
stream = ZSTD_initDStream(
637636
ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size);
@@ -696,9 +695,7 @@ int zstd_decompress(struct list_head *ws, unsigned char *data_in,
696695
ret = 0;
697696
finish:
698697
if (pg_offset < destlen) {
699-
kaddr = kmap_atomic(dest_page);
700-
memset(kaddr + pg_offset, 0, destlen - pg_offset);
701-
kunmap_atomic(kaddr);
698+
memzero_page(dest_page, pg_offset, destlen - pg_offset);
702699
}
703700
return ret;
704701
}

0 commit comments

Comments
 (0)