fs/ext4/migrate.c
Source file repositories/reference/linux-study-clean/fs/ext4/migrate.c
File Facts
- System
- Linux kernel
- Corpus path
fs/ext4/migrate.c- Extension
.c- Size
- 17919 bytes
- Lines
- 685
- 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/slab.hext4_jbd2.hext4_extents.h
Detected Declarations
struct migrate_structfunction finish_rangefunction update_extent_rangefunction rangefunction update_ind_extent_rangefunction update_dind_extent_rangefunction update_tind_extent_rangefunction free_dind_blocksfunction free_tind_blocksfunction free_ind_blockfunction ext4_ext_swap_inode_datafunction free_ext_idxfunction free_ext_blockfunction ext4_ext_migratefunction ext4_ind_migrate
Annotated Snippet
struct migrate_struct {
ext4_lblk_t first_block, last_block, curr_block;
ext4_fsblk_t first_pblock, last_pblock;
};
static int finish_range(handle_t *handle, struct inode *inode,
struct migrate_struct *lb)
{
int retval = 0, needed;
struct ext4_extent newext;
struct ext4_ext_path *path;
if (lb->first_pblock == 0)
return 0;
/* Add the extent to temp inode*/
newext.ee_block = cpu_to_le32(lb->first_block);
newext.ee_len = cpu_to_le16(lb->last_block - lb->first_block + 1);
ext4_ext_store_pblock(&newext, lb->first_pblock);
/* Locking only for convenience since we are operating on temp inode */
down_write(&EXT4_I(inode)->i_data_sem);
path = ext4_find_extent(inode, lb->first_block, NULL, 0);
if (IS_ERR(path)) {
retval = PTR_ERR(path);
goto err_out;
}
/*
* Calculate the credit needed to inserting this extent
* Since we are doing this in loop we may accumulate extra
* credit. But below we try to not accumulate too much
* of them by restarting the journal.
*/
needed = ext4_ext_calc_credits_for_single_extent(inode,
lb->last_block - lb->first_block + 1, path);
retval = ext4_datasem_ensure_credits(handle, inode, needed, needed, 0);
if (retval < 0)
goto err_out;
path = ext4_ext_insert_extent(handle, inode, path, &newext, 0);
if (IS_ERR(path))
retval = PTR_ERR(path);
err_out:
up_write((&EXT4_I(inode)->i_data_sem));
ext4_free_ext_path(path);
lb->first_pblock = 0;
return retval;
}
static int update_extent_range(handle_t *handle, struct inode *inode,
ext4_fsblk_t pblock, struct migrate_struct *lb)
{
int retval;
/*
* See if we can add on to the existing range (if it exists)
*/
if (lb->first_pblock &&
(lb->last_pblock+1 == pblock) &&
(lb->last_block+1 == lb->curr_block)) {
lb->last_pblock = pblock;
lb->last_block = lb->curr_block;
lb->curr_block++;
return 0;
}
/*
* Start a new range.
*/
retval = finish_range(handle, inode, lb);
lb->first_pblock = lb->last_pblock = pblock;
lb->first_block = lb->last_block = lb->curr_block;
lb->curr_block++;
return retval;
}
static int update_ind_extent_range(handle_t *handle, struct inode *inode,
ext4_fsblk_t pblock,
struct migrate_struct *lb)
{
struct buffer_head *bh;
__le32 *i_data;
int i, retval = 0;
unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
bh = ext4_sb_bread(inode->i_sb, pblock, 0);
if (IS_ERR(bh))
return PTR_ERR(bh);
i_data = (__le32 *)bh->b_data;
for (i = 0; i < max_entries; i++) {
if (i_data[i]) {
Annotation
- Immediate include surface: `linux/slab.h`, `ext4_jbd2.h`, `ext4_extents.h`.
- Detected declarations: `struct migrate_struct`, `function finish_range`, `function update_extent_range`, `function range`, `function update_ind_extent_range`, `function update_dind_extent_range`, `function update_tind_extent_range`, `function free_dind_blocks`, `function free_tind_blocks`, `function free_ind_block`.
- 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.