fs/ntfs/aops.c
Source file repositories/reference/linux-study-clean/fs/ntfs/aops.c
File Facts
- System
- Linux kernel
- Corpus path
fs/ntfs/aops.c- Extension
.c- Size
- 9595 bytes
- Lines
- 306
- 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.
- 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/writeback.hattrib.hmft.hntfs.hdebug.hiomap.h
Detected Declarations
function Copyrightfunction bio_for_each_folio_allfunction ntfs_iomap_bio_submit_readfunction ntfs_read_compressed_blockfunction respectfunction NInoMstProtectedfunction LCN_EIOfunction ntfs_readaheadfunction ntfs_writepagesfunction ntfs_swap_activate
Annotated Snippet
if (NInoEncrypted(ni)) {
folio_unlock(folio);
return -EOPNOTSUPP;
}
/* Compressed data streams are handled in compress.c. */
if (NInoNonResident(ni) && NInoCompressed(ni))
return ntfs_read_compressed_block(folio);
}
iomap_read_folio(&ntfs_read_iomap_ops, &ctx, NULL);
return 0;
}
/*
* ntfs_bmap - map logical file block to physical device block
* @mapping: address space mapping to which the block to be mapped belongs
* @block: logical block to map to its physical device block
*
* For regular, non-resident files (i.e. not compressed and not encrypted), map
* the logical @block belonging to the file described by the address space
* mapping @mapping to its physical device block.
*
* The size of the block is equal to the @s_blocksize field of the super block
* of the mounted file system which is guaranteed to be smaller than or equal
* to the cluster size thus the block is guaranteed to fit entirely inside the
* cluster which means we do not need to care how many contiguous bytes are
* available after the beginning of the block.
*
* Return the physical device block if the mapping succeeded or 0 if the block
* is sparse or there was an error.
*
* Note: This is a problem if someone tries to run bmap() on $Boot system file
* as that really is in block zero but there is nothing we can do. bmap() is
* just broken in that respect (just like it cannot distinguish sparse from
* not available or error).
*/
static sector_t ntfs_bmap(struct address_space *mapping, sector_t block)
{
s64 ofs, size;
loff_t i_size;
s64 lcn;
unsigned long blocksize, flags;
struct ntfs_inode *ni = NTFS_I(mapping->host);
struct ntfs_volume *vol = ni->vol;
unsigned int delta;
unsigned char blocksize_bits;
ntfs_debug("Entering for mft_no 0x%llx, logical block 0x%llx.",
ni->mft_no, (unsigned long long)block);
if (ni->type != AT_DATA || !NInoNonResident(ni) || NInoEncrypted(ni) ||
NInoMstProtected(ni)) {
ntfs_error(vol->sb, "BMAP does not make sense for %s attributes, returning 0.",
(ni->type != AT_DATA) ? "non-data" :
(!NInoNonResident(ni) ? "resident" :
"encrypted"));
return 0;
}
/* None of these can happen. */
blocksize = vol->sb->s_blocksize;
blocksize_bits = vol->sb->s_blocksize_bits;
ofs = (s64)block << blocksize_bits;
read_lock_irqsave(&ni->size_lock, flags);
size = ni->initialized_size;
i_size = i_size_read(VFS_I(ni));
read_unlock_irqrestore(&ni->size_lock, flags);
/*
* If the offset is outside the initialized size or the block straddles
* the initialized size then pretend it is a hole unless the
* initialized size equals the file size.
*/
if (unlikely(ofs >= size || (ofs + blocksize > size && size < i_size)))
goto hole;
down_read(&ni->runlist.lock);
lcn = ntfs_attr_vcn_to_lcn_nolock(ni, ntfs_bytes_to_cluster(vol, ofs),
false);
up_read(&ni->runlist.lock);
if (unlikely(lcn < LCN_HOLE)) {
/*
* Step down to an integer to avoid gcc doing a long long
* comparision in the switch when we know @lcn is between
* LCN_HOLE and LCN_EIO (i.e. -1 to -5).
*
* Otherwise older gcc (at least on some architectures) will
* try to use __cmpdi2() which is of course not available in
* the kernel.
*/
switch ((int)lcn) {
case LCN_ENOENT:
/*
* If the offset is out of bounds then pretend it is a
Annotation
- Immediate include surface: `linux/writeback.h`, `attrib.h`, `mft.h`, `ntfs.h`, `debug.h`, `iomap.h`.
- Detected declarations: `function Copyright`, `function bio_for_each_folio_all`, `function ntfs_iomap_bio_submit_read`, `function ntfs_read_compressed_block`, `function respect`, `function NInoMstProtected`, `function LCN_EIO`, `function ntfs_readahead`, `function ntfs_writepages`, `function ntfs_swap_activate`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
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.