131 lines
4.0 KiB
Diff
131 lines
4.0 KiB
Diff
From 78dc9788be1a9296340f66b3168a6fd48dbf31b1 Mon Sep 17 00:00:00 2001
|
||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||
Date: Thu, 26 Mar 2026 12:42:32 +0100
|
||
Subject: [PATCH 123/211] libdm: report: fix row sorting for string list fields
|
||
(continued)
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
(extending commit 424e995f6daeb56eeccec4b3d54d151d4e259040)
|
||
|
||
_row_compare was treating the sort_value of DM_REPORT_FIELD_TYPE_STRING_LIST
|
||
fields as plain char pointer, but it was actually a pointer to
|
||
struct str_list_sort_value. This caused incorrect sorting of these fields.
|
||
|
||
Also add an internal error report if a field type is not handled
|
||
for sorting, so we notice if a new type is added without a sorting
|
||
handler.
|
||
|
||
For example, before this patch:
|
||
|
||
❯ lvs -o lv_name,lv_layout -O lv_layout vg
|
||
lv_name lv_layout
|
||
lvol5 raid,raid1
|
||
lvol4 thin,sparse
|
||
lvol3 thin,sparse
|
||
lvol2 thin,sparse
|
||
lvol0 raid,raid1
|
||
pool thin,pool
|
||
|
||
With this patch applied:
|
||
|
||
❯ lvs -o lv_name,lv_layout -O lv_layout vg
|
||
lv_name lv_layout
|
||
lvol0 raid,raid1
|
||
lvol5 raid,raid1
|
||
pool thin,pool
|
||
lvol2 thin,sparse
|
||
lvol3 thin,sparse
|
||
lvol4 thin,sparse
|
||
|
||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||
(cherry picked from commit fabee343f79327bcfd9ca653bfcd4af4c03ad693)
|
||
---
|
||
libdm/libdm-report.c | 52 ++++++++++++++++++++------------------------
|
||
1 file changed, 24 insertions(+), 28 deletions(-)
|
||
|
||
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
|
||
index 13bc9a1e5..a92f96720 100644
|
||
--- a/libdm/libdm-report.c
|
||
+++ b/libdm/libdm-report.c
|
||
@@ -4618,10 +4618,12 @@ static int _row_compare(const void *a, const void *b)
|
||
const struct row *rowb = *(const struct row * const *) b;
|
||
const struct dm_report_field *sfa, *sfb;
|
||
uint32_t cnt;
|
||
+ int cmp;
|
||
|
||
for (cnt = 0; cnt < rowa->rh->keys_count; cnt++) {
|
||
sfa = (*rowa->sort_fields)[cnt];
|
||
sfb = (*rowb->sort_fields)[cnt];
|
||
+
|
||
if (sfa->props->flags &
|
||
(DM_REPORT_FIELD_TYPE_NUMBER |
|
||
DM_REPORT_FIELD_TYPE_SIZE |
|
||
@@ -4632,40 +4634,34 @@ static int _row_compare(const void *a, const void *b)
|
||
const uint64_t numb =
|
||
*(const uint64_t *) sfb->sort_value;
|
||
|
||
- if (numa == numb)
|
||
- continue;
|
||
+ cmp = (numa == numb) ? 0 : (numa > numb) ? 1 : -1;
|
||
+ } else if (sfa->props->flags &
|
||
+ (DM_REPORT_FIELD_TYPE_STRING |
|
||
+ DM_REPORT_FIELD_TYPE_STRING_LIST)) {
|
||
+ const char *stra, *strb;
|
||
|
||
- if (sfa->props->flags & FLD_ASCENDING) {
|
||
- return (numa > numb) ? 1 : -1;
|
||
- } else { /* FLD_DESCENDING */
|
||
- return (numa < numb) ? 1 : -1;
|
||
+ if (sfa->props->flags & DM_REPORT_FIELD_TYPE_STRING_LIST) {
|
||
+ stra = ((const struct str_list_sort_value *) sfa->sort_value)->value;
|
||
+ strb = ((const struct str_list_sort_value *) sfb->sort_value)->value;
|
||
+ } else {
|
||
+ stra = (const char *) sfa->sort_value;
|
||
+ strb = (const char *) sfb->sort_value;
|
||
}
|
||
- } else if (sfa->props->flags & DM_REPORT_FIELD_TYPE_STRING_LIST) {
|
||
- int cmp = strcmp(((const struct str_list_sort_value *) sfa->sort_value)->value,
|
||
- ((const struct str_list_sort_value *) sfb->sort_value)->value);
|
||
|
||
- if (!cmp)
|
||
- continue;
|
||
-
|
||
- if (sfa->props->flags & FLD_ASCENDING) {
|
||
- return (cmp > 0) ? 1 : -1;
|
||
- } else { /* FLD_DESCENDING */
|
||
- return (cmp < 0) ? 1 : -1;
|
||
- }
|
||
+ cmp = strcmp(stra, strb);
|
||
} else {
|
||
- /* DM_REPORT_FIELD_TYPE_STRING and others */
|
||
- int cmp = strcmp((const char *) sfa->sort_value,
|
||
- (const char *) sfb->sort_value);
|
||
+ log_err_once(INTERNAL_ERROR "_row_compare: unhandled field type: %#x",
|
||
+ sfa->props->flags & DM_REPORT_FIELD_TYPE_MASK);
|
||
+ return 0;
|
||
+ }
|
||
|
||
- if (!cmp)
|
||
- continue;
|
||
+ if (!cmp)
|
||
+ continue;
|
||
|
||
- if (sfa->props->flags & FLD_ASCENDING) {
|
||
- return (cmp > 0) ? 1 : -1;
|
||
- } else { /* FLD_DESCENDING */
|
||
- return (cmp < 0) ? 1 : -1;
|
||
- }
|
||
- }
|
||
+ if (sfa->props->flags & FLD_ASCENDING)
|
||
+ return (cmp > 0) ? 1 : -1;
|
||
+ else /* FLD_DESCENDING */
|
||
+ return (cmp < 0) ? 1 : -1;
|
||
}
|
||
|
||
return 0; /* Identical */
|
||
--
|
||
2.54.0
|
||
|