This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 1063e8201b1b89c6ee19945e9479055957b421be
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Mon Aug 5 15:23:08 2024 +0200

    sys/log: Add support for walking back in log
    
    This adds field to log_offset that allows to specify log
    walk back direction.
    
    For now only log_fcb/fcb use implement walking back.
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 sys/log/full/include/log/log.h |  2 ++
 sys/log/full/src/log_fcb.c     | 35 +++++++++++++++++++++++++----------
 sys/log/full/src/log_shell.c   | 12 +++++++++++-
 3 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/sys/log/full/include/log/log.h b/sys/log/full/include/log/log.h
index 7e874ceb0..d04a191eb 100644
--- a/sys/log/full/include/log/log.h
+++ b/sys/log/full/include/log/log.h
@@ -60,6 +60,8 @@ struct log_offset {
 
     /* Specific to walk / read function. */
     void *lo_arg;
+
+    bool lo_walk_backward;
 };
 
 #if MYNEWT_VAL(LOG_STORAGE_INFO)
diff --git a/sys/log/full/src/log_fcb.c b/sys/log/full/src/log_fcb.c
index 82bd1a415..5ed640820 100644
--- a/sys/log/full/src/log_fcb.c
+++ b/sys/log/full/src/log_fcb.c
@@ -135,6 +135,9 @@ log_fcb_find_gte(struct log *log, struct log_offset 
*log_offset,
 
     /* Attempt to read the first entry.  If this fails, the FCB is empty. */
     memset(out_entry, 0, sizeof *out_entry);
+    if (log_offset->lo_ts < 0) {
+        out_entry->fe_step_back = true;
+    }
     rc = fcb_getnext(fcb, out_entry);
     if (rc == FCB_ERR_NOVAR) {
         return SYS_ENOENT;
@@ -146,7 +149,7 @@ log_fcb_find_gte(struct log *log, struct log_offset 
*log_offset,
      * if timestamp for request is < 0, return last log entry
      */
     if (log_offset->lo_ts < 0) {
-        *out_entry = fcb->f_active;
+        out_entry->fe_step_back = false;
         return 0;
     }
 
@@ -348,7 +351,7 @@ log_fcb_append_body(struct log *log, const struct 
log_entry_hdr *hdr,
     }
     memcpy(buf + hdr_len, u8p, hdr_alignment);
 
-    rc = flash_area_write(loc.fe_area, loc.fe_data_off, buf, chunk_sz);
+    rc = fcb_write(fcb, &loc, buf, chunk_sz);
     if (rc != 0) {
         return rc;
     }
@@ -359,8 +362,7 @@ log_fcb_append_body(struct log *log, const struct 
log_entry_hdr *hdr,
     body_len -= hdr_alignment;
 
     if (body_len > 0) {
-        rc = flash_area_write(loc.fe_area, loc.fe_data_off + chunk_sz, u8p,
-                              body_len);
+        rc = fcb_write(fcb, &loc, u8p, body_len);
         if (rc != 0) {
             return rc;
         }
@@ -578,6 +580,7 @@ log_fcb_walk_impl(struct log *log, log_walk_func_t 
walk_func,
     struct fcb_entry loc;
     struct flash_area *fap;
     int rc;
+    struct fcb_entry_cache cache;
 
     fcb_log = log->l_arg;
     fcb = &fcb_log->fl_fcb;
@@ -596,6 +599,14 @@ log_fcb_walk_impl(struct log *log, log_walk_func_t 
walk_func,
     }
     fap = loc.fe_area;
 
+    if (log_offset->lo_walk_backward) {
+        loc.fe_step_back = true;
+        if (MYNEWT_VAL(FCB_BIDIRECTIONAL_CACHE)) {
+            fcb_cache_init(fcb, &cache, 50);
+            loc.fe_cache = &cache;
+        }
+    }
+
 #if MYNEWT_VAL(LOG_FCB_BOOKMARKS)
     /* If a minimum index was specified (i.e., we are not just retrieving the
      * last entry), add a bookmark pointing to this walk's start location.
@@ -605,24 +616,28 @@ log_fcb_walk_impl(struct log *log, log_walk_func_t 
walk_func,
     }
 #endif
 
+    rc = 0;
     do {
         if (area) {
             if (fap != loc.fe_area) {
-                return 0;
+                break;
             }
         }
 
         rc = walk_func(log, log_offset, &loc, loc.fe_data_len);
         if (rc != 0) {
-            if (rc < 0) {
-                return rc;
-            } else {
-                return 0;
+            if (rc > 0) {
+                rc = 0;
             }
+            break;
         }
     } while (fcb_getnext(fcb, &loc) == 0);
 
-    return 0;
+    if (log_offset->lo_walk_backward && MYNEWT_VAL(FCB_BIDIRECTIONAL_CACHE)) {
+        fcb_cache_free(fcb, &cache);
+    }
+
+    return rc;
 }
 
 static int
diff --git a/sys/log/full/src/log_shell.c b/sys/log/full/src/log_shell.c
index e252d33f8..342fb202b 100644
--- a/sys/log/full/src/log_shell.c
+++ b/sys/log/full/src/log_shell.c
@@ -156,6 +156,7 @@ shell_log_dump_cmd(int argc, char **argv)
     bool stream;
     bool partial_match = false;
     bool clear_log;
+    bool reverse = false;
     bool dump_logs = true;
     struct walk_arg arg = {};
     int i;
@@ -193,6 +194,10 @@ shell_log_dump_cmd(int argc, char **argv)
             dump_logs = false;
             continue;
         }
+        if (0 == strcmp(argv[i], "-r")) {
+            reverse = true;
+            continue;
+        }
 
         /* the -c option is to clear a log (or logs). */
         if (!strcmp(argv[i], "-c")) {
@@ -243,7 +248,12 @@ shell_log_dump_cmd(int argc, char **argv)
                 console_printf("Dumping log %s\n", log->l_name);
             }
 
-            log_offset.lo_ts = 0;
+            if (reverse) {
+                log_offset.lo_ts = -1;
+                log_offset.lo_walk_backward = true;
+            } else {
+                log_offset.lo_ts = 0;
+            }
             log_last_index = log_get_last_index(log);
             if (log_limit == 0 || log_last_index < log_limit) {
                 log_offset.lo_index = 0;

Reply via email to