Implement ring buffer clear
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 30 May 2018 00:11:43 +0000 (02:11 +0200)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 26 Mar 2019 15:15:56 +0000 (11:15 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/ringbuffer/frontend_internal.h
lib/ringbuffer/ring_buffer_frontend.c
lib/ringbuffer/ring_buffer_vfs.c
lib/ringbuffer/vfs.h

index f143ecae462df68f2823387962ea27388ed1f603..adda26c7dd6e696482aff056634be9431e975e8b 100644 (file)
@@ -169,6 +169,8 @@ extern
 void lib_ring_buffer_switch_remote(struct lib_ring_buffer *buf);
 extern
 void lib_ring_buffer_switch_remote_empty(struct lib_ring_buffer *buf);
+extern
+void lib_ring_buffer_clear(struct lib_ring_buffer *buf);
 
 /* Buffer write helpers */
 
@@ -200,6 +202,30 @@ void lib_ring_buffer_reserve_push_reader(struct lib_ring_buffer *buf,
                                              consumed_new) != consumed_old));
 }
 
+/*
+ * Move consumed position to the beginning of subbuffer in which the
+ * write offset is.
+ */
+static inline
+void lib_ring_buffer_clear_reader(struct lib_ring_buffer *buf,
+                                 struct channel *chan)
+{
+       const struct lib_ring_buffer_config *config = &chan->backend.config;
+       unsigned long offset, consumed_old, consumed_new;
+
+       do {
+               offset = v_read(config, &buf->offset);
+               consumed_old = atomic_long_read(&buf->consumed);
+               if (unlikely(subbuf_trunc(offset, chan)
+                             - subbuf_trunc(consumed_old, chan)
+                            > 0))
+                       consumed_new = subbuf_trunc(offset, chan);
+               else
+                       return;
+       } while (unlikely(atomic_long_cmpxchg(&buf->consumed, consumed_old,
+                                             consumed_new) != consumed_old));
+}
+
 static inline
 int lib_ring_buffer_pending_data(const struct lib_ring_buffer_config *config,
                                 struct lib_ring_buffer *buf,
index 4a8919b354ea1599ce9299d6b8f184d10d9f8dd9..cd94bbb731b577ba4fb4cf5d243a98a123955200 100644 (file)
@@ -1917,6 +1917,16 @@ void lib_ring_buffer_switch_remote_empty(struct lib_ring_buffer *buf)
 }
 EXPORT_SYMBOL_GPL(lib_ring_buffer_switch_remote_empty);
 
+void lib_ring_buffer_clear(struct lib_ring_buffer *buf)
+{
+       struct lib_ring_buffer_backend *bufb = &buf->backend;
+       struct channel *chan = bufb->chan;
+
+       lib_ring_buffer_switch_remote(buf);
+       lib_ring_buffer_clear_reader(buf, chan);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_clear);
+
 /*
  * Returns :
  * 0 if ok
index 97be835655a8c0f665526f8471aa1030e140b561..8f83c856ffd2e2313811e2dcad851cc77b88d980 100644 (file)
@@ -276,6 +276,9 @@ long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd,
        case RING_BUFFER_FLUSH_EMPTY:
                lib_ring_buffer_switch_remote_empty(buf);
                return 0;
+       case RING_BUFFER_CLEAR:
+               lib_ring_buffer_clear(buf);
+               return 0;
        default:
                return -ENOIOCTLCMD;
        }
@@ -427,6 +430,9 @@ long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd,
        case RING_BUFFER_COMPAT_FLUSH_EMPTY:
                lib_ring_buffer_switch_remote_empty(buf);
                return 0;
+       case RING_BUFFER_COMPAT_CLEAR:
+               lib_ring_buffer_clear(buf);
+               return 0;
        default:
                return -ENOIOCTLCMD;
        }
index b2e5b1c84810a606b4368a84673bc8dca410ccb6..07e51ba2ad3e7a53b3e6586698d3621d3b7a0396 100644 (file)
@@ -123,6 +123,13 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
 #define RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS  _IO(0xF6, 0x0E)
 /* Flush the current sub-buffer, even if empty. */
 #define RING_BUFFER_FLUSH_EMPTY                        _IO(0xF6, 0x0F)
+/*
+ * Reset the position of what has been consumed from the metadata cache to 0
+ * so it can be read again.
+ */
+#define RING_BUFFER_METADATA_CACHE_DUMP                _IO(0xF6, 0x10)
+/* Clear ring buffer content. */
+#define RING_BUFFER_CLEAR                      _IO(0xF6, 0x11)
 
 #ifdef CONFIG_COMPAT
 /* Get a snapshot of the current ring buffer producer and consumer positions */
@@ -167,6 +174,9 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
 /* Flush the current sub-buffer, even if empty. */
 #define RING_BUFFER_COMPAT_FLUSH_EMPTY                 \
        RING_BUFFER_FLUSH_EMPTY
+/* Clear ring buffer content. */
+#define RING_BUFFER_COMPAT_CLEAR                       \
+       RING_BUFFER_CLEAR
 #endif /* CONFIG_COMPAT */
 
 #endif /* _LIB_RING_BUFFER_VFS_H */
This page took 0.038201 seconds and 5 git commands to generate.