Summary
The OCP SMART / Health Information extended log (C0) JSON printer json_smart_extended_log_v2() is missing the case 6: field block that both the plain-text printer and the legacy JSON v1 printer emit. As a result, for drives reporting a C0 log_page_version >= 6, the fields form factor, die in use bad NAND block (raw) and die in use bad NAND block (normalized) are silently absent from the default -o json output while they are present in the default text output.
Static-analysis finding against current master; not executed here.
Location
- File:
plugins/ocp/ocp-print-json.c
- Function:
json_smart_extended_log_v2() - the version-gating switch (smart_log_ver) around lines 471-475 goes straight from default: into case 5: with no case 6: section.
- Reference implementations that do print the block:
plugins/ocp/ocp-print-stdout.c, stdout_smart_extended_log(), case 6: at ~lines 181-187 (Form factor, Die in use badnandblock-Raw, Die in use badnandblock-Normal)
plugins/ocp/ocp-print-json.c, json_smart_extended_log_v1(), which contains the equivalent default: case 6: block (~lines 300-311)
- Field definitions:
plugins/ocp/ocp-smart-extended-log.h (form_factor [223], die_in_use_bad_nand_block_raw[6] [363:358], die_in_use_bad_nand_block_normalized [365:364])
Problem
ocp_smart_add_log() passes nvme_args.output_format_ver (default = 2, see src/args.c) to ocp_smart_extended_log(), so JSON output normally goes through json_smart_extended_log_v2(). Inside that function the per-field gating switch is:
switch (smart_log_ver) {
case 0 ... 1:
break;
default:
case 5:
/* pcie errata, media dies, power ... */
fallthrough;
...
There is no case 6: arm and no code anywhere else in the function that emits form_factor or either die_in_use_bad_nand_block_* value. The other two printers gate exactly these three fields behind case 6: (i.e. printed when the drive reports log page version >= 6), so v2 JSON diverges from them.
Trigger / Reproduction
Based on static analysis:
nvme ocp smart-add-log /dev/nvme0 # text: prints Form factor + Die in use badnandblock
nvme ocp smart-add-log /dev/nvme0 -o json # json v2 (default): the three keys are missing entirely
on a drive whose C0 log page reports log_page_version >= 6.
Expected Behavior
All three output paths (text, JSON v1, JSON v2) should expose the same spec-defined fields, subject to the same log_page_version gating. For version >= 6, JSON v2 should contain e.g. "form_factor", "die_in_use_bad_nand_block_raw" and "die_in_use_bad_nand_block_normalized".
Actual Behavior
JSON v2 output never contains those three keys, regardless of the drive's log page version, because no case 6: block exists in json_smart_extended_log_v2().
Impact
Scripts and monitoring systems consuming the default JSON output lose data that the human-readable output shows. The inconsistency is easy to miss because the legacy JSON v1 path (selected via an explicit older --output-format-version) still emits the fields under different key names ("Form factor", "Die use badnandblock raw", "Die use badnandblock normal").
Suggested Direction
Add the missing default:/case 6: section to json_smart_extended_log_v2(), mirroring stdout_smart_extended_log(): emit form_factor, int48_to_long(log->die_in_use_bad_nand_block_raw) and le16_to_cpu(log->die_in_use_bad_nand_block_normalized) ahead of the existing case 5: block, using snake_case keys consistent with the rest of v2.
Evidence
plugins/ocp/ocp-print-json.c lines ~471-475: switch (smart_log_ver) in v2 jumps from default: directly to case 5:; grep confirms form_factor / die_in_use appear only inside json_smart_extended_log_v1() in this file.
plugins/ocp/ocp-print-stdout.c ~line 181: case 6: prints the same three fields before falling through to case 5:.
src/args.c: .output_format_ver = 2 is the default, making v2 the common path.
Summary
The OCP SMART / Health Information extended log (C0) JSON printer
json_smart_extended_log_v2()is missing thecase 6:field block that both the plain-text printer and the legacy JSON v1 printer emit. As a result, for drives reporting a C0log_page_version >= 6, the fields form factor, die in use bad NAND block (raw) and die in use bad NAND block (normalized) are silently absent from the default-o jsonoutput while they are present in the default text output.Static-analysis finding against current
master; not executed here.Location
plugins/ocp/ocp-print-json.cjson_smart_extended_log_v2()- the version-gatingswitch (smart_log_ver)around lines 471-475 goes straight fromdefault:intocase 5:with nocase 6:section.plugins/ocp/ocp-print-stdout.c,stdout_smart_extended_log(),case 6:at ~lines 181-187 (Form factor,Die in use badnandblock-Raw,Die in use badnandblock-Normal)plugins/ocp/ocp-print-json.c,json_smart_extended_log_v1(), which contains the equivalentdefault: case 6:block (~lines 300-311)plugins/ocp/ocp-smart-extended-log.h(form_factor[223],die_in_use_bad_nand_block_raw[6][363:358],die_in_use_bad_nand_block_normalized[365:364])Problem
ocp_smart_add_log()passesnvme_args.output_format_ver(default = 2, seesrc/args.c) toocp_smart_extended_log(), so JSON output normally goes throughjson_smart_extended_log_v2(). Inside that function the per-field gating switch is:There is no
case 6:arm and no code anywhere else in the function that emitsform_factoror eitherdie_in_use_bad_nand_block_*value. The other two printers gate exactly these three fields behindcase 6:(i.e. printed when the drive reports log page version >= 6), so v2 JSON diverges from them.Trigger / Reproduction
Based on static analysis:
on a drive whose C0 log page reports
log_page_version >= 6.Expected Behavior
All three output paths (text, JSON v1, JSON v2) should expose the same spec-defined fields, subject to the same
log_page_versiongating. For version >= 6, JSON v2 should contain e.g."form_factor","die_in_use_bad_nand_block_raw"and"die_in_use_bad_nand_block_normalized".Actual Behavior
JSON v2 output never contains those three keys, regardless of the drive's log page version, because no
case 6:block exists injson_smart_extended_log_v2().Impact
Scripts and monitoring systems consuming the default JSON output lose data that the human-readable output shows. The inconsistency is easy to miss because the legacy JSON v1 path (selected via an explicit older
--output-format-version) still emits the fields under different key names ("Form factor", "Die use badnandblock raw", "Die use badnandblock normal").Suggested Direction
Add the missing
default:/case 6:section tojson_smart_extended_log_v2(), mirroringstdout_smart_extended_log(): emitform_factor,int48_to_long(log->die_in_use_bad_nand_block_raw)andle16_to_cpu(log->die_in_use_bad_nand_block_normalized)ahead of the existingcase 5:block, using snake_case keys consistent with the rest of v2.Evidence
plugins/ocp/ocp-print-json.clines ~471-475:switch (smart_log_ver)in v2 jumps fromdefault:directly tocase 5:; grep confirmsform_factor/die_in_useappear only insidejson_smart_extended_log_v1()in this file.plugins/ocp/ocp-print-stdout.c~line 181:case 6:prints the same three fields before falling through tocase 5:.src/args.c:.output_format_ver = 2is the default, making v2 the common path.