/** * vfs_lib_ring_buffer_ioctl - control ring buffer reader synchronization * * @filp: the file * @cmd: the command * @arg: command arg * * This ioctl implements commands necessary for producer/consumer * and flight recorder reader interaction : * RING_BUFFER_GET_NEXT_SUBBUF * Get the next sub-buffer that can be read. It never blocks. * RING_BUFFER_PUT_NEXT_SUBBUF * Release the currently read sub-buffer. * RING_BUFFER_GET_SUBBUF_SIZE * returns the size of the current sub-buffer. * RING_BUFFER_GET_MAX_SUBBUF_SIZE * returns the maximum size for sub-buffers. * RING_BUFFER_GET_NUM_SUBBUF * returns the number of reader-visible sub-buffers in the per cpu * channel (for mmap). * RING_BUFFER_GET_MMAP_READ_OFFSET * returns the offset of the subbuffer belonging to the reader. * Should only be used for mmap clients. */ static long vfs_lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct lib_ring_buffer *buf = filp->private_data; return lib_ring_buffer_ioctl(filp, cmd, arg, buf); }
static long lttng_metadata_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int ret; struct lttng_metadata_stream *stream = filp->private_data; struct lib_ring_buffer *buf = stream->priv; switch (cmd) { case RING_BUFFER_GET_NEXT_SUBBUF: { struct lttng_metadata_stream *stream = filp->private_data; struct lib_ring_buffer *buf = stream->priv; struct channel *chan = buf->backend.chan; ret = lttng_metadata_output_channel(stream, chan); if (ret > 0) { lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); ret = 0; } else if (ret < 0) goto err; break; } case RING_BUFFER_GET_SUBBUF: { /* * Random access is not allowed for metadata channel. */ return -ENOSYS; } case RING_BUFFER_FLUSH: { struct lttng_metadata_stream *stream = filp->private_data; struct lib_ring_buffer *buf = stream->priv; struct channel *chan = buf->backend.chan; /* * Before doing the actual ring buffer flush, write up to one * packet of metadata in the ring buffer. */ ret = lttng_metadata_output_channel(stream, chan); if (ret < 0) goto err; break; } case RING_BUFFER_GET_METADATA_VERSION: { struct lttng_metadata_stream *stream = filp->private_data; return put_u64(stream->version, arg); } default: break; } /* PUT_SUBBUF is the one from lib ring buffer, unmodified. */ /* Performing lib ring buffer ioctl after our own. */ 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; }