MINI SHELL

Server : Apache/2.2.2 (Fedora)
System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686
User : apache ( 48)
PHP Version : 5.2.9
Disable Function : NONE
Directory :  /usr/share/systemtap/runtime/relayfs/linux/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/systemtap/runtime/relayfs/linux/relayfs_fs.h
/*
 * linux/include/linux/relayfs_fs.h
 *
 * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
 * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com)
 *
 * RelayFS definitions and declarations
 */

#ifndef _LINUX_RELAYFS_FS_H
#define _LINUX_RELAYFS_FS_H

#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/kref.h>

/*
 * Tracks changes to rchan_buf struct
 */
#define RELAYFS_CHANNEL_VERSION		3

/*
 * Per-cpu relay channel buffer
 */
struct rchan_buf
{
	void *start;			/* start of channel buffer */
	void *data;			/* start of current sub-buffer */
	unsigned offset;		/* current offset into sub-buffer */
	atomic_t subbufs_produced;	/* count of sub-buffers produced */
	atomic_t subbufs_consumed;	/* count of sub-buffers consumed */
	atomic_t unfull;		/* state has gone from full to not */
	struct rchan *chan;		/* associated channel */
	wait_queue_head_t read_wait;	/* reader wait queue */
	struct work_struct wake_readers; /* reader wake-up work struct */
	struct dentry *dentry;		/* channel file dentry */
	struct kref kref;		/* channel buffer refcount */
	struct page **page_array;	/* array of current buffer pages */
	int page_count;			/* number of current buffer pages */
	unsigned *padding;		/* padding counts per sub-buffer */
	unsigned *commit;		/* commit counts per sub-buffer */
	int finalized;			/* buffer has been finalized */
} ____cacheline_aligned;

/*
 * Relay channel data structure
 */
struct rchan
{
	u32 version;			/* the version of this struct */
	unsigned subbuf_size;		/* sub-buffer size */
	unsigned n_subbufs;		/* number of sub-buffers per buffer */
	unsigned alloc_size;		/* total buffer size allocated */
	int overwrite;			/* overwrite buffer when full? */
	struct rchan_callbacks *cb;	/* client callbacks */
	struct kref kref;		/* channel refcount */
	void *private_data;		/* for user-defined data */
	struct rchan_buf *buf[NR_CPUS]; /* per-cpu channel buffers */
};

/*
 * Relayfs inode
 */
struct relayfs_inode_info
{
	struct inode vfs_inode;
	struct rchan_buf *buf;
};

static inline struct relayfs_inode_info *RELAYFS_I(struct inode *inode)
{
	return container_of(inode, struct relayfs_inode_info, vfs_inode);
}

/*
 * Relay channel client callbacks
 */
struct rchan_callbacks
{
	/*
	 * subbuf_start - called on buffer-switch to a new sub-buffer
	 * @buf: the channel buffer containing the new sub-buffer
	 * @subbuf: the start of the new sub-buffer
	 * @prev_subbuf_idx: the previous sub-buffer's index
	 * @prev_subbuf: the start of the previous sub-buffer
	 *
	 * The client should return the number of bytes it reserves at
	 * the beginning of the sub-buffer, 0 if none.
	 *
	 * NOTE: subbuf_start will also be invoked when the buffer is
	 *       created, so that the first sub-buffer can be initialized
	 *       if necessary.  In this case, prev_subbuf will be NULL.
	 */
	int (*subbuf_start) (struct rchan_buf *buf,
			     void *subbuf,
			     unsigned prev_subbuf_idx,
			     void *prev_subbuf);

	/*
	 * deliver - deliver a guaranteed full sub-buffer to client
	 * @buf: the channel buffer containing the sub-buffer
	 * @subbuf_idx: the sub-buffer's index
	 * @subbuf: the start of the new sub-buffer
	 *
	 * Only works if relay_commit is also used
	 */
	void (*deliver) (struct rchan_buf *buf,
			 unsigned subbuf_idx,
			 void *subbuf);

	/*
	 * buf_mapped - relayfs buffer mmap notification
	 * @buf: the channel buffer
	 * @filp: relayfs file pointer
	 *
	 * Called when a relayfs file is successfully mmapped
	 */
        void (*buf_mapped)(struct rchan_buf *buf,
			   struct file *filp);

	/*
	 * buf_unmapped - relayfs buffer unmap notification
	 * @buf: the channel buffer
	 * @filp: relayfs file pointer
	 *
	 * Called when a relayfs file is successfully unmapped
	 */
        void (*buf_unmapped)(struct rchan_buf *buf,
			     struct file *filp);

	/*
	 * buf_full - relayfs buffer full notification
	 * @buf: the channel channel buffer
	 * @subbuf_idx: the current sub-buffer's index
	 * @subbuf: the start of the current sub-buffer
	 *
	 * Called when a relayfs buffer becomes full
	 */
        void (*buf_full)(struct rchan_buf *buf,
			 unsigned subbuf_idx,
			 void *subbuf);
};

/*
 * relayfs kernel API, fs/relayfs/relay.c
 */

struct rchan *relay_open(const char *base_filename,
			 struct dentry *parent,
			 unsigned subbuf_size,
			 unsigned n_subbufs,
			 int overwrite,
			 struct rchan_callbacks *cb);
extern void relay_close(struct rchan *chan);
extern void relay_flush(struct rchan *chan);
extern void relay_subbufs_consumed(struct rchan *chan,
				   int cpu,
				   int subbufs_consumed);
extern void relay_reset(struct rchan *chan);
extern unsigned relay_switch_subbuf(struct rchan_buf *buf,
				    unsigned length);
extern void relay_commit(struct rchan_buf *buf,
			 void *reserved,
			 unsigned count);
extern struct dentry *relayfs_create_dir(const char *name,
					 struct dentry *parent);
extern int relayfs_remove_dir(struct dentry *dentry);

/**
 *	relay_write - write data into the channel
 *	@chan: relay channel
 *	@data: data to be written
 *	@length: number of bytes to write
 *
 *	Writes data into the current cpu's channel buffer.
 *
 *	Protects the buffer by disabling interrupts.  Use this
 *	if you might be logging from interrupt context.  Try
 *	__relay_write() if you know you	won't be logging from
 *	interrupt context.
 */
static inline void relay_write(struct rchan *chan,
			       const void *data,
			       unsigned length)
{
	unsigned long flags;
	struct rchan_buf *buf;

	local_irq_save(flags);
	buf = chan->buf[smp_processor_id()];
	if (unlikely(buf->offset + length > chan->subbuf_size))
		length = relay_switch_subbuf(buf, length);
	memcpy(buf->data + buf->offset, data, length);
	buf->offset += length;
	local_irq_restore(flags);
}

/**
 *	__relay_write - write data into the channel
 *	@chan: relay channel
 *	@data: data to be written
 *	@length: number of bytes to write
 *
 *	Writes data into the current cpu's channel buffer.
 *
 *	Protects the buffer by disabling preemption.  Use
 *	relay_write() if you might be logging from interrupt
 *	context.
 */
static inline void __relay_write(struct rchan *chan,
				 const void *data,
				 unsigned length)
{
	struct rchan_buf *buf;

	buf = chan->buf[get_cpu()];
	if (unlikely(buf->offset + length > buf->chan->subbuf_size))
		length = relay_switch_subbuf(buf, length);
	memcpy(buf->data + buf->offset, data, length);
	buf->offset += length;
	put_cpu();
}

/**
 *	relay_reserve - reserve slot in channel buffer
 *	@chan: relay channel
 *	@length: number of bytes to reserve
 *
 *	Returns pointer to reserved slot, NULL if full.
 *
 *	Reserves a slot in the current cpu's channel buffer.
 *	Does not protect the buffer at all - caller must provide
 *	appropriate synchronization.
 */
static inline void *relay_reserve(struct rchan *chan, unsigned length)
{
	void *reserved;
	struct rchan_buf *buf = chan->buf[smp_processor_id()];

	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
		length = relay_switch_subbuf(buf, length);
		if (!length)
			return NULL;
	}
	reserved = buf->data + buf->offset;
	buf->offset += length;

	return reserved;
}

/*
 * exported relayfs file operations, fs/relayfs/inode.c
 */

extern struct file_operations relayfs_file_operations;
extern int relayfs_open(struct inode *inode, struct file *filp);
extern unsigned int relayfs_poll(struct file *filp, poll_table *wait);
extern int relayfs_mmap(struct file *filp, struct vm_area_struct *vma);
extern int relayfs_release(struct inode *inode, struct file *filp);

#endif /* _LINUX_RELAYFS_FS_H */


Anon7 - 2021