]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
fsid cache WIP
authorAlex Markuze <amarkuze@redhat.com>
Tue, 15 Apr 2025 14:09:21 +0000 (14:09 +0000)
committerAlex Markuze <amarkuze@redhat.com>
Tue, 15 Apr 2025 14:09:21 +0000 (14:09 +0000)
include/linux/ceph/ceph_debug.h
include/linux/ceph/ceph_san_logger.h
net/ceph/ceph_san_logger.c

index 19d27fb4eaf2b05ddf93296d33356f705413f982..48ebf9e2632e024a3052e832df97adb99d12dbea 100644 (file)
  * or, just wrap pr_debug
  */
 # define dout(fmt, ...)        CEPH_SAN_LOG(fmt, ##__VA_ARGS__)
-# define doutc(__c, fmt, ...) if (__c) { CEPH_SAN_LOG(fmt, ##__VA_ARGS__); }
-//# define doutc(client, fmt, ...) \
-//     CEPH_SAN_LOG("[%pU:%llu] " fmt, &client->fsid,                  \
-//              client->monc.auth->global_id, ##__VA_ARGS__)
+# define doutc(client, fmt, ...) CEPH_SAN_LOG_CLIENT(client, fmt, ##__VA_ARGS__)
 
 #endif
 
index cc200c639026078b41ee13808f35bd33accef80e..e7e4fecf71b53fbbd62b7ec2bf81ae587515e850 100644 (file)
 #define CEPH_SAN_LOG_MAX_LEN 256
 #define CEPH_SAN_LOG_ENTRY_POISON 0xDEADBEEF
 #define CEPH_SAN_MAX_SOURCE_IDS 4096
+#define CEPH_SAN_MAX_CLIENT_IDS 1024
+
+/* Client ID cache entry */
+struct ceph_san_client_id {
+    char fsid[16];         /* Client FSID */
+    u64 global_id;         /* Client global ID */
+    u32 idx;              /* Index in the cache */
+};
 
 /* Source information mapping structure */
 struct ceph_san_source_info {
@@ -28,6 +36,7 @@ struct ceph_san_log_entry {
     u64 debug_poison;           /* Debug poison value */
     u64 ts;                     /* Timestamp (jiffies) */
     u32 source_id;              /* ID for source file/function/line */
+    u32 client_id;              /* ID for client (fsid:global_id) */
     unsigned int len;           /* Length of the message */
     char *buffer;               /* Flexible array for inline buffer */
 };
@@ -48,7 +57,10 @@ struct ceph_san_logger {
     struct ceph_san_batch alloc_batch;  /* Batch for allocating new entries */
     struct ceph_san_batch log_batch;    /* Batch for storing log entries */
     struct ceph_san_source_info source_map[CEPH_SAN_MAX_SOURCE_IDS]; /* Source info mapping */
+    struct ceph_san_client_id client_map[CEPH_SAN_MAX_CLIENT_IDS]; /* Client ID mapping */
     atomic_t next_source_id;    /* Next source ID to assign */
+    u32 next_client_id;        /* Next client ID to assign */
+    spinlock_t client_lock;     /* Protects client ID operations */
 };
 
 /* Iterator for log entries in a single pagefrag */
@@ -78,8 +90,14 @@ u32 ceph_san_get_source_id(const char *file, const char *func, unsigned int line
 /* Get source information for ID */
 const struct ceph_san_source_info *ceph_san_get_source_info(u32 id);
 
+/* Check if client ID matches given fsid and global_id, returning the actual ID */
+u32 ceph_san_check_client_id(u32 id, const char *fsid, u64 global_id);
+
+/* Get client information for ID */
+const struct ceph_san_client_id *ceph_san_get_client_info(u32 id);
+
 /* Log a message */
-void* ceph_san_log(u32 source_id, size_t size);
+void* ceph_san_log(u32 source_id, size_t needed_size);
 
 /* Get current TLS context, creating if necessary */
 struct ceph_san_tls_ctx *ceph_san_get_tls_ctx(void);
@@ -100,6 +118,24 @@ struct ceph_san_tls_ctx *ceph_san_get_tls_ctx(void);
        } \
     } while (0)
 
+/* Helper macro for logging with client ID */
+#define CEPH_SAN_LOG_CLIENT(client, fmt, ...) \
+    do { \
+        static u32 __source_id = 0; \
+        static u32 __client_id = 0; \
+        static size_t __size = 0; \
+        void *___buffer = NULL; \
+        if (unlikely(__source_id == 0)) { \
+            __source_id = ceph_san_get_source_id(kbasename(__FILE__), __func__, __LINE__, fmt); \
+            __size = ceph_san_cnt(__VA_ARGS__); \
+        } \
+        __client_id = ceph_san_check_client_id(__client_id, client->fsid.fsid, client->monc.auth->global_id); \
+        ___buffer = ceph_san_log(__source_id, __size); \
+       if (likely(___buffer)) {        \
+               ceph_san_ser(___buffer, ##__VA_ARGS__);\
+       } \
+    } while (0)
+
 /* Global logger instance */
 extern struct ceph_san_logger g_logger;
 
index 46127229cc3244f081f34cd1589fe1abb6d27eda..f2ba6f7c384b5d4718d85d4c5111528a6d8711aa 100644 (file)
@@ -152,6 +152,124 @@ const struct ceph_san_source_info *ceph_san_get_source_info(u32 id)
 }
 EXPORT_SYMBOL(ceph_san_get_source_info);
 
+/**
+ * ceph_san_check_client_id - Check if a client ID matches the given fsid:global_id pair
+ * @id: Client ID to check
+ * @fsid: Client FSID to compare
+ * @global_id: Client global ID to compare
+ *
+ * Returns the actual ID of the pair. If the given ID doesn't match, scans for
+ * existing matches or allocates a new ID if no match is found.
+ */
+u32 ceph_san_check_client_id(u32 id, const char *fsid, u64 global_id)
+{
+    u32 found_id = 0;
+    struct ceph_san_client_id *entry;
+    u32 max_id;
+
+    /* First check if the given ID matches */
+    if (id != 0 && id < CEPH_SAN_MAX_CLIENT_IDS) {
+        entry = &g_logger.client_map[id];
+        if (memcmp(entry->fsid, fsid, sizeof(entry->fsid)) == 0 &&
+            entry->global_id == global_id) {
+            found_id = id;
+            goto out_fast;
+        }
+    }
+
+    spin_lock(&g_logger.client_lock);
+    max_id = g_logger.next_client_id;
+
+    /* Scan for existing match */
+    for (id = 1; id < max_id && id < CEPH_SAN_MAX_CLIENT_IDS; id++) {
+        entry = &g_logger.client_map[id];
+        if (memcmp(entry->fsid, fsid, sizeof(entry->fsid)) == 0 &&
+            entry->global_id == global_id) {
+            found_id = id;
+            goto out;
+        }
+    }
+
+    /* No match found, allocate new ID */
+    found_id = ++g_logger.next_client_id;
+    if (found_id >= CEPH_SAN_MAX_CLIENT_IDS) {
+        /* If we run out of IDs, just use the first one */
+        pr_warn("ceph_san_logger: client ID overflow, reusing ID 1\n");
+        found_id = 1;
+    }
+
+    entry = &g_logger.client_map[found_id];
+    memcpy(entry->fsid, fsid, sizeof(entry->fsid));
+    entry->global_id = global_id;
+    entry->idx = found_id;
+
+out:
+    spin_unlock(&g_logger.client_lock);
+out_fast:
+    return found_id;
+}
+EXPORT_SYMBOL(ceph_san_check_client_id);
+
+/**
+ * ceph_san_get_client_id - Helper function to get or create a client ID
+ * @fsid: Client FSID
+ * @global_id: Client global ID
+ *
+ * Returns a unique ID for this client pair
+ */
+static u32 ceph_san_get_client_id(const char *fsid, u64 global_id)
+{
+    u32 id;
+    struct ceph_san_client_id *entry;
+    bool found = false;
+    u32 max_id;
+
+    spin_lock(&g_logger.client_lock);
+    max_id = g_logger.next_client_id;
+
+    /* First try to find existing entry */
+    for (id = 1; id < max_id && id < CEPH_SAN_MAX_CLIENT_IDS; id++) {
+        entry = &g_logger.client_map[id];
+        if (memcmp(entry->fsid, fsid, sizeof(entry->fsid)) == 0 &&
+            entry->global_id == global_id) {
+            found = true;
+            break;
+        }
+    }
+
+    /* If not found, allocate new ID */
+    if (!found) {
+        id = ++g_logger.next_client_id;
+        if (id >= CEPH_SAN_MAX_CLIENT_IDS) {
+            /* If we run out of IDs, just use the first one */
+            pr_warn("ceph_san_logger: client ID overflow, reusing ID 1\n");
+            id = 1;
+        }
+
+        entry = &g_logger.client_map[id];
+        memcpy(entry->fsid, fsid, sizeof(entry->fsid));
+        entry->global_id = global_id;
+        entry->idx = id;
+    }
+
+    spin_unlock(&g_logger.client_lock);
+    return id;
+}
+
+/**
+ * ceph_san_get_client_info - Get client info for a given ID
+ * @id: Client ID
+ *
+ * Returns the client information for this ID
+ */
+const struct ceph_san_client_id *ceph_san_get_client_info(u32 id)
+{
+    if (id == 0 || id >= CEPH_SAN_MAX_CLIENT_IDS)
+        return NULL;
+    return &g_logger.client_map[id];
+}
+EXPORT_SYMBOL(ceph_san_get_client_info);
+
 /**
  * ceph_san_log - Log a message
  * @source_id: Source ID for this location