mask |= POLLHUP;
if (stream->metadata_cache->metadata_written >
- stream->metadata_cache_read)
+ stream->metadata_out)
mask |= POLLIN;
}
}
static
-int lttng_metadata_ring_buffer_ioctl_get_subbuf(struct file *filp,
+int lttng_metadata_ring_buffer_ioctl_get_next_subbuf(struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct lttng_metadata_stream *stream = filp->private_data;
return ret;
}
+static
+void lttng_metadata_ring_buffer_ioctl_put_next_subbuf(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct lttng_metadata_stream *stream = filp->private_data;
+
+ stream->metadata_out = stream->metadata_in;
+}
+
static
long lttng_metadata_ring_buffer_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg)
struct lib_ring_buffer *buf = stream->priv;
switch (cmd) {
- case RING_BUFFER_GET_SUBBUF:
case RING_BUFFER_GET_NEXT_SUBBUF:
{
- ret = lttng_metadata_ring_buffer_ioctl_get_subbuf(filp,
+ ret = lttng_metadata_ring_buffer_ioctl_get_next_subbuf(filp,
cmd, arg);
if (ret < 0)
goto err;
break;
}
+ case RING_BUFFER_GET_SUBBUF:
+ {
+ /*
+ * Random access is not allowed for metadata channel.
+ */
+ return -ENOSYS;
+ }
default:
break;
}
+ /* PUT_SUBBUF is the one from lib ring buffer, unmodified. */
+
/* Performing lib ring buffer ioctl after our own. */
- return lib_ring_buffer_ioctl(filp, cmd, arg, buf);
+ ret = lib_ring_buffer_ioctl(filp, cmd, arg, buf);
+ if (ret < 0)
+ goto err;
+ switch (cmd) {
+ case RING_BUFFER_PUT_NEXT_SUBBUF:
+ {
+ lttng_metadata_ring_buffer_ioctl_put_next_subbuf(filp,
+ cmd, arg);
+ break;
+ }
+ default:
+ break;
+ }
err:
return ret;
}
struct lib_ring_buffer *buf = stream->priv;
switch (cmd) {
- case RING_BUFFER_GET_SUBBUF:
case RING_BUFFER_GET_NEXT_SUBBUF:
{
- ret = lttng_metadata_ring_buffer_ioctl_get_subbuf(filp,
+ ret = lttng_metadata_ring_buffer_ioctl_get_next_subbuf(filp,
cmd, arg);
if (ret < 0)
goto err;
break;
}
+ case RING_BUFFER_GET_SUBBUF:
+ {
+ /*
+ * Random access is not allowed for metadata channel.
+ */
+ return -ENOSYS;
+ }
default:
break;
}
+ /* PUT_SUBBUF is the one from lib ring buffer, unmodified. */
+
/* Performing lib ring buffer ioctl after our own. */
- return lib_ring_buffer_compat_ioctl(filp, cmd, arg, buf);
+ ret = lib_ring_buffer_compat_ioctl(filp, cmd, arg, buf);
+ if (ret < 0)
+ goto err;
+ switch (cmd) {
+ case RING_BUFFER_PUT_NEXT_SUBBUF:
+ {
+ lttng_metadata_ring_buffer_ioctl_put_next_subbuf(filp,
+ cmd, arg);
+ break;
+ }
+ default:
+ break;
+ }
err:
return ret;
}
int ret = 0;
size_t len, reserve_len;
+ /*
+ * Ensure we support mutiple get_next / put sequences followed
+ * by put_next.
+ */
+ WARN_ON(stream->metadata_in < stream->metadata_out);
+ if (stream->metadata_in != stream->metadata_out)
+ return 0;
+
len = stream->metadata_cache->metadata_written -
- stream->metadata_cache_read;
+ stream->metadata_in;
if (!len)
return 0;
reserve_len = min_t(size_t,
goto end;
}
chan->ops->event_write(&ctx,
- stream->metadata_cache->data + stream->metadata_cache_read,
+ stream->metadata_cache->data + stream->metadata_in,
reserve_len);
chan->ops->event_commit(&ctx);
- stream->metadata_cache_read += reserve_len;
+ stream->metadata_in += reserve_len;
ret = reserve_len;
end:
struct lttng_metadata_stream {
void *priv; /* Ring buffer private data */
struct lttng_metadata_cache *metadata_cache;
- unsigned int metadata_cache_read; /* Bytes read from the cache */
+ unsigned int metadata_in; /* Bytes read from the cache */
+ unsigned int metadata_out; /* Bytes consumed from stream */
int finalized; /* Has channel been finalized */
wait_queue_head_t read_wait; /* Reader buffer-level wait queue */
struct list_head list; /* Stream list */