invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
}
+static u32 calc_block_max_order(u32 sectorsize_bits)
+{
+ u32 max_size;
+
+ max_size = min(BTRFS_MAX_BLOCKS_PER_FOLIO << sectorsize_bits,
+ BTRFS_MAX_FOLIO_SIZE);
+ return ilog2(round_up(max_size, PAGE_SIZE) >> PAGE_SHIFT);
+}
+
int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices)
{
u32 sectorsize;
fs_info->sectorsize = sectorsize;
fs_info->sectorsize_bits = ilog2(sectorsize);
fs_info->block_min_order = ilog2(round_up(sectorsize, PAGE_SIZE) >> PAGE_SHIFT);
- fs_info->block_max_order = ilog2((BITS_PER_LONG << fs_info->sectorsize_bits) >> PAGE_SHIFT);
+ fs_info->block_max_order = calc_block_max_order(fs_info->sectorsize_bits);
fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size;
fs_info->stripesize = stripesize;
fs_info->fs_devices->fs_info = fs_info;
* extent_writepage_io().
* This is to avoid touching ranges covered by compression/inline.
*/
- unsigned long *submit_bitmap;
- /*
- * When blocks_per_folio <= BITS_PER_LONG, we can use the inline
- * one without allocating memory.
- */
- unsigned long submit_bitmap_value;
+ unsigned long submit_bitmap[BITS_TO_LONGS(BTRFS_MAX_BLOCKS_PER_FOLIO)];
struct readahead_control *ractl;
const u64 page_start = folio_pos(folio);
const u64 page_end = page_start + folio_size(folio) - 1;
const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
- unsigned long delalloc_bitmap = 0;
+ unsigned long delalloc_bitmap[BITS_TO_LONGS(BTRFS_MAX_BLOCKS_PER_FOLIO)] = { 0 };
/*
* Save the last found delalloc end. As the delalloc end can go beyond
* page boundary, thus we cannot rely on subpage bitmap to locate the
delalloc_start = delalloc_end + 1;
continue;
}
- set_delalloc_bitmap(folio, &delalloc_bitmap, delalloc_start,
+ set_delalloc_bitmap(folio, delalloc_bitmap, delalloc_start,
min(delalloc_end, page_end) + 1 - delalloc_start);
last_delalloc_end = delalloc_end;
delalloc_start = delalloc_end + 1;
found_len = last_delalloc_end + 1 - found_start;
found = true;
} else {
- found = find_next_delalloc_bitmap(folio, &delalloc_bitmap,
+ found = find_next_delalloc_bitmap(folio, delalloc_bitmap,
delalloc_start, &found_start, &found_len);
}
if (!found)
{
const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
- /* Only supported for blocks per folio <= BITS_PER_LONG for now. */
- ASSERT(blocks_per_folio <= BITS_PER_LONG);
- bio_ctrl->submit_bitmap_value = 0;
- bio_ctrl->submit_bitmap = &bio_ctrl->submit_bitmap_value;
+ ASSERT(blocks_per_folio <= BTRFS_MAX_BLOCKS_PER_FOLIO);
+
/*
* Default to unlock the whole folio.
* The proper bitmap is not initialized until writepage_delalloc().
+ *
+ * We're safe just to set the bitmap range [0, blocks_per_folio), as
+ * all later usage of the bitmap will follow the same range limit.
+ * Any bits beyond blocks_per_folio will be ignored.
*/
bitmap_set(bio_ctrl->submit_bitmap, 0, blocks_per_folio);
}
#define BTRFS_MIN_BLOCKSIZE (SZ_4K)
#define BTRFS_MAX_BLOCKSIZE (SZ_64K)
+/* The maximum folio size btrfs supports. */
+#define BTRFS_MAX_FOLIO_SIZE (SZ_2M)
+static_assert(BTRFS_MAX_FOLIO_SIZE > PAGE_SIZE);
+
+/*
+ * The maximum number of blocks a huge folio can support.
+ *
+ * Depending on the filesystem block size, the real maximum blocks per folio
+ * may also be limited by the above BTRFS_MAX_FOLIO_SIZE.
+ */
+#ifdef CONFIG_BTRFS_EXPERIMENTAL
+#define BTRFS_MAX_BLOCKS_PER_FOLIO (512)
+#else
+#define BTRFS_MAX_BLOCKS_PER_FOLIO (BITS_PER_LONG)
+#endif
+
#define BTRFS_MAX_EXTENT_SIZE SZ_128M
/*
* - Metadata must be fully aligned to node size
* So when nodesize <= page size, the metadata can never cross folio boundaries.
*
- * - Only support blocks per folio <= BITS_PER_LONG
- * This is to make bitmap copying much easier, a single unsigned long can handle
- * one bitmap.
+ * - Only support blocks per folio <= min(BTRFS_MAX_FOLIO_SIZE / fs block size,
+ * BTRFS_MAX_BLOCKS_PER_FOLIO)
+ * This is to ensure we can afford an on-stack bitmap, without the need to allocate
+ * bitmap memory at runtime.
*
* Implementation:
*