fs/ext4/ialloc.c
Source file repositories/reference/linux-study-clean/fs/ext4/ialloc.c
File Facts
- System
- Linux kernel
- Corpus path
fs/ext4/ialloc.c- Extension
.c- Size
- 45758 bytes
- Lines
- 1629
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/time.hlinux/fs.hlinux/stat.hlinux/string.hlinux/quotaops.hlinux/buffer_head.hlinux/random.hlinux/bitops.hlinux/blkdev.hlinux/cred.hasm/byteorder.hext4.hext4_jbd2.hxattr.hacl.htrace/events/ext4.h
Detected Declarations
struct orlov_statsfunction Copyrightfunction ext4_end_bitmap_readfunction ext4_validate_inode_bitmapfunction ext4_simulate_failfunction ext4_read_inode_bitmapfunction numberfunction get_orlov_statsfunction alreadyfunction find_group_otherfunction recently_deletedfunction find_inode_bitfunction ext4_mark_inode_usedfunction ext4_xattr_credits_for_new_inodefunction ext4_count_free_inodesfunction ext4_count_dirsfunction ext4_new_inode
Annotated Snippet
struct orlov_stats {
__u64 free_clusters;
__u32 free_inodes;
__u32 used_dirs;
};
/*
* Helper function for Orlov's allocator; returns critical information
* for a particular block group or flex_bg. If flex_size is 1, then g
* is a block group number; otherwise it is flex_bg number.
*/
static void get_orlov_stats(struct super_block *sb, ext4_group_t g,
int flex_size, struct orlov_stats *stats)
{
struct ext4_group_desc *desc;
if (flex_size > 1) {
struct flex_groups *fg = sbi_array_rcu_deref(EXT4_SB(sb),
s_flex_groups, g);
stats->free_inodes = atomic_read(&fg->free_inodes);
stats->free_clusters = atomic64_read(&fg->free_clusters);
stats->used_dirs = atomic_read(&fg->used_dirs);
return;
}
desc = ext4_get_group_desc(sb, g, NULL);
if (desc) {
stats->free_inodes = ext4_free_inodes_count(sb, desc);
stats->free_clusters = ext4_free_group_clusters(sb, desc);
stats->used_dirs = ext4_used_dirs_count(sb, desc);
} else {
stats->free_inodes = 0;
stats->free_clusters = 0;
stats->used_dirs = 0;
}
}
/*
* Orlov's allocator for directories.
*
* We always try to spread first-level directories.
*
* If there are blockgroups with both free inodes and free clusters counts
* not worse than average we return one with smallest directory count.
* Otherwise we simply return a random group.
*
* For the rest rules look so:
*
* It's OK to put directory into a group unless
* it has too many directories already (max_dirs) or
* it has too few free inodes left (min_inodes) or
* it has too few free clusters left (min_clusters) or
* Parent's group is preferred, if it doesn't satisfy these
* conditions we search cyclically through the rest. If none
* of the groups look good we just look for a group with more
* free inodes than average (starting at parent's group).
*/
static int find_group_orlov(struct super_block *sb, struct inode *parent,
ext4_group_t *group, umode_t mode,
const struct qstr *qstr)
{
ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
struct ext4_sb_info *sbi = EXT4_SB(sb);
ext4_group_t real_ngroups = ext4_get_groups_count(sb);
int inodes_per_group = EXT4_INODES_PER_GROUP(sb);
unsigned int freei, avefreei, grp_free;
ext4_fsblk_t freec, avefreec;
unsigned int ndirs;
int max_dirs, min_inodes;
ext4_grpblk_t min_clusters;
ext4_group_t i, grp, g, ngroups;
struct ext4_group_desc *desc;
struct orlov_stats stats;
int flex_size = ext4_flex_bg_size(sbi);
struct dx_hash_info hinfo;
ngroups = real_ngroups;
if (flex_size > 1) {
ngroups = (real_ngroups + flex_size - 1) >>
sbi->s_log_groups_per_flex;
parent_group >>= sbi->s_log_groups_per_flex;
}
freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
avefreei = freei / ngroups;
freec = percpu_counter_read_positive(&sbi->s_freeclusters_counter);
avefreec = freec;
do_div(avefreec, ngroups);
ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
Annotation
- Immediate include surface: `linux/time.h`, `linux/fs.h`, `linux/stat.h`, `linux/string.h`, `linux/quotaops.h`, `linux/buffer_head.h`, `linux/random.h`, `linux/bitops.h`.
- Detected declarations: `struct orlov_stats`, `function Copyright`, `function ext4_end_bitmap_read`, `function ext4_validate_inode_bitmap`, `function ext4_simulate_fail`, `function ext4_read_inode_bitmap`, `function number`, `function get_orlov_stats`, `function already`, `function find_group_other`.
- 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.