On Wed, 2021-06-09 at 11:06 +0800, Jingqi Liu wrote:
> The following bug is caused by setting the size of Label Index Block
> to a fixed 256 bytes.
> 
> Use the following Qemu command to start a Guest with 2MB label-size:
>       -object 
> memory-backend-file,id=mem1,share=on,mem-path=/dev/dax1.1,size=14G,align=2M
>       -device nvdimm,memdev=mem1,id=nv1,label-size=2M
> 
> There is a namespace in the Guest as follows:
>       $ ndctl list
>       [
>         {
>           "dev":"namespace0.0",
>           "mode":"devdax",
>           "map":"dev",
>           "size":14780727296,
>           "uuid":"58ad5282-5a16-404f-b8ee-e28b4c784eb8",
>           "chardev":"dax0.0",
>           "align":2097152,
>           "name":"namespace0.0"
>         }
>       ]
> 
> Fail to read labels. The result is as follows:
>       $ ndctl read-labels -u nmem0
>       [
>       ]
>       read 0 nmem
> 
> If using the following Qemu command to start the Guest with 128K
> label-size, this label can be read correctly.
>       -object 
> memory-backend-file,id=mem1,share=on,mem-path=/dev/dax1.1,size=14G,align=2M
>       -device nvdimm,memdev=mem1,id=nv1,label-size=128K
> 
> The size of a Label Index Block depends on how many label slots fit into
> the label storage area. The minimum size of an index block is 256 bytes
> and the size must be a multiple of 256 bytes. For a storage area of 128KB,
> the corresponding Label Index Block size is 256 bytes. But if the label
> storage area is not 128KB, the Label Index Block size should not be 256 bytes.
> 
> Namespace Label Index Block appears twice at the top of the label storage 
> area.
> Following the two index blocks, an array for storing labels takes up the
> remainder of the label storage area.
> 
> For obtaining the size of Namespace Index Block, we also cannot rely on
> the field of 'mysize' in this index block since it might be corrupted.
> Similar to the linux kernel, we use sizeof_namespace_index() to get the size
> of Namespace Index Block. Then we can also correctly calculate the starting
> offset of the following namespace labels.
> 
> Suggested-by: Dan Williams <[email protected]>
> Signed-off-by: Jingqi Liu <[email protected]>
> ---
>  ndctl/dimm.c           | 19 +++++++++++++++----
>  ndctl/lib/dimm.c       |  5 +++++
>  ndctl/lib/libndctl.sym |  1 +
>  ndctl/libndctl.h       |  1 +
>  4 files changed, 22 insertions(+), 4 deletions(-)

Hi Jingqi,

This looks fine, one comment below.

[..]
> 
> diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
> index 0a82616..0ce2bb9 100644
> --- a/ndctl/lib/libndctl.sym
> +++ b/ndctl/lib/libndctl.sym
> @@ -290,6 +290,7 @@ global:
>       ndctl_dimm_validate_labels;
>       ndctl_dimm_init_labels;
>       ndctl_dimm_sizeof_namespace_label;
> +     ndctl_dimm_sizeof_namespace_index;

This can't go into an 'old' section of the symbol version script - if
you base off the current 'pending' branch, you should see a LIBNDCTL_26
section at the bottom. You can add this there.

>       ndctl_mapping_get_position;
>       ndctl_namespace_set_enforce_mode;
>       ndctl_namespace_get_enforce_mode;
> diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
> index 60e1288..9a1a799 100644
> --- a/ndctl/libndctl.h
> +++ b/ndctl/libndctl.h
> @@ -335,6 +335,7 @@ int ndctl_dimm_init_labels(struct ndctl_dimm *dimm,
>               enum ndctl_namespace_version v);
>  unsigned long ndctl_dimm_get_available_labels(struct ndctl_dimm *dimm);
>  unsigned int ndctl_dimm_sizeof_namespace_label(struct ndctl_dimm *dimm);
> +unsigned int ndctl_dimm_sizeof_namespace_index(struct ndctl_dimm *dimm);
>  unsigned int ndctl_cmd_cfg_size_get_size(struct ndctl_cmd *cfg_size);
>  ssize_t ndctl_cmd_cfg_read_get_data(struct ndctl_cmd *cfg_read, void *buf,
>               unsigned int len, unsigned int offset);

Reply via email to