fs/udf/inode.c
Source file repositories/reference/linux-study-clean/fs/udf/inode.c
File Facts
- System
- Linux kernel
- Corpus path
fs/udf/inode.c- Extension
.c- Size
- 70080 bytes
- Lines
- 2460
- 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
udfdecl.hlinux/mm.hlinux/module.hlinux/pagemap.hlinux/writeback.hlinux/slab.hlinux/crc-itu-t.hlinux/mpage.hlinux/uio.hlinux/bio.hudf_i.hudf_sb.h
Detected Declarations
struct udf_map_rqstruct udf_map_rqfunction __udf_clear_extent_cachefunction udf_clear_extent_cachefunction udf_read_extent_cachefunction udf_update_extent_cachefunction udf_evict_inodefunction udf_write_failedfunction udf_handle_page_wbfunction udf_writepagesfunction udf_adinicb_read_foliofunction udf_read_foliofunction udf_readaheadfunction udf_write_beginfunction udf_write_endfunction udf_direct_IOfunction udf_bmapfunction udf_expand_file_adinicbfunction udf_map_blockfunction __udf_get_blockfunction udf_get_blockfunction udf_get_block_wbfunction udf_do_extend_filefunction udf_do_extend_final_blockfunction udf_extend_filefunction inode_getblkfunction udf_split_extentsfunction udf_prealloc_extentsfunction udf_merge_extentsfunction udf_update_extentsfunction udf_setsizefunction udf_read_inodefunction udf_alloc_i_datafunction udf_convert_permissionsfunction udf_update_extra_permsfunction udf_write_inodefunction udf_sync_inodefunction udf_adjust_timefunction udf_update_inodefunction udf_setup_indirect_aextfunction __udf_add_aextfunction udf_add_aextfunction udf_write_aextfunction udf_next_aextfunction udf_current_aextfunction udf_insert_aextfunction udf_delete_aextfunction inode_bmap
Annotated Snippet
struct udf_map_rq {
sector_t lblk;
udf_pblk_t pblk;
int iflags; /* UDF_MAP_ flags determining behavior */
int oflags; /* UDF_BLK_ flags reporting results */
};
static int udf_map_block(struct inode *inode, struct udf_map_rq *map)
{
int ret;
struct udf_inode_info *iinfo = UDF_I(inode);
if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB))
return -EFSCORRUPTED;
map->oflags = 0;
if (!(map->iflags & UDF_MAP_CREATE)) {
struct kernel_lb_addr eloc;
uint32_t elen;
sector_t offset;
struct extent_position epos = {};
int8_t etype;
down_read(&iinfo->i_data_sem);
ret = inode_bmap(inode, map->lblk, &epos, &eloc, &elen, &offset,
&etype);
if (ret < 0)
goto out_read;
if (ret > 0 && etype == (EXT_RECORDED_ALLOCATED >> 30)) {
map->pblk = udf_get_lb_pblock(inode->i_sb, &eloc,
offset);
map->oflags |= UDF_BLK_MAPPED;
ret = 0;
}
out_read:
up_read(&iinfo->i_data_sem);
brelse(epos.bh);
return ret;
}
down_write(&iinfo->i_data_sem);
/*
* Block beyond EOF and prealloc extents? Just discard preallocation
* as it is not useful and complicates things.
*/
if (((loff_t)map->lblk) << inode->i_blkbits >= iinfo->i_lenExtents)
udf_discard_prealloc(inode);
udf_clear_extent_cache(inode);
ret = inode_getblk(inode, map);
up_write(&iinfo->i_data_sem);
return ret;
}
static int __udf_get_block(struct inode *inode, sector_t block,
struct buffer_head *bh_result, int flags)
{
int err;
struct udf_map_rq map = {
.lblk = block,
.iflags = flags,
};
err = udf_map_block(inode, &map);
if (err < 0)
return err;
if (map.oflags & UDF_BLK_MAPPED) {
map_bh(bh_result, inode->i_sb, map.pblk);
if (map.oflags & UDF_BLK_NEW)
set_buffer_new(bh_result);
}
return 0;
}
int udf_get_block(struct inode *inode, sector_t block,
struct buffer_head *bh_result, int create)
{
int flags = create ? UDF_MAP_CREATE : 0;
/*
* We preallocate blocks only for regular files. It also makes sense
* for directories but there's a problem when to drop the
* preallocation. We might use some delayed work for that but I feel
* it's overengineering for a filesystem like UDF.
*/
if (!S_ISREG(inode->i_mode))
flags |= UDF_MAP_NOPREALLOC;
return __udf_get_block(inode, block, bh_result, flags);
}
Annotation
- Immediate include surface: `udfdecl.h`, `linux/mm.h`, `linux/module.h`, `linux/pagemap.h`, `linux/writeback.h`, `linux/slab.h`, `linux/crc-itu-t.h`, `linux/mpage.h`.
- Detected declarations: `struct udf_map_rq`, `struct udf_map_rq`, `function __udf_clear_extent_cache`, `function udf_clear_extent_cache`, `function udf_read_extent_cache`, `function udf_update_extent_cache`, `function udf_evict_inode`, `function udf_write_failed`, `function udf_handle_page_wb`, `function udf_writepages`.
- 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.