fs/gfs2/bmap.c
Source file repositories/reference/linux-study-clean/fs/gfs2/bmap.c
File Facts
- System
- Linux kernel
- Corpus path
fs/gfs2/bmap.c- Extension
.c- Size
- 66644 bytes
- Lines
- 2510
- 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/spinlock.hlinux/completion.hlinux/buffer_head.hlinux/blkdev.hlinux/gfs2_ondisk.hlinux/crc32.hlinux/iomap.hlinux/ktime.hgfs2.hincore.hbmap.hglock.hinode.hmeta_io.hquota.hrgrp.hlog.hsuper.htrans.hdir.hutil.haops.htrace_gfs2.h
Detected Declarations
struct metapathenum walker_statusenum alloc_stateenum dealloc_statesfunction gfs2_unstuffer_foliofunction __gfs2_unstuff_inodefunction gfs2_unstuff_dinodefunction find_metapathfunction metapath_branch_startfunction clone_metapathfunction gfs2_metapath_rafunction metapath_dibhfunction __fillup_metapathfunction find_metapathfunction fillup_metapathfunction metapath_to_blockfunction release_metapathfunction gfs2_extent_lengthfunction gfs2_walk_metadatafunction gfs2_hole_walkerfunction gfs2_hole_sizefunction gfs2_indirect_initfunction __gfs2_iomap_allocfunction gfs2_alloc_sizefunction __gfs2_iomap_getfunction gfs2_iomap_get_foliofunction gfs2_iomap_put_foliofunction gfs2_iomap_begin_writefunction gfs2_iomap_beginfunction gfs2_iomap_endfunction buffer_mappedfunction gfs2_get_extentfunction gfs2_alloc_extentfunction gfs2_block_zero_rangefunction gfs2_journaled_truncatefunction trunc_startfunction gfs2_iomap_getfunction gfs2_iomap_allocfunction bufferfunction mp_eq_to_hgtfunction validfunction metapointer_rangefunction walk_donefunction punch_holefunction treefunction trunc_endfunction do_shrinkfunction do_grow
Annotated Snippet
struct metapath {
struct buffer_head *mp_bh[GFS2_MAX_META_HEIGHT];
__u16 mp_list[GFS2_MAX_META_HEIGHT];
int mp_fheight; /* find_metapath height */
int mp_aheight; /* actual height (lookup height) */
};
static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length);
/**
* gfs2_unstuffer_folio - unstuff a stuffed inode into a block cached by a folio
* @ip: the inode
* @dibh: the dinode buffer
* @block: the block number that was allocated
* @folio: The folio.
*
* Returns: errno
*/
static int gfs2_unstuffer_folio(struct gfs2_inode *ip, struct buffer_head *dibh,
u64 block, struct folio *folio)
{
struct inode *inode = &ip->i_inode;
if (!folio_test_uptodate(folio)) {
void *kaddr = kmap_local_folio(folio, 0);
u64 dsize = i_size_read(inode);
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
memset(kaddr + dsize, 0, folio_size(folio) - dsize);
kunmap_local(kaddr);
folio_mark_uptodate(folio);
}
if (gfs2_is_jdata(ip)) {
struct buffer_head *bh = folio_buffers(folio);
if (!bh)
bh = create_empty_buffers(folio,
BIT(inode->i_blkbits), BIT(BH_Uptodate));
if (!buffer_mapped(bh))
map_bh(bh, inode->i_sb, block);
set_buffer_uptodate(bh);
gfs2_trans_add_data(ip->i_gl, bh);
} else {
folio_mark_dirty(folio);
gfs2_ordered_add_inode(ip);
}
return 0;
}
static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct folio *folio)
{
struct buffer_head *bh, *dibh;
struct gfs2_dinode *di;
u64 block = 0;
int isdir = gfs2_is_dir(ip);
int error;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (error)
return error;
if (i_size_read(&ip->i_inode)) {
/* Get a free block, fill it with the stuffed data,
and write it out to disk */
unsigned int n = 1;
error = gfs2_alloc_blocks(ip, &block, &n, 0);
if (error)
goto out_brelse;
if (isdir) {
gfs2_trans_remove_revoke(GFS2_SB(&ip->i_inode), block, 1);
error = gfs2_dir_get_new_buffer(ip, block, &bh);
if (error)
goto out_brelse;
gfs2_buffer_copy_tail(bh, sizeof(struct gfs2_meta_header),
dibh, sizeof(struct gfs2_dinode));
brelse(bh);
} else {
error = gfs2_unstuffer_folio(ip, dibh, block, folio);
if (error)
goto out_brelse;
}
}
/* Set up the pointer to the new block */
Annotation
- Immediate include surface: `linux/spinlock.h`, `linux/completion.h`, `linux/buffer_head.h`, `linux/blkdev.h`, `linux/gfs2_ondisk.h`, `linux/crc32.h`, `linux/iomap.h`, `linux/ktime.h`.
- Detected declarations: `struct metapath`, `enum walker_status`, `enum alloc_state`, `enum dealloc_states`, `function gfs2_unstuffer_folio`, `function __gfs2_unstuff_inode`, `function gfs2_unstuff_dinode`, `function find_metapath`, `function metapath_branch_start`, `function clone_metapath`.
- 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.