+static
+enum get_next_subbuffer_status get_next_subbuffer_mmap(
+ struct lttng_consumer_stream *stream,
+ struct stream_subbuffer *subbuffer)
+{
+ int ret;
+ enum get_next_subbuffer_status status;
+ const char *addr;
+
+ status = get_subbuffer_common(stream, subbuffer);
+ if (status != GET_NEXT_SUBBUFFER_STATUS_OK) {
+ goto end;
+ }
+
+ ret = get_current_subbuf_addr(stream, &addr);
+ if (ret) {
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
+ goto end;
+ }
+
+ subbuffer->buffer.buffer = lttng_buffer_view_init(
+ addr, 0, subbuffer->info.data.padded_subbuf_size);
+end:
+ return status;
+}
+
+static
+enum get_next_subbuffer_status get_next_subbuffer_metadata_check(struct lttng_consumer_stream *stream,
+ struct stream_subbuffer *subbuffer)
+{
+ int ret;
+ const char *addr;
+ bool coherent;
+ enum get_next_subbuffer_status status;
+
+ ret = kernctl_get_next_subbuf_metadata_check(stream->wait_fd,
+ &coherent);
+ if (ret) {
+ goto end;
+ }
+
+ ret = stream->read_subbuffer_ops.extract_subbuffer_info(
+ stream, subbuffer);
+ if (ret) {
+ goto end;
+ }
+
+ LTTNG_OPTIONAL_SET(&subbuffer->info.metadata.coherent, coherent);
+
+ ret = get_current_subbuf_addr(stream, &addr);
+ if (ret) {
+ goto end;
+ }
+
+ subbuffer->buffer.buffer = lttng_buffer_view_init(
+ addr, 0, subbuffer->info.data.padded_subbuf_size);
+ DBG("Got metadata packet with padded_subbuf_size = %lu, coherent = %s",
+ subbuffer->info.metadata.padded_subbuf_size,
+ coherent ? "true" : "false");
+end:
+ /*
+ * The caller only expects -ENODATA when there is no data to read, but
+ * the kernel tracer returns -EAGAIN when there is currently no data
+ * for a non-finalized stream, and -ENODATA when there is no data for a
+ * finalized stream. Those can be combined into a -ENODATA return value.
+ */
+ switch (ret) {
+ case 0:
+ status = GET_NEXT_SUBBUFFER_STATUS_OK;
+ break;
+ case -ENODATA:
+ case -EAGAIN: