fs/btrfs/subpage.c
Source file repositories/reference/linux-study-clean/fs/btrfs/subpage.c
File Facts
- System
- Linux kernel
- Corpus path
fs/btrfs/subpage.c- Extension
.c- Size
- 24949 bytes
- Lines
- 767
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hmessages.hsubpage.hbtrfs_inode.h
Detected Declarations
function Subpagefunction btrfs_detach_folio_statefunction detach_extent_buffer_pagefunction btrfs_folio_dec_eb_refsfunction btrfs_subpage_assertfunction btrfs_subpage_clamp_rangefunction btrfs_subpage_end_and_test_lockfunction extent_clear_unlock_delallocfunction writepage_delallocfunction btrfs_folio_end_lock_bitmapfunction btrfs_subpage_set_uptodatefunction btrfs_subpage_clear_uptodatefunction btrfs_subpage_set_dirtyfunction btrfs_subpage_clear_and_test_dirtyfunction btrfs_subpage_clear_dirtyfunction btrfs_subpage_set_writebackfunction btrfs_subpage_clear_writebackfunction btrfs_folio_assert_not_dirtyfunction lock_pagefunction btrfs_meta_folio_clear_and_test_dirtyfunction btrfs_subpage_dump_bitmapfunction btrfs_copy_subpage_dirty_bitmap
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
#include <linux/slab.h>
#include "messages.h"
#include "subpage.h"
#include "btrfs_inode.h"
/*
* Subpage (block size < folio size) support overview:
*
* Limitations:
*
* - 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 <= 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:
*
* - Common
* Both metadata and data will use a new structure, btrfs_folio_state, to
* record the status of each sector inside a page. This provides the extra
* granularity needed.
*
* - Metadata
* Since we have multiple tree blocks inside one page, we can't rely on page
* locking anymore, or we will have greatly reduced concurrency or even
* deadlocks (hold one tree lock while trying to lock another tree lock in
* the same page).
*
* Thus for metadata locking, subpage support relies on io_tree locking only.
* This means a slightly higher tree locking latency.
*/
int btrfs_attach_folio_state(const struct btrfs_fs_info *fs_info,
struct folio *folio, enum btrfs_folio_type type)
{
struct btrfs_folio_state *bfs;
/* For metadata we don't support large folio yet. */
if (type == BTRFS_SUBPAGE_METADATA)
ASSERT(!folio_test_large(folio));
/*
* We have cases like a dummy extent buffer page, which is not mapped
* and doesn't need to be locked.
*/
if (folio->mapping)
ASSERT(folio_test_locked(folio));
/* Either not subpage, or the folio already has private attached. */
if (folio_test_private(folio))
return 0;
if (type == BTRFS_SUBPAGE_METADATA && !btrfs_meta_is_subpage(fs_info))
return 0;
if (type == BTRFS_SUBPAGE_DATA && !btrfs_is_subpage(fs_info, folio))
return 0;
bfs = btrfs_alloc_folio_state(fs_info, folio_size(folio), type);
if (IS_ERR(bfs))
return PTR_ERR(bfs);
folio_attach_private(folio, bfs);
return 0;
}
void btrfs_detach_folio_state(const struct btrfs_fs_info *fs_info, struct folio *folio,
enum btrfs_folio_type type)
{
struct btrfs_folio_state *bfs;
/* Either not subpage, or the folio already has private attached. */
if (!folio_test_private(folio))
return;
if (type == BTRFS_SUBPAGE_METADATA && !btrfs_meta_is_subpage(fs_info))
return;
if (type == BTRFS_SUBPAGE_DATA && !btrfs_is_subpage(fs_info, folio))
return;
bfs = folio_detach_private(folio);
ASSERT(bfs);
btrfs_free_folio_state(bfs);
}
struct btrfs_folio_state *btrfs_alloc_folio_state(const struct btrfs_fs_info *fs_info,
size_t fsize, enum btrfs_folio_type type)
{
Annotation
- Immediate include surface: `linux/slab.h`, `messages.h`, `subpage.h`, `btrfs_inode.h`.
- Detected declarations: `function Subpage`, `function btrfs_detach_folio_state`, `function detach_extent_buffer_page`, `function btrfs_folio_dec_eb_refs`, `function btrfs_subpage_assert`, `function btrfs_subpage_clamp_range`, `function btrfs_subpage_end_and_test_lock`, `function extent_clear_unlock_delalloc`, `function writepage_delalloc`, `function btrfs_folio_end_lock_bitmap`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.