drivers/target/target_core_sbc.c
Source file repositories/reference/linux-study-clean/drivers/target/target_core_sbc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/target/target_core_sbc.c- Extension
.c- Size
- 37802 bytes
- Lines
- 1450
- 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.
- 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/kernel.hlinux/module.hlinux/ratelimit.hlinux/crc-t10dif.hlinux/t10-pi.hlinux/unaligned.hscsi/scsi_proto.hscsi/scsi_tcq.htarget/target_core_base.htarget/target_core_backend.htarget/target_core_fabric.htarget_core_internal.htarget_core_ua.htarget_core_alua.h
Detected Declarations
function sbc_emulate_readcapacityfunction sbc_emulate_readcapacity_16function CAPACITYfunction sbc_emulate_startstopfunction sbc_get_write_same_sectorsfunction sbc_execute_write_same_unmapfunction sbc_emulate_noopfunction sbc_get_sizefunction transport_get_sectors_6function transport_get_sectors_10function transport_get_sectors_12function transport_get_sectors_16function transport_get_sectors_32function transport_lba_21function transport_lba_32function transport_lba_64function sbc_setup_write_samefunction sbc_execute_rwfunction compare_and_write_postfunction compare_and_write_do_cmpfunction compare_and_write_callbackfunction sbc_compare_and_writefunction sbc_set_prot_op_checksfunction sbc_check_protfunction sbc_check_dpofuafunction sbc_check_atomicfunction sbc_parse_cdbfunction sbc_get_device_typefunction sbc_execute_unmapfunction sbc_dif_generatefunction for_each_sgfunction sbc_dif_v1_verifyfunction sbc_dif_copy_protfunction for_each_sgfunction sbc_dif_verifyexport sbc_get_write_same_sectorsexport sbc_parse_cdbexport sbc_get_device_typeexport sbc_dif_copy_protexport sbc_dif_verify
Annotated Snippet
if (!dev->dev_attrib.emulate_tpws) {
pr_err("Got WRITE_SAME w/ UNMAP=1, but backend device"
" has emulate_tpws disabled\n");
return TCM_UNSUPPORTED_SCSI_OPCODE;
}
cmd->execute_cmd = sbc_execute_write_same_unmap;
return 0;
}
if (!ops->execute_write_same)
return TCM_UNSUPPORTED_SCSI_OPCODE;
ret = sbc_check_prot(dev, cmd, flags >> 5, sectors, true);
if (ret)
return ret;
cmd->execute_cmd = ops->execute_write_same;
return 0;
}
static sense_reason_t
sbc_execute_rw(struct se_cmd *cmd)
{
struct exec_cmd_ops *ops = cmd->protocol_data;
return ops->execute_rw(cmd, cmd->t_data_sg, cmd->t_data_nents,
cmd->data_direction);
}
static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success,
int *post_ret)
{
struct se_device *dev = cmd->se_dev;
sense_reason_t ret = TCM_NO_SENSE;
spin_lock_irq(&cmd->t_state_lock);
if (success) {
*post_ret = 1;
if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION)
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
spin_unlock_irq(&cmd->t_state_lock);
/*
* Unlock ->caw_sem originally obtained during sbc_compare_and_write()
* before the original READ I/O submission.
*/
up(&dev->caw_sem);
return ret;
}
/*
* compare @cmp_len bytes of @read_sgl with @cmp_sgl. On miscompare, fill
* @miscmp_off and return TCM_MISCOMPARE_VERIFY.
*/
static sense_reason_t
compare_and_write_do_cmp(struct scatterlist *read_sgl, unsigned int read_nents,
struct scatterlist *cmp_sgl, unsigned int cmp_nents,
unsigned int cmp_len, unsigned int *miscmp_off)
{
unsigned char *buf = NULL;
struct scatterlist *sg;
sense_reason_t ret;
unsigned int offset;
size_t rc;
int sg_cnt;
buf = kzalloc(cmp_len, GFP_KERNEL);
if (!buf) {
ret = TCM_OUT_OF_RESOURCES;
goto out;
}
rc = sg_copy_to_buffer(cmp_sgl, cmp_nents, buf, cmp_len);
if (!rc) {
pr_err("sg_copy_to_buffer() failed for compare_and_write\n");
ret = TCM_OUT_OF_RESOURCES;
goto out;
}
/*
* Compare SCSI READ payload against verify payload
*/
offset = 0;
ret = TCM_NO_SENSE;
for_each_sg(read_sgl, sg, read_nents, sg_cnt) {
unsigned int len = min(sg->length, cmp_len);
unsigned char *addr = kmap_atomic(sg_page(sg));
if (memcmp(addr, buf + offset, len)) {
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/ratelimit.h`, `linux/crc-t10dif.h`, `linux/t10-pi.h`, `linux/unaligned.h`, `scsi/scsi_proto.h`, `scsi/scsi_tcq.h`.
- Detected declarations: `function sbc_emulate_readcapacity`, `function sbc_emulate_readcapacity_16`, `function CAPACITY`, `function sbc_emulate_startstop`, `function sbc_get_write_same_sectors`, `function sbc_execute_write_same_unmap`, `function sbc_emulate_noop`, `function sbc_get_size`, `function transport_get_sectors_6`, `function transport_get_sectors_10`.
- Atlas domain: Driver Families / drivers/target.
- 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.