struct folio {
struct page *base_page;
_Atomic enum folio_flags flags;
uint8_t order;
refcount_t refcount;
mapcount_t mapcount;
void *mapping;
pgoff_t index;
struct list_head lru;
};
enum folio_flags : uint32_t {
FOLIO_FLAGS_NONE = 0,
FOLIO_FLAG_ON_LRU = (1u << 0),
FOLIO_FLAG_ANON = (1u << 1),
FOLIO_FLAG_MAPPED = (1u << 2),
FOLIO_FLAG_DIRTY = (1u << 3),
FOLIO_FLAG_UPTODATE = (1u << 4),
FOLIO_FLAG_LOCKED = (1u << 5),
};
enum folio_tag : uintptr_t {
FOLIO_TAG_ADDRESS_SPACE = 0,
FOLIO_TAG_ANON = 1,
};
uint32_t page_get_folio_index(struct page *p);
bool page_is_folio_head(struct page *p);
struct folio * folio_alloc_folio_struct();
void folio_free_folio_struct(struct folio *f);
struct folio * folio_alloc_internal(uint8_t order, enum alloc_flags flags, enum alloc_behavior bh);
void folio_free(struct folio *folio);
void folio_bind_pages(struct folio *f);
void folio_unbind_pages(struct folio *f);
void folio_zero(struct folio *f);
void folio_copy(const struct folio *src, struct folio *dst);
void folio_add_lru(struct folio *f);
void folio_del_lru(struct folio *f);
void page_set_folio(struct page *p, struct folio *f);
struct folio page_get_folio(const struct page *p);
void page_clear_folio(struct page *p);
bool folio_mapped(const struct folio *f);
unsigned long folio_nr_pages(const struct folio *f);
void folio_set_tag(struct folio *f, enum folio_tag t);
enum folio_tag folio_get_tag(const struct folio *f);
bool folio_test_flag(const struct folio *f, enum folio_flags m);
void folio_set_flag(struct folio *f, enum folio_flags m);
void folio_clear_flag(struct folio *f, enum folio_flags m);
bool folio_test_set_flag(struct folio *f, enum folio_flags m);
bool folio_get(struct folio *f);
void folio_put(struct folio *f);
struct page folio_get_page(const struct folio *f, size_t n);
pfn_t folio_get_pfn(const struct folio *f);
struct folio folio_from_page(const struct page *p);
struct folio folio_from_paddr(paddr_t pa);
paddr_t folio_get_paddr(const struct folio *f);
vaddr_t folio_get_vaddr(const struct folio *f);
paddr_t folio_get_paddr_for(const struct folio *f, size_t n);
vaddr_t folio_get_vaddr_for(const struct folio *f, size_t n);
void folio_mark_dirty(struct folio *f);
void folio_mark_uptodate(struct folio *f);
void folio_set_anon(struct folio *f, struct anon_vma *av, pgoff_t index);
bool folio_is_anon(const struct folio *f);
bool folio_is_file_vma_range(const struct folio *f);
struct anon_vma folio_get_anon_vma(const struct folio *f);
struct file_vma_range folio_get_file_vma_range(const struct folio *f);
bool folio_trylock(struct folio *f);
void folio_lock(struct folio *f);
void folio_unlock(struct folio *f);
void folio_mapcount_inc(struct folio *f);
bool folio_mapcount_dec(struct folio *f);
#define FOLIO_TAG_BITS 0x7
#define folio_for_each_page_struct(f, p) \
for (size_t __i = 0; \
__i < folio_nr_pages(f) && ((p) = folio_get_page((f), __i), true); \
__i++)
#define folio_for_each_page_paddr(f, p) \
for (size_t __i = 0; __i < folio_nr_pages(f) && \
((p) = folio_get_paddr_for((f), __i), true); \
__i++)
#define folio_for_each_page_vaddr(f, p) \
for (size_t __i = 0; __i < folio_nr_pages(f) && \
((p) = folio_get_vaddr_for((f), __i), true); \
__i++)
#define folio_alloc_1(sz) \
folio_alloc_internal((sz), ALLOC_FLAGS_DEFAULT, ALLOC_BEHAVIOR_DEFAULT)
#define folio_alloc_2(sz, fl) \
folio_alloc_internal((sz), (fl), ALLOC_BEHAVIOR_DEFAULT)
#define folio_alloc_3(sz, fl, bh) folio_alloc_internal((sz), (fl), (bh))
#define folio_alloc(...) \
_DISPATCH(folio_alloc, PP_NARG(__VA_ARGS__))(__VA_ARGS__)