]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
adding des code
authorAlex Markuze <amarkuze@redhat.com>
Mon, 7 Apr 2025 11:49:37 +0000 (11:49 +0000)
committerAlex Markuze <amarkuze@redhat.com>
Mon, 7 Apr 2025 11:50:01 +0000 (11:50 +0000)
include/linux/ceph/ceph_san_des.h [new file with mode: 0644]
include/linux/ceph/ceph_san_logger.h
net/ceph/Makefile
net/ceph/ceph_san_des.c [new file with mode: 0644]

diff --git a/include/linux/ceph/ceph_san_des.h b/include/linux/ceph/ceph_san_des.h
new file mode 100644 (file)
index 0000000..eb9d759
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef CEPH_SAN_DES_H
+#define CEPH_SAN_DES_H
+
+#include <linux/types.h> /* For size_t */
+
+/**
+ * Reconstructs a formatted string from a buffer containing serialized values.
+ * The function uses the format string to determine the types and number of values
+ * to extract from the buffer.
+ *
+ * @param fmt Format string containing % specifiers
+ * @param buffer Buffer containing serialized values
+ * @param nr_args Number of arguments to process
+ * @param size Size of the buffer in bytes
+ * @param out Buffer to store the reconstructed string
+ * @param out_size Size of the output buffer
+ * @return Number of bytes written to out buffer, or -1 on error
+ */
+int ceph_san_des_reconstruct(const char *fmt, const void *buffer, size_t nr_args,
+                           size_t size, char *out, size_t out_size);
+
+#endif /* CEPH_SAN_DES_H */
index 957805fabd7cf3049bce2bc2f3160accf651d94c..0b377119abb9f8ba14d2b99c91751d67b67df4f9 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/ceph/ceph_san_batch.h>
 #include <linux/ceph/ceph_san_pagefrag.h>
 #include <linux/ceph/ceph_san_ser.h>
+#include <linux/ceph/ceph_san_des.h>
 
 /* Maximum length of a log entry buffer */
 #define CEPH_SAN_LOG_MAX_LEN 256
index c0766fd8b2cd209e3aef9e0f2545211a3396bd0e..be61857dafcb437b15a814e97d6eee5253de051a 100644 (file)
@@ -10,7 +10,7 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
        osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
        striper.o \
        debugfs.o \
-       ceph_san_pagefrag.o ceph_san_batch.o  ceph_san_logger.o \
+       ceph_san_pagefrag.o ceph_san_batch.o  ceph_san_logger.o ceph_san_des.o \
        auth.o auth_none.o \
        crypto.o armor.o \
        auth_x.o \
diff --git a/net/ceph/ceph_san_des.c b/net/ceph/ceph_san_des.c
new file mode 100644 (file)
index 0000000..b37ae7c
--- /dev/null
@@ -0,0 +1,162 @@
+#include <linux/ceph/ceph_san_des.h>
+#include <linux/string.h>   /* For strchr, strlen */
+#include <linux/ctype.h>    /* For isdigit */
+#include <linux/types.h>    /* For size_t */
+#include <linux/kernel.h>   /* For snprintf */
+
+static int parse_format_specifier(const char **fmt, char *spec) {
+    const char *p = *fmt;
+    char *s = spec;
+
+    /* Skip the '%' */
+    if (*p != '%') return -1;
+    *s++ = *p++;
+
+    /* Skip flags */
+    while (*p && (*p == '-' || *p == '+' || *p == ' ' || *p == '#' || *p == '0')) {
+        *s++ = *p++;
+    }
+
+    /* Skip field width */
+    while (*p && isdigit(*p)) {
+        *s++ = *p++;
+    }
+
+    /* Skip precision */
+    if (*p == '.') {
+        *s++ = *p++;
+        while (*p && isdigit(*p)) {
+            *s++ = *p++;
+        }
+    }
+
+    /* Get length modifier */
+    if (*p == 'h' || *p == 'l' || *p == 'L' || *p == 'j' || *p == 'z' || *p == 't') {
+        *s++ = *p++;
+        if ((*p == 'h' || *p == 'l') && *(p-1) == *p) {
+            *s++ = *p++;
+        }
+    }
+
+    /* Get conversion specifier */
+    if (*p && strchr("diouxXeEfFgGaAcspn%", *p)) {
+        *s++ = *p++;
+    } else {
+        return -1;
+    }
+
+    *s = '\0';
+    *fmt = p;
+    return 0;
+}
+
+int ceph_san_des_reconstruct(const char *fmt, const void *buffer, size_t nr_args,
+                           size_t size, char *out, size_t out_size) {
+    const unsigned char *buf = buffer;
+    const char *p = fmt;
+    char spec[32];
+    size_t offset = 0;
+    size_t out_offset = 0;
+    size_t arg_count = 0;
+
+    if (!fmt || !buffer || !out || !out_size) {
+        return -1;
+    }
+    //printf("Starting reconstruction with buffer at %p, size %zu, nr_args %zu, out_size %zu\n",
+    //       buffer, size, nr_args, out_size);
+    while (*p && out_offset < out_size - 1) {
+        if (*p != '%') {
+            out[out_offset++] = *p++;
+            continue;
+        }
+
+        if (parse_format_specifier(&p, spec) < 0) {
+            return -1;
+        }
+
+        if (arg_count >= nr_args) {
+            return -1;
+        }
+
+        /* Check buffer overflow */
+        if (offset >= size) {
+            return -1;
+        }
+
+        //printf("Processing specifier '%s' at offset %zu\n", spec, offset);
+
+        /* Handle different format specifiers */
+        switch (spec[strlen(spec)-1]) {
+            case 'd':
+            case 'i':
+            case 'o':
+            case 'u':
+            case 'x':
+            case 'X': {
+                long long val;
+                const void *ptr = buf + offset;
+                if (strchr(spec, 'l')) {
+                    val = *(const long long*)ptr;
+                    offset += sizeof(long long);
+                } else {
+                    val = *(const int*)ptr;
+                    offset += sizeof(int);
+                }
+                //printf("Read integer value: %lld at address %p (offset %zu)\n", val, ptr, offset);
+                out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val);
+                break;
+            }
+
+            case 'f':
+            case 'e':
+            case 'E':
+            case 'g':
+            case 'G':
+            case 'a':
+            case 'A': {
+                double val = *(const double*)(buf + offset);
+                offset += sizeof(double);
+                //printf("Read double value: %f at offset %zu\n", val, offset - sizeof(double));
+                out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val);
+                break;
+            }
+
+            case 'c': {
+                char val = *(const char*)(buf + offset);
+                offset += sizeof(char);
+                //printf("Read char value: %c at offset %zu\n", val, offset - sizeof(char));
+                out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val);
+                break;
+            }
+
+            case 's': {
+                const char *val = *(const char**)(buf + offset);
+                offset += sizeof(const char*);
+                //printf("Read string pointer: %p at offset %zu\n", val, offset - sizeof(const char*));
+                out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val);
+                break;
+            }
+
+            case 'p': {
+                const void *val = *(const void**)(buf + offset);
+                offset += sizeof(const void*);
+                //printf("Read pointer value: %p at offset %zu\n", val, offset - sizeof(const void*));
+                out_offset += snprintf(out + out_offset, out_size - out_offset, spec, val);
+                break;
+            }
+
+            case '%': {
+                out[out_offset++] = '%';
+                break;
+            }
+
+            default:
+                return -1;
+        }
+
+        arg_count++;
+    }
+
+    out[out_offset] = '\0';
+    return out_offset;
+}