> +struct alua_dh_data {
> + struct alua_port_group *pg;
> + int rel_port;
> + int tpgs;
The tpgs file doesn't make much sense in the new alua_dh_data
structure. Please return it explicitly from alua_check_tpgs and
assign it directly to the member in struct alua_port_group.
> +static void release_port_group(struct kref *kref)
> +{
> + struct alua_port_group *pg;
> +
> + pg = container_of(kref, struct alua_port_group, kref);
> + printk(KERN_WARNING "alua: release port group %d\n", pg->group_id);
Why is this a warning? I'd consider it nothing but debug noise.
> - err = alua_rtpg(sdev, h, 0);
> - if (err != SCSI_DH_OK)
> + if (err != SCSI_DH_OK || !h->pg)
> goto out;
>
> + kref_get(&h->pg->kref);
What prevents this kref_get from racing with the last kref_put?
I think all the kref_get calls in this patch need to be
kref_get_unless_zero with proper error handling.
> + rcu_read_lock();
> + pg = rcu_dereference(h->pg);
> + if (!pg) {
> + rcu_read_unlock();
> + return -ENXIO;
> + }
What is this rcu_read_lock supposed to protect against given
that struct alua_port_group isn't RCU freed? I think this needs
to be another kref_get_unless_zero.
> +
> if (optimize)
> - h->flags |= ALUA_OPTIMIZE_STPG;
> + pg->flags |= ALUA_OPTIMIZE_STPG;
> else
> - h->flags &= ~ALUA_OPTIMIZE_STPG;
> + pg->flags |= ~ALUA_OPTIMIZE_STPG;
> + rcu_read_unlock();
The read-modify-write of pg->flags will need some sort of locking.
Seems like most modifications of it are under pg->rtpg_lock, so
I'd suggest to enforce that as a strict rule.
> + err = alua_rtpg(sdev, h->pg, 1);
> + if (err != SCSI_DH_OK) {
> + kref_put(&h->pg->kref, release_port_group);
> + goto out;
goto out_put_pg;
out_put_pg:
> + kref_put(&h->pg->kref, release_port_group);
> out:
> if (fn)
> fn(data, err);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html