On 04/12/2018 10:08 PM, Xiubo Li wrote:
>
>>> +
>>> + if (val != 1) {
>>> + pr_err("Invalid block value %d\n", val);
>> I think you wanted
>>
>> "Invalid reset value %d\n"
> Yeah, just copied it from other place.
>>
>>> + return -EINVAL;
>>> + }
>>> +
>>> + spin_unlock(&udev->nl_cmd_lock);
>> Need spin_lock() instead of unlock.
>>
>>
>> I think before calling the code below you need to check if a nl command
>> is even waiting. If you just run this with no nl commands waiting then
>> next time we send a command nl_cmd->complete will be true and
>> tcmu_wait_genl_cmd_reply's wait_event call will return right away.
> Will fix this.
>
>>
>>> + nl_cmd->complete = true;
>>> + nl_cmd->status = -EINTR;
>>> + wake_up(&udev->complete_wq);
>> Instead of the code above, I think you need to take some of the guts out
>> of tcmu_genl_cmd_done to handle removal which is an odd cases due to the
>> refcoutning/locking and configfs use.
>>
>> For non removal commands we need to do a target_undepend_item. For
>> remove, we don't want to since we came through configfs and teardown
>> already started.
>>
>> So instead of the above lines take:
>>
>> if (nl_cmd->cmd != completed_cmd) {
>> printk(KERN_ERR "Mismatched commands (Expecting reply
>> for %d. Current %d).\n",
>> completed_cmd, nl_cmd->cmd);
>> ret = -EINVAL;
>> } else {
>> nl_cmd->status = rc;
>> }
>>
>> // Note: I changed this from the is_removed
>> if (completed_cmd != TCMU_CMD_REMOVED_DEVICE)
>> target_undepend_item(&dev->dev_group.cg_item);
>> if (!ret) {
>> nl_cmd->complete = true;
>> wake_up(&udev->complete_wq);
>> }
>>
> Sorry, this part I couldn't totally understand.
>
> Do you mean take the code above you pasted by introducing
> target_undepend_item() for none removal paths just like in
> tcmu_genl_cmd_done() does?
> While in tcmu_genl_cmd_done(), the target_depend_item() is called by
> target_find_device() and then it should do target_undepend_item() after
> that, but in
> reset_netlink_store(), should it need target_undepend_item() ? If so
> they won't be in pairs.
>
Yes, you are right. I thought we took a count when we sent the nl cmd.
> I think we should only take this part:
>
> if (nl_cmd->cmd != completed_cmd) {
> printk(KERN_ERR "Mismatched commands (Expecting reply
> for %d. Current %d).\n",
> completed_cmd, nl_cmd->cmd);
> ret = -EINVAL;
> } else {
> nl_cmd->status = rc;
> }
>
> from the tcmu_genl_cmd_done(), right ?
>
We want the complete and wake up part too right?
>> nl_cmd->complete = true;
>> wake_up(&udev->complete_wq);
> Thanks,
> BRs
>
>
>> from tcmu_genl_cmd_done and make a function that takes the status code
>> and completed_cmd. You would just then do
>>
>> __tcmu_genl_cmd_done(&udev->curr_nl_cmd.cmd, -EINTR);
>>
>>
>>
>>
>>> + spin_unlock(&udev->nl_cmd_lock);
>>> +
>>> + return count;
>>> +}
>>> +CONFIGFS_ATTR_WO(tcmu_, reset_netlink);
>>> +
>>> static ssize_t tcmu_reset_ring_store(struct config_item *item,
>>> const char *page,
>>> size_t count)
>>> {
>>> @@ -2363,6 +2400,7 @@ static ssize_t tcmu_reset_ring_store(struct
>>> config_item *item, const char *page,
>>> static struct configfs_attribute *tcmu_action_attrs[] = {
>>> &tcmu_attr_block_dev,
>>> &tcmu_attr_reset_ring,
>>> + &tcmu_attr_reset_netlink,
>>> NULL,
>>> };
>>>
>