[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: Tom Zanussi <zanussi@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Родитель
03d78d11d9
Коммит
e6c08367b8
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче