On 05/29/2018 10:24 AM, Christoph Hellwig wrote:
> On Tue, May 29, 2018 at 04:59:05PM +0000, Verkamp, Daniel wrote:
>>> +   } else if (ctrl->nr_changed_ns == NVME_MAX_CHANGED_NAMESPACES) {
>>> +           ctrl->changed_ns_list[0] = cpu_to_le32(0xffffffff);
>>> +   }
>>
>> Unless I'm missing it happening somewhere else, the list-full case that sets 
>> element 0 to 0xffffffff should also explicitly zero out the rest of the list 
>> to satisfy the "remainder of the list shall be zero-filled" wording in the 
>> spec, since the other changed_ns_list entries will be filled with non-zero 
>> NSIDs when we get here.
> 
> True.  We actually zero out unused elements already, but that doesn't
> catch the ctrl->nr_changed_ns == NVME_MAX_CHANGED_NAMESPACES special
> case.  This relative patch should fix it:
> 
> diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
> index d7b6293e830b..7b69c348d608 100644
> --- a/drivers/nvme/target/admin-cmd.c
> +++ b/drivers/nvme/target/admin-cmd.c
> @@ -136,7 +136,10 @@ static void nvmet_execute_get_log_changed_ns(struct 
> nvmet_req *req)
>               goto out;
>  
>       mutex_lock(&ctrl->lock);
> -     len = ctrl->nr_changed_ns * sizeof(__le32);
> +     if (ctrl->nr_changed_ns == NVME_MAX_CHANGED_NAMESPACES)
> +             len = sizeof(__le32);
> +     else
> +             len = ctrl->nr_changed_ns * sizeof(__le32);
>       status = nvmet_copy_to_sgl(req, 0, ctrl->changed_ns_list, len);
>       if (!status)
>               status = nvmet_zero_sgl(req, len, req->data_len - len);
> 

I'm not sure that's quite right; if nr_changed_ns == 
NVME_MAX_CHANGED_NAMESPACES but we haven't overflowed (in other words, the list 
has exactly NVME_MAX_CHANGED_NAMESPACES NSIDs), this will still only copy over 
the first entry.

I think it needs a:
        && ctrlr->changed_ns_list[0] == cpu_to_le32(0xffffffff)
in the NVME_MAX_CHANGED_NAMESPACES condition to make it fully correct.

Thanks,
-- Daniel

Reply via email to