STRUCT NVMET_FC_TARGET_TEMPLATE(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct nvmet_fc_target_template(9) β€” Kernel API Manual

okay bestie, buckle up, because this is the page where the NVME-FC target template gets its whole moment ✨ The manual name is struct nvmet_fc_target_template(9) and it lives in the Kernel API Manual, and yes we're doing the whole thing, every last field, no skipping 🫢


πŸŽ€ NAME πŸŽ€

struct nvmet_fc_target_template β€” a structure holding the static entrypoints plus operational parameters for an LLDD that supports NVME subsystem behavior. It gets passed by reference in port registrations. The NVME-FC transport literally remembers the template reference and may access it during runtime operation. iykyk πŸ’…


✨ SYNOPSIS ✨

struct nvmet_fc_target_template {
    void (*targetport_delete)(struct nvmet_fc_target_port *tgtport);
    int (*xmt_ls_rsp)(struct nvmet_fc_target_port *tgtport, struct nvmefc_ls_rsp *ls_rsp);
    int (*fcp_op)(struct nvmet_fc_target_port *tgtport, struct nvmefc_tgt_fcp_req *fcpreq);
    void (*fcp_abort)(struct nvmet_fc_target_port *tgtport, struct nvmefc_tgt_fcp_req *fcpreq);
    void (*fcp_req_release)(struct nvmet_fc_target_port *tgtport, struct nvmefc_tgt_fcp_req *fcpreq);
    void (*defer_rcv)(struct nvmet_fc_target_port *tgtport, struct nvmefc_tgt_fcp_req *fcpreq);
    void (*discovery_event)(struct nvmet_fc_target_port *tgtport);
    int (*ls_req)(struct nvmet_fc_target_port *targetport, void *hosthandle, struct nvmefc_ls_req *lsreq);
    void (*ls_abort)(struct nvmet_fc_target_port *targetport, void *hosthandle, struct nvmefc_ls_req *lsreq);
    void (*host_release)(void *hosthandle);
    int (*host_traddr)(void *hosthandle, u64 *wwnn, u64 *wwpn);
    u32 max_hw_queues;
    u16 max_sgl_segments;
    u16 max_dif_sgl_segments;
    u64 dma_boundary;
    u32 target_features;
    u32 target_priv_sz;
    u32 lsrqst_priv_sz;
 };

🌸 Members 🌸

okay so this is the big one, every single member, let's go πŸ¦‹

  • targetport_delete β€” The LLDD kicks off deletion of a targetport through nvmet_fc_unregister_targetport. But plot twist: the teardown is asynchronous 😭 So this routine gets called once the teardown completes, to let the LLDD know the targetport has officially been deleted. Entrypoint is Mandatory.
  • xmt_ls_rsp β€” Called to transmit the response to a FC-NVME FC-4 LS service. The nvmefc_ls_rsp structure is the same LLDD-supplied exchange structure you specified in the nvmet_fc_rcv_ls_req call made when the LS request came in. The structure fully describes the buffers for the response payload and the dma address of the payload. The LLDD is to transmit the response (or return a non-zero errno status), and on completion of the transmit, call the "done" routine specified in the nvmefc_ls_rsp structure β€” the argument to done is the address of the nvmefc_ls_rsp structure itself, no cap. Once the done routine completes, the LLDD shall consider the LS handling complete and the nvmefc_ls_rsp structure may be freed/released. The transport will always call the xmt_ls_rsp routine for any LS received. Entrypoint is Mandatory.
  • fcp_op β€” Called to perform a data transfer or transmit a response. The nvmefc_tgt_fcp_req structure is the same LLDD-supplied exchange structure you specified in the nvmet_fc_rcv_fcp_req call made when the FCP CMD IU was received. The op field in the structure shall indicate the operation for the LLDD to perform relative to the io. πŸ’«
    • NVMET_FCOP_READDATA operation: the LLDD is to send the payload data (described by sglist) to the host in 1 or more FC sequences (preferrably 1). Note: the fc-nvme layer may call the READDATA operation multiple times for longer payloads.
    • NVMET_FCOP_WRITEDATA operation: the LLDD is to receive the payload data (described by sglist) from the host via 1 or more FC sequences (preferrably 1). The LLDD is to generate the XFER_RDY IU(s) corresponding to the data being requested.
  • fcp_abort β€” Called by the transport to abort an active command. The command may be in-between operations (nothing active in LLDD) or may have an active WRITEDATA operation pending. The LLDD is to initiate the ABTS process for the command and return from the callback. The ABTS does not need to be complete on the command. The fcp_abort callback inherently cannot fail. After the fcp_abort callback completes, the transport will wait for any outstanding operation (if there was one) to complete, then will call the fcp_req_release callback to return the command's exchange context back to the LLDD. Entrypoint is Mandatory.
  • fcp_req_release β€” Called by the transport to return a nvmefc_tgt_fcp_req back to the LLDD after all operations on the fcp operation are complete. This may be because the command completed, or on completion of abort cleanup. Entrypoint is Mandatory.
  • defer_rcv β€” Called by the transport to signal the LLLD that it has begun processing of a previously received NVME CMD IU. The LLDD is now free to re-use the rcv buffer associated with the nvmefc_tgt_fcp_req. Entrypoint is Optional.
  • discovery_event β€” Called by the transport to generate RSCN change notifications to NVME initiators. Those RSCN notifications should cause the initiator to rescan the discovery controller on the targetport. πŸ‘‘
  • ls_req β€” Called to issue a FC-NVME FC-4 LS service request. The nvme_fc_ls_req structure fully describes the buffers for the request payload and where to place the response payload. The targetport that's going to issue the LS request is identified by the targetport argument. The remote port that's going to receive the LS request is identified by the hosthandle argument. The nvmet-fc transport is only allowed to issue FC-NVME LS's on behalf of an association that was created earlier by a Create Association LS. The hosthandle will originate from the LLDD in the struct nvmefc_ls_rsp structure for the Create Association LS that was delivered to the transport. The transport will save the hosthandle as an attribute of the association. If the LLDD loses connectivity with the remote port, it must call the nvmet_fc_invalidate_host routine to remove any references to the remote port in the transport. The LLDD is to allocate an exchange, issue the LS request, obtain the LS response, and call the "done" routine specified in the request structure (the argument to done is the ls request structure itself). Entrypoint is Optional - but highly recommended. πŸ’–
  • ls_abort β€” called to request the LLDD abort the indicated ls request. The call may return before the abort has completed. After aborting the request, the LLDD must still call the ls request done routine indicating an FC transport Aborted status. Entrypoint is Mandatory if the ls_req entry point is specified.
  • host_release β€” called to inform the LLDD that the request to invalidate the host port indicated by the hosthandle has been fully completed. No associations exist with the host port and there will be no further references to hosthandle. Entrypoint is Mandatory if the lldd calls nvmet_fc_invalidate_host.
  • host_traddr β€” called by the transport to retrieve the node name and port name of the host port address. πŸŽ€
  • max_hw_queues β€” indicates the maximum number of hw queues the LLDD supports for cpu affinitization. Value is Mandatory. Must be at least 1.
  • max_sgl_segments β€” indicates the maximum number of sgl segments supported by the LLDD. Value is Mandatory. Must be at least 1. Recommend at least 256.
  • max_dif_sgl_segments β€” indicates the maximum number of sgl segments supported by the LLDD for DIF operations. Value is Mandatory. Must be at least 1. Recommend at least 256.
  • dma_boundary β€” indicates the dma address boundary where dma mappings will be split across. Value is Mandatory. Typical value is 0xFFFFFFFF to split across 4Gig address boundarys.
  • target_features β€” The LLDD sets bits in this field to correspond to optional features that are supported by the LLDD. Refer to the NVMET_FCTGTFEAT_xxx values. Value is Mandatory. Allowed to be zero.
  • target_priv_sz β€” The LLDD sets this field to the amount of additional memory that it would like the fc nvme layer to allocate on the LLDD's behalf whenever a targetport is allocated. The additional memory area is solely for the of the LLDD and its location is specified by the targetport->private pointer. Value is Mandatory. Allowed to be zero.
  • lsrqst_priv_sz β€” The LLDD sets this field to the amount of additional memory that it would like the nvmet-fc layer to allocate on the LLDD's behalf whenever a ls request structure is allocated. The additional memory area is solely for use by the LLDD and its location is specified by the ls_request->private pointer. Value is Mandatory. Allowed to be zero.

🌈 Description 🌈

Subsystem/Target Transport Entrypoints/Parameters:


...and that's where part 1 wraps, bestie β€” more coming, don't you dare close the tab πŸ’œ

Note: okay bestie, the FC-NVME layer may call the WRITEDATA operation multiple times for longer payloads. Not a one-and-done vibe. πŸ’…
  • NVMET_FCOP_READDATA_RSP operation: the LLDD is to send the payload data (described by sglist) to the host in 1 or more FC sequences (preferrably 1). If an error occurs during payload data transmission, the LLDD is to set the nvmefc_tgt_fcp_req fcp_error and transferred_length field, then consider the operation complete. On error, the LLDD is to not transmit the FCP_RSP iu. If all payload data is transferred successfully, the LLDD is to update the nvmefc_tgt_fcp_req transferred_length field and may subsequently transmit the FCP_RSP iu payload (described by rspbuf, rspdma, rsplen). If FCP_CONF is supported, the LLDD is to await FCP_CONF reception to confirm the RSP reception by the host. The LLDD may retramsit the FCP_RSP iu if necessary per FC-NVME. Upon transmission of the FCP_RSP iu if FCP_CONF is not supported, or upon success/failure of FCP_CONF if it is supported, the LLDD is to set the nvmefc_tgt_fcp_req fcp_error field and consider the operation complete. ✨
  • NVMET_FCOP_RSP: the LLDD is to transmit the FCP_RSP iu payload (described by rspbuf, rspdma, rsplen). If FCP_CONF is supported, the LLDD is to await FCP_CONF reception to confirm the RSP reception by the host. The LLDD may retramsit the FCP_RSP iu if FCP_CONF is not received per FC-NVME. Upon transmission of the FCP_RSP iu if FCP_CONF is not supported, or upon success/failure of FCP_CONF if it is supported, the LLDD is to set the nvmefc_tgt_fcp_req fcp_error field and consider the operation complete. 🫢

Upon completing the indicated operation, the LLDD is to set the status fields for the operation (tranferred_length and fcp_error status) in the request, then call the "done" routine indicated in the fcp request. After the operation completes, regardless of whether the FCP_RSP iu was successfully transmit, the LLDD-supplied exchange structure must remain valid until the transport calls the fcp_req_release callback to return ownership of the exchange structure back to the LLDD so that it may be used for another fcp command. πŸ‘‘

When calling the done routine for READDATA or WRITEDATA operations, the fc-nvme layer may immediate convert, in the same thread and before returning to the LLDD, the fcp operation to the next operation for the fcp io and call the LLDDs fcp_op call again. If fields in the fcp request are to be accessed post the done call, the LLDD should save their values prior to calling the done routine, and inspect the save values after the done routine. 😭

Returns 0 on success, -<errno> on failure (Ex: -EIO). Entrypoint is Mandatory. periodt. πŸ’€


🌈 SEE ALSO 🌈

  • Kernel file: ./include/linux/nvme-fc-driver.h
  • struct nvmefc_ls_req(9)
  • struct nvmefc_ls_rsp(9)
  • struct nvme_fc_port_info(9)
  • struct nvmefc_fcp_req(9)
  • struct nvme_fc_local_port(9)
  • struct nvme_fc_remote_port(9)
  • struct nvme_fc_port_template(9)
  • struct nvmet_fc_port_info(9)
  • struct nvmefc_tgt_fcp_req(9)
  • struct nvmet_fc_target_port(9)

That’s the whole tea β˜•: this page lives under ./include/linux, it’s stamped October 2026, and the page is struct nvme...get_template(9). Mwah πŸ’‹

πŸ“¦ where this page comes from