Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

btrfs: subpage: remove btrfs_fs_info::subpage_info member

The member btrfs_fs_info::subpage_info stores the cached bitmap start
position inside the merged bitmap.

However in reality there is only one thing depending on the sectorsize,
bitmap_nr_bits, which records the number of sectors that fit inside a
page.

The sequence of sub-bitmaps have fixed order, thus it's just a quick
multiplication to calculate the start position of each sub-bitmaps.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by

Qu Wenruo and committed by
David Sterba
ce4a71ee 2c70fe16

+50 -110
+2 -12
fs/btrfs/disk-io.c
··· 1285 1285 btrfs_extent_buffer_leak_debug_check(fs_info); 1286 1286 kfree(fs_info->super_copy); 1287 1287 kfree(fs_info->super_for_commit); 1288 - kfree(fs_info->subpage_info); 1289 1288 kvfree(fs_info); 1290 1289 } 1291 1290 ··· 3321 3322 fs_info->nodesize = nodesize; 3322 3323 fs_info->sectorsize = sectorsize; 3323 3324 fs_info->sectorsize_bits = ilog2(sectorsize); 3325 + fs_info->sectors_per_page = (PAGE_SIZE >> fs_info->sectorsize_bits); 3324 3326 fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size; 3325 3327 fs_info->stripesize = stripesize; 3326 3328 ··· 3346 3346 */ 3347 3347 fs_info->max_inline = min_t(u64, fs_info->max_inline, fs_info->sectorsize); 3348 3348 3349 - if (sectorsize < PAGE_SIZE) { 3350 - struct btrfs_subpage_info *subpage_info; 3351 - 3349 + if (sectorsize < PAGE_SIZE) 3352 3350 btrfs_warn(fs_info, 3353 3351 "read-write for sector size %u with page size %lu is experimental", 3354 3352 sectorsize, PAGE_SIZE); 3355 - subpage_info = kzalloc(sizeof(*subpage_info), GFP_KERNEL); 3356 - if (!subpage_info) { 3357 - ret = -ENOMEM; 3358 - goto fail_alloc; 3359 - } 3360 - btrfs_init_subpage_info(subpage_info, sectorsize); 3361 - fs_info->subpage_info = subpage_info; 3362 - } 3363 3353 3364 3354 ret = btrfs_init_workqueues(fs_info); 3365 3355 if (ret)
+4 -4
fs/btrfs/extent_io.c
··· 1440 1440 } 1441 1441 1442 1442 if (btrfs_is_subpage(fs_info, inode->vfs_inode.i_mapping)) { 1443 - ASSERT(fs_info->subpage_info); 1443 + ASSERT(fs_info->sectors_per_page > 1); 1444 1444 btrfs_get_subpage_dirty_bitmap(fs_info, folio, &dirty_bitmap); 1445 - bitmap_size = fs_info->subpage_info->bitmap_nr_bits; 1445 + bitmap_size = fs_info->sectors_per_page; 1446 1446 } 1447 1447 for (cur = start; cur < start + len; cur += fs_info->sectorsize) 1448 1448 set_bit((cur - folio_start) >> fs_info->sectorsize_bits, &range_bitmap); ··· 1827 1827 int sectors_per_node = fs_info->nodesize >> fs_info->sectorsize_bits; 1828 1828 1829 1829 /* Lock and write each dirty extent buffers in the range */ 1830 - while (bit_start < fs_info->subpage_info->bitmap_nr_bits) { 1830 + while (bit_start < fs_info->sectors_per_page) { 1831 1831 struct btrfs_subpage *subpage = folio_get_private(folio); 1832 1832 struct extent_buffer *eb; 1833 1833 unsigned long flags; ··· 1843 1843 break; 1844 1844 } 1845 1845 spin_lock_irqsave(&subpage->lock, flags); 1846 - if (!test_bit(bit_start + fs_info->subpage_info->dirty_offset, 1846 + if (!test_bit(bit_start + btrfs_bitmap_nr_dirty * fs_info->sectors_per_page, 1847 1847 subpage->bitmaps)) { 1848 1848 spin_unlock_irqrestore(&subpage->lock, flags); 1849 1849 spin_unlock(&page->mapping->i_private_lock);
+1 -1
fs/btrfs/fs.h
··· 703 703 * running. 704 704 */ 705 705 refcount_t scrub_workers_refcnt; 706 + u32 sectors_per_page; 706 707 struct workqueue_struct *scrub_workers; 707 - struct btrfs_subpage_info *subpage_info; 708 708 709 709 struct btrfs_discard_ctl discard_ctl; 710 710
+30 -63
fs/btrfs/subpage.c
··· 88 88 } 89 89 #endif 90 90 91 - void btrfs_init_subpage_info(struct btrfs_subpage_info *subpage_info, u32 sectorsize) 92 - { 93 - unsigned int cur = 0; 94 - unsigned int nr_bits; 95 - 96 - ASSERT(IS_ALIGNED(PAGE_SIZE, sectorsize)); 97 - 98 - nr_bits = PAGE_SIZE / sectorsize; 99 - subpage_info->bitmap_nr_bits = nr_bits; 100 - 101 - subpage_info->uptodate_offset = cur; 102 - cur += nr_bits; 103 - 104 - subpage_info->dirty_offset = cur; 105 - cur += nr_bits; 106 - 107 - subpage_info->writeback_offset = cur; 108 - cur += nr_bits; 109 - 110 - subpage_info->ordered_offset = cur; 111 - cur += nr_bits; 112 - 113 - subpage_info->checked_offset = cur; 114 - cur += nr_bits; 115 - 116 - subpage_info->locked_offset = cur; 117 - cur += nr_bits; 118 - 119 - subpage_info->total_nr_bits = cur; 120 - } 121 - 122 91 int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info, 123 92 struct folio *folio, enum btrfs_subpage_type type) 124 93 { ··· 134 165 ASSERT(fs_info->sectorsize < PAGE_SIZE); 135 166 136 167 real_size = struct_size(ret, bitmaps, 137 - BITS_TO_LONGS(fs_info->subpage_info->total_nr_bits)); 168 + BITS_TO_LONGS(btrfs_bitmap_nr_max * fs_info->sectors_per_page)); 138 169 ret = kzalloc(real_size, GFP_NOFS); 139 170 if (!ret) 140 171 return ERR_PTR(-ENOMEM); ··· 217 248 \ 218 249 btrfs_subpage_assert(fs_info, folio, start, len); \ 219 250 __start_bit = offset_in_page(start) >> fs_info->sectorsize_bits; \ 220 - __start_bit += fs_info->subpage_info->name##_offset; \ 251 + __start_bit += fs_info->sectors_per_page * btrfs_bitmap_nr_##name; \ 221 252 __start_bit; \ 222 253 }) 223 254 ··· 389 420 390 421 #define subpage_test_bitmap_all_set(fs_info, subpage, name) \ 391 422 bitmap_test_range_all_set(subpage->bitmaps, \ 392 - fs_info->subpage_info->name##_offset, \ 393 - fs_info->subpage_info->bitmap_nr_bits) 423 + fs_info->sectors_per_page * btrfs_bitmap_nr_##name, \ 424 + fs_info->sectors_per_page) 394 425 395 426 #define subpage_test_bitmap_all_zero(fs_info, subpage, name) \ 396 427 bitmap_test_range_all_zero(subpage->bitmaps, \ 397 - fs_info->subpage_info->name##_offset, \ 398 - fs_info->subpage_info->bitmap_nr_bits) 428 + fs_info->sectors_per_page * btrfs_bitmap_nr_##name, \ 429 + fs_info->sectors_per_page) 399 430 400 431 void btrfs_subpage_set_uptodate(const struct btrfs_fs_info *fs_info, 401 432 struct folio *folio, u64 start, u32 len) ··· 774 805 ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits)); 775 806 bitmap_set(subpage->bitmaps, start_bit, nbits); 776 807 ret = atomic_add_return(nbits, &subpage->writers); 777 - ASSERT(ret <= fs_info->subpage_info->bitmap_nr_bits); 808 + ASSERT(ret <= fs_info->sectors_per_page); 778 809 spin_unlock_irqrestore(&subpage->lock, flags); 779 810 } 780 811 ··· 790 821 struct folio *folio, u64 search_start, 791 822 u64 *found_start_ret, u32 *found_len_ret) 792 823 { 793 - struct btrfs_subpage_info *subpage_info = fs_info->subpage_info; 794 824 struct btrfs_subpage *subpage = folio_get_private(folio); 825 + const u32 sectors_per_page = fs_info->sectors_per_page; 795 826 const unsigned int len = PAGE_SIZE - offset_in_page(search_start); 796 827 const unsigned int start_bit = subpage_calc_start_bit(fs_info, folio, 797 828 locked, search_start, len); 798 - const unsigned int locked_bitmap_start = subpage_info->locked_offset; 799 - const unsigned int locked_bitmap_end = locked_bitmap_start + 800 - subpage_info->bitmap_nr_bits; 829 + const unsigned int locked_bitmap_start = sectors_per_page * btrfs_bitmap_nr_locked; 830 + const unsigned int locked_bitmap_end = locked_bitmap_start + sectors_per_page; 801 831 unsigned long flags; 802 832 int first_zero; 803 833 int first_set; ··· 869 901 } 870 902 } 871 903 872 - #define GET_SUBPAGE_BITMAP(subpage, subpage_info, name, dst) \ 904 + #define GET_SUBPAGE_BITMAP(subpage, fs_info, name, dst) \ 873 905 { \ 874 - const int bitmap_nr_bits = subpage_info->bitmap_nr_bits; \ 906 + const int sectors_per_page = fs_info->sectors_per_page; \ 875 907 \ 876 - ASSERT(bitmap_nr_bits < BITS_PER_LONG); \ 908 + ASSERT(sectors_per_page < BITS_PER_LONG); \ 877 909 *dst = bitmap_read(subpage->bitmaps, \ 878 - subpage_info->name##_offset, \ 879 - bitmap_nr_bits); \ 910 + sectors_per_page * btrfs_bitmap_nr_##name, \ 911 + sectors_per_page); \ 880 912 } 881 913 882 914 void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info, 883 915 struct folio *folio, u64 start, u32 len) 884 916 { 885 - struct btrfs_subpage_info *subpage_info = fs_info->subpage_info; 886 917 struct btrfs_subpage *subpage; 918 + const u32 sectors_per_page = fs_info->sectors_per_page; 887 919 unsigned long uptodate_bitmap; 888 920 unsigned long dirty_bitmap; 889 921 unsigned long writeback_bitmap; ··· 892 924 unsigned long flags; 893 925 894 926 ASSERT(folio_test_private(folio) && folio_get_private(folio)); 895 - ASSERT(subpage_info); 927 + ASSERT(sectors_per_page > 1); 896 928 subpage = folio_get_private(folio); 897 929 898 930 spin_lock_irqsave(&subpage->lock, flags); 899 - GET_SUBPAGE_BITMAP(subpage, subpage_info, uptodate, &uptodate_bitmap); 900 - GET_SUBPAGE_BITMAP(subpage, subpage_info, dirty, &dirty_bitmap); 901 - GET_SUBPAGE_BITMAP(subpage, subpage_info, writeback, &writeback_bitmap); 902 - GET_SUBPAGE_BITMAP(subpage, subpage_info, ordered, &ordered_bitmap); 903 - GET_SUBPAGE_BITMAP(subpage, subpage_info, checked, &checked_bitmap); 904 - GET_SUBPAGE_BITMAP(subpage, subpage_info, locked, &checked_bitmap); 931 + GET_SUBPAGE_BITMAP(subpage, fs_info, uptodate, &uptodate_bitmap); 932 + GET_SUBPAGE_BITMAP(subpage, fs_info, dirty, &dirty_bitmap); 933 + GET_SUBPAGE_BITMAP(subpage, fs_info, writeback, &writeback_bitmap); 934 + GET_SUBPAGE_BITMAP(subpage, fs_info, ordered, &ordered_bitmap); 935 + GET_SUBPAGE_BITMAP(subpage, fs_info, checked, &checked_bitmap); 936 + GET_SUBPAGE_BITMAP(subpage, fs_info, locked, &checked_bitmap); 905 937 spin_unlock_irqrestore(&subpage->lock, flags); 906 938 907 939 dump_page(folio_page(folio, 0), "btrfs subpage dump"); 908 940 btrfs_warn(fs_info, 909 941 "start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl writeback=%*pbl ordered=%*pbl checked=%*pbl", 910 942 start, len, folio_pos(folio), 911 - subpage_info->bitmap_nr_bits, &uptodate_bitmap, 912 - subpage_info->bitmap_nr_bits, &dirty_bitmap, 913 - subpage_info->bitmap_nr_bits, &writeback_bitmap, 914 - subpage_info->bitmap_nr_bits, &ordered_bitmap, 915 - subpage_info->bitmap_nr_bits, &checked_bitmap); 943 + sectors_per_page, &uptodate_bitmap, 944 + sectors_per_page, &dirty_bitmap, 945 + sectors_per_page, &writeback_bitmap, 946 + sectors_per_page, &ordered_bitmap, 947 + sectors_per_page, &checked_bitmap); 916 948 } 917 949 918 950 void btrfs_get_subpage_dirty_bitmap(struct btrfs_fs_info *fs_info, 919 951 struct folio *folio, 920 952 unsigned long *ret_bitmap) 921 953 { 922 - struct btrfs_subpage_info *subpage_info = fs_info->subpage_info; 923 954 struct btrfs_subpage *subpage; 924 955 unsigned long flags; 925 956 926 957 ASSERT(folio_test_private(folio) && folio_get_private(folio)); 927 - ASSERT(subpage_info); 958 + ASSERT(fs_info->sectors_per_page > 1); 928 959 subpage = folio_get_private(folio); 929 960 930 961 spin_lock_irqsave(&subpage->lock, flags); 931 - GET_SUBPAGE_BITMAP(subpage, subpage_info, dirty, ret_bitmap); 962 + GET_SUBPAGE_BITMAP(subpage, fs_info, dirty, ret_bitmap); 932 963 spin_unlock_irqrestore(&subpage->lock, flags); 933 964 }
+13 -30
fs/btrfs/subpage.h
··· 19 19 * 20 20 * This structure records how they are organized in the bitmap: 21 21 * 22 - * /- uptodate_offset /- dirty_offset /- ordered_offset 22 + * /- uptodate /- dirty /- ordered 23 23 * | | | 24 24 * v v v 25 25 * |u|u|u|u|........|u|u|d|d|.......|d|d|o|o|.......|o|o| 26 - * |<- bitmap_nr_bits ->| 27 - * |<----------------- total_nr_bits ------------------>| 26 + * |< sectors_per_page >| 27 + * 28 + * Unlike regular macro-like enums, here we do not go upper-case names, as 29 + * these names will be utilized in various macros to define function names. 28 30 */ 29 - struct btrfs_subpage_info { 30 - /* Number of bits for each bitmap */ 31 - unsigned int bitmap_nr_bits; 32 - 33 - /* Total number of bits for the whole bitmap */ 34 - unsigned int total_nr_bits; 35 - 36 - /* 37 - * *_offset indicates where the bitmap starts, the length is always 38 - * @bitmap_size, which is calculated from PAGE_SIZE / sectorsize. 39 - */ 40 - unsigned int uptodate_offset; 41 - unsigned int dirty_offset; 42 - unsigned int writeback_offset; 43 - unsigned int ordered_offset; 44 - unsigned int checked_offset; 45 - 46 - /* 47 - * For locked bitmaps, normally it's subpage representation for folio 48 - * Locked flag, but metadata is different: 49 - * 50 - * - Metadata doesn't really lock the folio 51 - * It's just to prevent page::private get cleared before the last 52 - * end_page_read(). 53 - */ 54 - unsigned int locked_offset; 31 + enum { 32 + btrfs_bitmap_nr_uptodate = 0, 33 + btrfs_bitmap_nr_dirty, 34 + btrfs_bitmap_nr_writeback, 35 + btrfs_bitmap_nr_ordered, 36 + btrfs_bitmap_nr_checked, 37 + btrfs_bitmap_nr_locked, 38 + btrfs_bitmap_nr_max 55 39 }; 56 40 57 41 /* ··· 83 99 } 84 100 #endif 85 101 86 - void btrfs_init_subpage_info(struct btrfs_subpage_info *subpage_info, u32 sectorsize); 87 102 int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info, 88 103 struct folio *folio, enum btrfs_subpage_type type); 89 104 void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, struct folio *folio);