drivers/target/target_core_file.c
Source file repositories/reference/linux-study-clean/drivers/target/target_core_file.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/target/target_core_file.c- Extension
.c- Size
- 24670 bytes
- Lines
- 951
- Domain
- Driver Families
- Bucket
- drivers/target
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/string.hlinux/parser.hlinux/timer.hlinux/blkdev.hlinux/slab.hlinux/spinlock.hlinux/module.hlinux/vmalloc.hlinux/falloc.hlinux/uio.hlinux/scatterlist.hscsi/scsi_proto.hlinux/unaligned.htarget/target_core_base.htarget/target_core_backend.htarget_core_file.h
Detected Declarations
struct target_core_file_cmdfunction fd_attach_hbafunction fd_detach_hbafunction fd_configure_unmapfunction fd_configure_devicefunction accessfunction fd_dev_call_rcufunction fd_free_devicefunction fd_destroy_devicefunction cmd_rw_aio_completefunction fd_execute_rw_aiofunction for_each_sgfunction fd_do_rwfunction for_each_sgfunction fd_execute_sync_cachefunction fd_execute_write_samefunction fd_do_prot_fillfunction fd_do_prot_unmapfunction fd_execute_unmapfunction fd_execute_rw_bufferedfunction vfs_fsync_rangefunction fd_execute_rwfunction iovecsfunction fd_set_configfs_dev_paramsfunction fd_show_configfs_dev_paramsfunction fd_get_blocksfunction fd_init_protfunction fd_format_protfunction fd_free_protfunction fd_parse_cdbfunction fileio_module_initfunction fileio_module_exitmodule init fileio_module_init
Annotated Snippet
pr_err("vfs_write to prot file failed: %zd\n", ret);
return ret < 0 ? ret : -ENODEV;
}
prot += ret;
}
return 0;
}
static int
fd_do_prot_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb)
{
void *buf;
int rc;
buf = (void *)__get_free_page(GFP_KERNEL);
if (!buf) {
pr_err("Unable to allocate FILEIO prot buf\n");
return -ENOMEM;
}
rc = fd_do_prot_fill(cmd->se_dev, lba, nolb, buf, PAGE_SIZE);
free_page((unsigned long)buf);
return rc;
}
static sense_reason_t
fd_execute_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb)
{
struct file *file = FD_DEV(cmd->se_dev)->fd_file;
struct inode *inode = file->f_mapping->host;
int ret;
if (!nolb) {
return 0;
}
if (cmd->se_dev->dev_attrib.pi_prot_type) {
ret = fd_do_prot_unmap(cmd, lba, nolb);
if (ret)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
if (S_ISBLK(inode->i_mode)) {
/* The backend is block device, use discard */
struct block_device *bdev = I_BDEV(inode);
struct se_device *dev = cmd->se_dev;
ret = blkdev_issue_discard(bdev,
target_to_linux_sector(dev, lba),
target_to_linux_sector(dev, nolb),
GFP_KERNEL);
if (ret < 0) {
pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n",
ret);
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
} else {
/* The backend is normal file, use fallocate */
struct se_device *se_dev = cmd->se_dev;
loff_t pos = lba * se_dev->dev_attrib.block_size;
unsigned int len = nolb * se_dev->dev_attrib.block_size;
int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
if (!file->f_op->fallocate)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = file->f_op->fallocate(file, mode, pos, len);
if (ret < 0) {
pr_warn("FILEIO: fallocate() failed: %d\n", ret);
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
}
return 0;
}
static sense_reason_t
fd_execute_rw_buffered(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
enum dma_data_direction data_direction)
{
struct se_device *dev = cmd->se_dev;
struct fd_dev *fd_dev = FD_DEV(dev);
struct file *file = fd_dev->fd_file;
struct file *pfile = fd_dev->fd_prot_file;
sense_reason_t rc;
int ret = 0;
/*
Annotation
- Immediate include surface: `linux/string.h`, `linux/parser.h`, `linux/timer.h`, `linux/blkdev.h`, `linux/slab.h`, `linux/spinlock.h`, `linux/module.h`, `linux/vmalloc.h`.
- Detected declarations: `struct target_core_file_cmd`, `function fd_attach_hba`, `function fd_detach_hba`, `function fd_configure_unmap`, `function fd_configure_device`, `function access`, `function fd_dev_call_rcu`, `function fd_free_device`, `function fd_destroy_device`, `function cmd_rw_aio_complete`.
- Atlas domain: Driver Families / drivers/target.
- Implementation status: integration 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.