fs/crypto/bio.c
Source file repositories/reference/linux-study-clean/fs/crypto/bio.c
File Facts
- System
- Linux kernel
- Corpus path
fs/crypto/bio.c- Extension
.c- Size
- 6244 bytes
- Lines
- 217
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/bio.hlinux/export.hlinux/module.hlinux/namei.hlinux/pagemap.hfscrypt_private.h
Detected Declarations
struct fscrypt_zero_donefunction fscrypt_decrypt_biofunction bio_for_each_folio_allfunction fscrypt_zeroout_range_donefunction fscrypt_zeroout_range_end_iofunction fscrypt_zeroout_range_inline_cryptfunction fscrypt_zeroout_rangeexport fscrypt_decrypt_bioexport fscrypt_zeroout_range
Annotated Snippet
struct fscrypt_zero_done {
atomic_t pending;
blk_status_t status;
struct completion done;
};
static void fscrypt_zeroout_range_done(struct fscrypt_zero_done *done)
{
if (atomic_dec_and_test(&done->pending))
complete(&done->done);
}
static void fscrypt_zeroout_range_end_io(struct bio *bio)
{
struct fscrypt_zero_done *done = bio->bi_private;
if (bio->bi_status)
cmpxchg(&done->status, 0, bio->bi_status);
fscrypt_zeroout_range_done(done);
bio_put(bio);
}
static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode,
loff_t pos, sector_t sector,
u64 len)
{
struct fscrypt_zero_done done = {
.pending = ATOMIC_INIT(1),
.done = COMPLETION_INITIALIZER_ONSTACK(done.done),
};
while (len) {
struct bio *bio;
unsigned int n;
bio = bio_alloc(inode->i_sb->s_bdev, BIO_MAX_VECS, REQ_OP_WRITE,
GFP_NOFS);
bio->bi_iter.bi_sector = sector;
bio->bi_private = &done;
bio->bi_end_io = fscrypt_zeroout_range_end_io;
fscrypt_set_bio_crypt_ctx(bio, inode, pos, GFP_NOFS);
for (n = 0; n < BIO_MAX_VECS; n++) {
unsigned int bytes_this_page = min(len, PAGE_SIZE);
__bio_add_page(bio, ZERO_PAGE(0), bytes_this_page, 0);
len -= bytes_this_page;
pos += bytes_this_page;
sector += (bytes_this_page >> SECTOR_SHIFT);
if (!len || !fscrypt_mergeable_bio(bio, inode, pos))
break;
}
atomic_inc(&done.pending);
blk_crypto_submit_bio(bio);
}
fscrypt_zeroout_range_done(&done);
wait_for_completion(&done.done);
return blk_status_to_errno(done.status);
}
/**
* fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file
* @inode: the file's inode
* @pos: the first file position (in bytes) to zero out
* @sector: the first sector to zero out
* @len: bytes to zero out
*
* Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write
* ciphertext blocks which decrypt to the all-zeroes block. The blocks must be
* both logically and physically contiguous. It's also assumed that the
* filesystem only uses a single block device, ->s_bdev. @len must be a
* multiple of the file system logical block size.
*
* Note that since each block uses a different IV, this involves writing a
* different ciphertext to each block; we can't simply reuse the same one.
*
* Return: 0 on success; -errno on failure.
*/
int fscrypt_zeroout_range(const struct inode *inode, loff_t pos,
sector_t sector, u64 len)
{
const struct fscrypt_inode_info *ci = fscrypt_get_inode_info_raw(inode);
const unsigned int du_bits = ci->ci_data_unit_bits;
const unsigned int du_size = 1U << du_bits;
const unsigned int du_per_page_bits = PAGE_SHIFT - du_bits;
const unsigned int du_per_page = 1U << du_per_page_bits;
u64 du_index = pos >> du_bits;
Annotation
- Immediate include surface: `linux/bio.h`, `linux/export.h`, `linux/module.h`, `linux/namei.h`, `linux/pagemap.h`, `fscrypt_private.h`.
- Detected declarations: `struct fscrypt_zero_done`, `function fscrypt_decrypt_bio`, `function bio_for_each_folio_all`, `function fscrypt_zeroout_range_done`, `function fscrypt_zeroout_range_end_io`, `function fscrypt_zeroout_range_inline_crypt`, `function fscrypt_zeroout_range`, `export fscrypt_decrypt_bio`, `export fscrypt_zeroout_range`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: integration 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.