[PATCH 7/7 v2] nvme-fabrics: Add FC LLDD loopback driver to test FC-NVME
Christoph Hellwig
hch at infradead.org
Wed Oct 12 03:37:23 PDT 2016
> +#define is_end_of_list(pos, head, member) ((&pos->member) == (head))
This one isn't actually used in the code.
> + (tgt_lsreq->done)(tgt_lsreq);
no need for the first set of braces.
> +void
> +fcloop_fcp_copy_data(u8 op, struct scatterlist *data_sg,
> + struct scatterlist *io_sg, u32 offset, u32 length)
Should be marked static (as should most of the functions in this file)
> +int
> +fcloop_fcp_op(struct nvmet_fc_target_port *tgtport,
> + struct nvmefc_tgt_fcp_req *tgt_fcpreq)
> +{
> + struct fcloop_fcpreq *tfcp_req = tgt_fcp_req_to_fcpreq(tgt_fcpreq);
> + struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq;
> + u32 rsplen = 0, xfrlen = 0;
> + int fcp_err = 0;
> + u8 op = tgt_fcpreq->op;
> +
> + switch (op) {
> + case NVMET_FCOP_WRITEDATA:
> + xfrlen = tgt_fcpreq->transfer_length;
> + fcloop_fcp_copy_data(op, tgt_fcpreq->sg, fcpreq->first_sgl,
> + tgt_fcpreq->offset, xfrlen);
> + fcpreq->transferred_length += xfrlen;
.. but I don't even understand why we need to copy between these
SGLs?
> + spin_lock_irqsave(&fcloop_lock, flags);
> +
> + list_for_each_entry(tlport, &fcloop_lports, lport_list) {
> + if ((tlport->localport->node_name == nodename) &&
> + (tlport->localport->port_name == portname)) {
> + lport = tlport;
> + break;
> + }
> + }
> + spin_unlock_irqrestore(&fcloop_lock, flags);
> +
> + if (!lport)
> + return -ENOENT;
> +
> + ret = __delete_local_port(lport);
We either need a reference or do the actual deletion under the
lock.
> + list_for_each_entry(nport, &fcloop_nports, nport_list) {
> + if ((nport->node_name == opts->wwnn) &&
> + (nport->port_name == opts->wwpn)) {
> + if ((remoteport && nport->rport) ||
> + (!remoteport && nport->tport)) {
> + nport = NULL;
> + goto out_invalid_opts;
> + }
> +
> + fcloop_nport_get(nport);
Needs to check the return value.
> + list_for_each_entry(tnport, &fcloop_nports, nport_list) {
> + if ((tnport->node_name == nodename) &&
> + (tnport->port_name == portname) && tnport->rport) {
> + nport = tnport;
> + break;
> + }
> + }
> +
> + spin_unlock_irqrestore(&fcloop_lock, flags);
> +
> + if (!nport)
> + return -ENOENT;
> +
> + ret = __delete_remote_port(nport);
The deletion needs to be done under fcloop_lock, or we need a refcount.
> + list_for_each_entry(tnport, &fcloop_nports, nport_list) {
> + if ((tnport->node_name == nodename) &&
> + (tnport->port_name == portname) && tnport->tport) {
> + nport = tnport;
> + break;
> + }
> + }
> +
> + spin_unlock_irqrestore(&fcloop_lock, flags);
> +
> + if (!nport)
> + return -ENOENT;
> +
> + ret = __delete_target_port(nport);
Same here.
> +
> + fcloop_device =
> + device_create(fcloop_class, NULL, MKDEV(0, 0), NULL, "ctl");
> + if (IS_ERR(fcloop_device)) {
> + pr_err("couldn't create ctl device!\n");
> + ret = PTR_ERR(fcloop_device);
> + goto out_destroy_class;
> + }
> +
> + ret = device_create_file(fcloop_device, &dev_attr_add_local_port);
> + if (ret) {
> + pr_err("couldn't add device add_local_port attr.\n");
> + goto out_destroy_device;
> + }
> +
> + ret = device_create_file(fcloop_device, &dev_attr_del_local_port);
...
Please use device_create_with_groups.
> + for (;;) {
> + nport = list_first_entry_or_null(&fcloop_nports,
> + typeof(*nport), nport_list);
> + if (!nport)
> + break;
> +
> + spin_unlock_irqrestore(&fcloop_lock, flags);
> +
> + ret = __delete_target_port(nport);
> + if (ret)
> + pr_warn("%s: Failed deleting target port\n", __func__);
> +
> + ret = __delete_remote_port(nport);
> + if (ret)
> + pr_warn("%s: Failed deleting remote port\n", __func__);
> +
> + spin_lock_irqsave(&fcloop_lock, flags);
> + }
The deletions need to happen without dropping the lock, or you need
refcounts.
> +
> + for (;;) {
> + lport = list_first_entry_or_null(&fcloop_lports,
> + typeof(*lport), lport_list);
> + if (!lport)
> + break;
> +
> + spin_unlock_irqrestore(&fcloop_lock, flags);
> +
> + ret = __delete_local_port(lport);
> + if (ret)
> + pr_warn("%s: Failed deleting local port\n", __func__);
> +
> + spin_lock_irqsave(&fcloop_lock, flags);
> +
> + }
> +
> + spin_unlock_irqrestore(&fcloop_lock, flags);
Same here.
More information about the Linux-nvme
mailing list