From: Tom Zanussi 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: Tom Zanussi Signed-off-by: Andrew Morton --- fs/relayfs/relay.c | 35 +++++++++++++++++++++++++---------- include/linux/relayfs_fs.h | 8 +++++++- 2 files changed, 32 insertions(+), 11 deletions(-) diff -puN fs/relayfs/relay.c~relayfs-add-support-for-global-relay-buffers fs/relayfs/relay.c --- devel/fs/relayfs/relay.c~relayfs-add-support-for-global-relay-buffers 2005-11-12 13:18:16.000000000 -0800 +++ devel-akpm/fs/relayfs/relay.c 2005-11-12 13:18:17.000000000 -0800 @@ -86,7 +86,8 @@ static void buf_unmapped_default_callbac 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 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 *bas 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 *bas 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); @@ -421,14 +432,16 @@ void relay_destroy_channel(struct 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]; } kref_put(&chan->kref, relay_destroy_channel); @@ -443,14 +456,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]; } } diff -puN include/linux/relayfs_fs.h~relayfs-add-support-for-global-relay-buffers include/linux/relayfs_fs.h --- devel/include/linux/relayfs_fs.h~relayfs-add-support-for-global-relay-buffers 2005-11-12 13:18:17.000000000 -0800 +++ devel-akpm/include/linux/relayfs_fs.h 2005-11-12 13:18:17.000000000 -0800 @@ -115,6 +115,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 @@ -125,12 +126,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 _