Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6c08367 authored by Tom Zanussi's avatar Tom Zanussi Committed by Linus Torvalds
Browse files

[PATCH] relayfs: add support for global relay buffers



This patch adds the optional is_global outparam to the create_buf_file()
callback.  This can be used by clients to create a single global relayfs
buffer instead of the default per-cpu buffers.  This was suggested as being
useful for certain debugging applications where it's more convenient to be
able to get all the data from a single channel without having to go to the
bother of dealing with per-cpu files.

Signed-off-by: default avatarTom Zanussi <zanussi@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 03d78d11
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -86,7 +86,8 @@ static void buf_unmapped_default_callback(struct rchan_buf *buf,
static struct dentry *create_buf_file_default_callback(const char *filename,
						       struct dentry *parent,
						       int mode,
						       struct rchan_buf *buf)
						       struct rchan_buf *buf,
						       int *is_global)
{
	return relayfs_create_file(filename, parent, mode,
				   &relayfs_file_operations, buf);
@@ -170,14 +171,16 @@ static inline void __relay_reset(struct rchan_buf *buf, unsigned int init)
void relay_reset(struct rchan *chan)
{
	unsigned int i;
	struct rchan_buf *prev = NULL;

	if (!chan)
		return;

	for (i = 0; i < NR_CPUS; i++) {
		if (!chan->buf[i])
			continue;
		if (!chan->buf[i] || chan->buf[i] == prev)
			break;
		__relay_reset(chan->buf[i], 0);
		prev = chan->buf[i];
	}
}

@@ -188,18 +191,22 @@ void relay_reset(struct rchan *chan)
 */
static struct rchan_buf *relay_open_buf(struct rchan *chan,
					const char *filename,
					struct dentry *parent)
					struct dentry *parent,
					int *is_global)
{
	struct rchan_buf *buf;
	struct dentry *dentry;

	if (*is_global)
		return chan->buf[0];

 	buf = relay_create_buf(chan);
 	if (!buf)
 		return NULL;

	/* Create file in fs */
 	dentry = chan->cb->create_buf_file(filename, parent, S_IRUSR,
 					   buf);
 					   buf, is_global);
 	if (!dentry) {
 		relay_destroy_buf(buf);
		return NULL;
@@ -273,6 +280,7 @@ struct rchan *relay_open(const char *base_filename,
	unsigned int i;
	struct rchan *chan;
	char *tmpname;
	int is_global = 0;

	if (!base_filename)
		return NULL;
@@ -297,7 +305,8 @@ struct rchan *relay_open(const char *base_filename,

	for_each_online_cpu(i) {
		sprintf(tmpname, "%s%d", base_filename, i);
		chan->buf[i] = relay_open_buf(chan, tmpname, parent);
		chan->buf[i] = relay_open_buf(chan, tmpname, parent,
					      &is_global);
		chan->buf[i]->cpu = i;
		if (!chan->buf[i])
			goto free_bufs;
@@ -311,6 +320,8 @@ free_bufs:
		if (!chan->buf[i])
			break;
		relay_close_buf(chan->buf[i]);
		if (is_global)
			break;
	}
	kfree(tmpname);

@@ -420,14 +431,16 @@ void relay_destroy_channel(struct kref *kref)
void relay_close(struct rchan *chan)
{
	unsigned int i;
	struct rchan_buf *prev = NULL;

	if (!chan)
		return;

	for (i = 0; i < NR_CPUS; i++) {
		if (!chan->buf[i])
			continue;
		if (!chan->buf[i] || chan->buf[i] == prev)
			break;
		relay_close_buf(chan->buf[i]);
		prev = chan->buf[i];
	}

	if (chan->last_toobig)
@@ -447,14 +460,16 @@ void relay_close(struct rchan *chan)
void relay_flush(struct rchan *chan)
{
	unsigned int i;
	struct rchan_buf *prev = NULL;

	if (!chan)
		return;

	for (i = 0; i < NR_CPUS; i++) {
		if (!chan->buf[i])
			continue;
		if (!chan->buf[i] || chan->buf[i] == prev)
			break;
		relay_switch_subbuf(chan->buf[i], 0);
		prev = chan->buf[i];
	}
}

+7 −1
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ struct rchan_callbacks
	 * @parent: the parent of the file to create
	 * @mode: the mode of the file to create
	 * @buf: the channel buffer
	 * @is_global: outparam - set non-zero if the buffer should be global
	 *
	 * Called during relay_open(), once for each per-cpu buffer,
	 * to allow the client to create a file to be used to
@@ -126,12 +127,17 @@ struct rchan_callbacks
	 * The callback should return the dentry of the file created
	 * to represent the relay buffer.
	 *
	 * Setting the is_global outparam to a non-zero value will
	 * cause relay_open() to create a single global buffer rather
	 * than the default set of per-cpu buffers.
	 *
	 * See Documentation/filesystems/relayfs.txt for more info.
	 */
	struct dentry *(*create_buf_file)(const char *filename,
					  struct dentry *parent,
					  int mode,
					  struct rchan_buf *buf);
					  struct rchan_buf *buf,
					  int *is_global);

	/*
	 * remove_buf_file - remove file representing a relayfs channel buffer