[RFC/PATCH 4/4] relayfs include files

From: Tom Zanussi (zanussi_at_us.ibm.com)
Date: 12/01/03

  • Next message: Markus Hästbacka: "[OT] Rootkit queston"
    Date:	Mon, 1 Dec 2003 14:56:48 -0600
    To: linux-kernel@vger.kernel.org
    
    

    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-alpha/relay.h linux-2.6.0-test11.cur/include/asm-alpha/relay.h
    --- linux-2.6.0-test11/include/asm-alpha/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-alpha/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_ALPHA_RELAY_H
    +#define _ASM_ALPHA_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-arm/relay.h linux-2.6.0-test11.cur/include/asm-arm/relay.h
    --- linux-2.6.0-test11/include/asm-arm/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-arm/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_ARM_RELAY_H
    +#define _ASM_ARM_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-arm26/relay.h linux-2.6.0-test11.cur/include/asm-arm26/relay.h
    --- linux-2.6.0-test11/include/asm-arm26/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-arm26/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_ARM_RELAY_H
    +#define _ASM_ARM_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-cris/relay.h linux-2.6.0-test11.cur/include/asm-cris/relay.h
    --- linux-2.6.0-test11/include/asm-cris/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-cris/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_CRIS_RELAY_H
    +#define _ASM_CRIS_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-generic/relay.h linux-2.6.0-test11.cur/include/asm-generic/relay.h
    --- linux-2.6.0-test11/include/asm-generic/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-generic/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,76 @@
    +#ifndef _ASM_GENERIC_RELAY_H
    +#define _ASM_GENERIC_RELAY_H
    +/*
    + * linux/include/asm-generic/relay.h
    + *
    + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
    + * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com)
    + *
    + * Architecture-independent definitions for relayfs
    + */
    +
    +#include <linux/relayfs_fs.h>
    +
    +/**
    + * get_time_delta - utility function for getting time delta
    + * @now: pointer to a timeval struct that may be given current time
    + * @rchan: the channel
    + *
    + * Returns the time difference between the current time and the buffer
    + * start time.
    + */
    +static inline u32
    +get_time_delta(struct timeval *now, struct rchan *rchan)
    +{
    + u32 time_delta;
    +
    + do_gettimeofday(now);
    + time_delta = calc_time_delta(now, &rchan->buf_start_time);
    +
    + return time_delta;
    +}
    +
    +/**
    + * get_timestamp - utility function for getting a time and TSC pair
    + * @now: current time
    + * @tsc: the TSC associated with now
    + * @rchan: the channel
    + *
    + * Sets the value pointed to by now to the current time. Value pointed to
    + * by tsc is not set since there is no generic TSC support.
    + */
    +static inline void
    +get_timestamp(struct timeval *now,
    + u32 *tsc,
    + struct rchan *rchan)
    +{
    + do_gettimeofday(now);
    +}
    +
    +/**
    + * get_time_or_tsc: - Utility function for getting a time or a TSC.
    + * @now: current time
    + * @tsc: current TSC
    + * @rchan: the channel
    + *
    + * Sets the value pointed to by now to the current time.
    + */
    +static inline void
    +get_time_or_tsc(struct timeval *now,
    + u32 *tsc,
    + struct rchan *rchan)
    +{
    + do_gettimeofday(now);
    +}
    +
    +/**
    + * have_tsc - does this platform have a useable TSC?
    + *
    + * Returns 0.
    + */
    +static inline int
    +have_tsc(void)
    +{
    + return 0;
    +}
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-h8300/relay.h linux-2.6.0-test11.cur/include/asm-h8300/relay.h
    --- linux-2.6.0-test11/include/asm-h8300/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-h8300/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_H8300_RELAY_H
    +#define _ASM_H8300_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-i386/relay.h linux-2.6.0-test11.cur/include/asm-i386/relay.h
    --- linux-2.6.0-test11/include/asm-i386/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-i386/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,101 @@
    +#ifndef _ASM_I386_RELAY_H
    +#define _ASM_I386_RELAY_H
    +/*
    + * linux/include/asm-i386/relay.h
    + *
    + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
    + * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com)
    + *
    + * i386 definitions for relayfs
    + */
    +
    +#include <linux/relayfs_fs.h>
    +
    +#ifdef CONFIG_X86_TSC
    +#include <asm/msr.h>
    +
    +/**
    + * get_time_delta - utility function for getting time delta
    + * @now: pointer to a timeval struct that may be given current time
    + * @rchan: the channel
    + *
    + * Returns either the TSC if TSCs are being used, or the time and the
    + * time difference between the current time and the buffer start time
    + * if TSCs are not being used.
    + */
    +static inline u32
    +get_time_delta(struct timeval *now, struct rchan *rchan)
    +{
    + u32 time_delta;
    +
    + if ((using_tsc(rchan) == 1) && cpu_has_tsc)
    + rdtscl(time_delta);
    + else {
    + do_gettimeofday(now);
    + time_delta = calc_time_delta(now, &rchan->buf_start_time);
    + }
    +
    + return time_delta;
    +}
    +
    +/**
    + * get_timestamp - utility function for getting a time and TSC pair
    + * @now: current time
    + * @tsc: the TSC associated with now
    + * @rchan: the channel
    + *
    + * Sets the value pointed to by now to the current time and the value
    + * pointed to by tsc to the tsc associated with that time, if the
    + * platform supports TSC.
    + */
    +static inline void
    +get_timestamp(struct timeval *now,
    + u32 *tsc,
    + struct rchan *rchan)
    +{
    + do_gettimeofday(now);
    +
    + if ((using_tsc(rchan) == 1) && cpu_has_tsc)
    + rdtscl(*tsc);
    +}
    +
    +/**
    + * get_time_or_tsc - utility function for getting a time or a TSC
    + * @now: current time
    + * @tsc: current TSC
    + * @rchan: the channel
    + *
    + * Sets the value pointed to by now to the current time or the value
    + * pointed to by tsc to the current tsc, depending on whether we're
    + * using TSCs or not.
    + */
    +static inline void
    +get_time_or_tsc(struct timeval *now,
    + u32 *tsc,
    + struct rchan *rchan)
    +{
    + if ((using_tsc(rchan) == 1) && cpu_has_tsc)
    + rdtscl(*tsc);
    + else
    + do_gettimeofday(now);
    +}
    +
    +/**
    + * have_tsc - does this platform have a useable TSC?
    + *
    + * Returns 1 if this platform has a useable TSC counter for
    + * timestamping purposes, 0 otherwise.
    + */
    +static inline int
    +have_tsc(void)
    +{
    + if (cpu_has_tsc)
    + return 1;
    + else
    + return 0;
    +}
    +
    +#else /* No TSC support (#ifdef CONFIG_X86_TSC) */
    +#include <asm-generic/relay.h>
    +#endif /* #ifdef CONFIG_X86_TSC */
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-ia64/relay.h linux-2.6.0-test11.cur/include/asm-ia64/relay.h
    --- linux-2.6.0-test11/include/asm-ia64/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-ia64/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_IA64_RELAY_H
    +#define _ASM_IA64_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-m68k/relay.h linux-2.6.0-test11.cur/include/asm-m68k/relay.h
    --- linux-2.6.0-test11/include/asm-m68k/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-m68k/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_M68K_RELAY_H
    +#define _ASM_M68K_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-m68knommu/relay.h linux-2.6.0-test11.cur/include/asm-m68knommu/relay.h
    --- linux-2.6.0-test11/include/asm-m68knommu/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-m68knommu/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_M68KNOMMU_RELAY_H
    +#define _ASM_M68KNOMMU_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-mips/relay.h linux-2.6.0-test11.cur/include/asm-mips/relay.h
    --- linux-2.6.0-test11/include/asm-mips/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-mips/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_RELAY_H
    +#define _ASM_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-mips64/relay.h linux-2.6.0-test11.cur/include/asm-mips64/relay.h
    --- linux-2.6.0-test11/include/asm-mips64/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-mips64/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_RELAY_H
    +#define _ASM_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-parisc/relay.h linux-2.6.0-test11.cur/include/asm-parisc/relay.h
    --- linux-2.6.0-test11/include/asm-parisc/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-parisc/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_PARISC_RELAY_H
    +#define _ASM_PARISC_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-ppc/relay.h linux-2.6.0-test11.cur/include/asm-ppc/relay.h
    --- linux-2.6.0-test11/include/asm-ppc/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-ppc/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_PPC_RELAY_H
    +#define _ASM_PPC_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-ppc64/relay.h linux-2.6.0-test11.cur/include/asm-ppc64/relay.h
    --- linux-2.6.0-test11/include/asm-ppc64/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-ppc64/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_PPC64_RELAY_H
    +#define _ASM_PPC64_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-s390/relay.h linux-2.6.0-test11.cur/include/asm-s390/relay.h
    --- linux-2.6.0-test11/include/asm-s390/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-s390/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_S390_RELAY_H
    +#define _ASM_S390_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-sh/relay.h linux-2.6.0-test11.cur/include/asm-sh/relay.h
    --- linux-2.6.0-test11/include/asm-sh/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-sh/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_SH_RELAY_H
    +#define _ASM_SH_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-sparc/relay.h linux-2.6.0-test11.cur/include/asm-sparc/relay.h
    --- linux-2.6.0-test11/include/asm-sparc/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-sparc/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_SPARC_RELAY_H
    +#define _ASM_SPARC_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-sparc64/relay.h linux-2.6.0-test11.cur/include/asm-sparc64/relay.h
    --- linux-2.6.0-test11/include/asm-sparc64/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-sparc64/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_SPARC64_RELAY_H
    +#define _ASM_SPARC64_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-v850/relay.h linux-2.6.0-test11.cur/include/asm-v850/relay.h
    --- linux-2.6.0-test11/include/asm-v850/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-v850/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef __V850_RELAY_H
    +#define __V850_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/asm-x86_64/relay.h linux-2.6.0-test11.cur/include/asm-x86_64/relay.h
    --- linux-2.6.0-test11/include/asm-x86_64/relay.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/asm-x86_64/relay.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,5 @@
    +#ifndef _ASM_X86_64_RELAY_H
    +#define _ASM_X86_64_RELAY_H
    +
    +#include <asm-generic/relay.h>
    +#endif
    diff -urpN -X dontdiff linux-2.6.0-test11/include/linux/klog.h linux-2.6.0-test11.cur/include/linux/klog.h
    --- linux-2.6.0-test11/include/linux/klog.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/linux/klog.h Wed Nov 26 22:48:42 2003
    @@ -0,0 +1,24 @@
    +/*
    + * KLOG Generic Logging facility built upon the relayfs infrastructure
    + *
    + * Authors: Hubertus Frankeh (frankeh@us.ibm.com)
    + * Tom Zanussi (zanussi@us.ibm.com)
    + *
    + * Please direct all questions/comments to zanussi@us.ibm.com
    + *
    + * Copyright (C) 2003, IBM Corp
    + *
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * as published by the Free Software Foundation; either version
    + * 2 of the License, or (at your option) any later version.
    + */
    +
    +#ifndef _LINUX_KLOG_H
    +#define _LINUX_KLOG_H
    +
    +extern int klog(const char *fmt, ...);
    +extern int klog_raw(const char *buf,int len);
    +
    +#endif /* _LINUX_KLOG_H */
    diff -urpN -X dontdiff linux-2.6.0-test11/include/linux/relayfs_fs.h linux-2.6.0-test11.cur/include/linux/relayfs_fs.h
    --- linux-2.6.0-test11/include/linux/relayfs_fs.h Wed Dec 31 18:00:00 1969
    +++ linux-2.6.0-test11.cur/include/linux/relayfs_fs.h Mon Dec 1 12:18:26 2003
    @@ -0,0 +1,667 @@
    +/*
    + * 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
    + *
    + * Please see Documentation/filesystems/relayfs.txt for more info.
    + */
    +
    +#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>
    +
    +/*
    + * Tracks changes to rchan struct
    + */
    +#define RELAYFS_CHANNEL_VERSION 1
    +
    +/*
    + * Maximum number of simultaneously open channels
    + */
    +#define RELAY_MAX_CHANNELS 256
    +
    +/*
    + * Relay properties
    + */
    +#define RELAY_MIN_BUFS 2
    +#define RELAY_MIN_BUFSIZE 4096
    +#define RELAY_MAX_BUFS 256
    +#define RELAY_MAX_BUF_SIZE 0x1000000
    +#define RELAY_MAX_TOTAL_BUF_SIZE 0x8000000
    +
    +/*
    + * Lockless scheme utility macros
    + */
    +#define RELAY_MAX_BUFNO(bufno_bits) (1UL << (bufno_bits))
    +#define RELAY_BUF_SIZE(offset_bits) (1UL << (offset_bits))
    +#define RELAY_BUF_OFFSET_MASK(offset_bits) (RELAY_BUF_SIZE(offset_bits) - 1)
    +#define RELAY_BUFNO_GET(index, offset_bits) ((index) >> (offset_bits))
    +#define RELAY_BUF_OFFSET_GET(index, mask) ((index) & (mask))
    +#define RELAY_BUF_OFFSET_CLEAR(index, mask) ((index) & ~(mask))
    +
    +/*
    + * Flags returned by relay_reserve()
    + */
    +#define RELAY_BUFFER_SWITCH_NONE 0x0
    +#define RELAY_WRITE_DISCARD_NONE 0x0
    +#define RELAY_BUFFER_SWITCH 0x1
    +#define RELAY_WRITE_DISCARD 0x2
    +#define RELAY_WRITE_TOO_LONG 0x4
    +
    +/*
    + * Relay attribute flags
    + */
    +#define RELAY_DELIVERY_BULK 0x1
    +#define RELAY_DELIVERY_PACKET 0x2
    +#define RELAY_SCHEME_LOCKLESS 0x4
    +#define RELAY_SCHEME_LOCKING 0x8
    +#define RELAY_SCHEME_ANY 0xC
    +#define RELAY_TIMESTAMP_TSC 0x10
    +#define RELAY_TIMESTAMP_GETTIMEOFDAY 0x20
    +#define RELAY_TIMESTAMP_ANY 0x30
    +#define RELAY_USAGE_SMP 0x40
    +#define RELAY_USAGE_GLOBAL 0x80
    +#define RELAY_MODE_CONTINUOUS 0x100
    +#define RELAY_MODE_NO_OVERWRITE 0x200
    +
    +/*
    + * Flags for needs_resize() callback
    + */
    +#define RELAY_RESIZE_NONE 0x0
    +#define RELAY_RESIZE_EXPAND 0x1
    +#define RELAY_RESIZE_SHRINK 0x2
    +#define RELAY_RESIZE_REPLACE 0x4
    +#define RELAY_RESIZE_REPLACED 0x8
    +
    +/*
    + * Values for fileop_notify() callback
    + */
    +enum relay_fileop
    +{
    + RELAY_FILE_OPEN,
    + RELAY_FILE_CLOSE,
    + RELAY_FILE_MAP,
    + RELAY_FILE_UNMAP
    +};
    +
    +/*
    + * Data structure returned by relay_info()
    + */
    +struct rchan_info
    +{
    + u32 flags; /* relay attribute flags for channel */
    + u32 buf_size; /* channel's sub-buffer size */
    + char *buf_addr; /* address of channel start */
    + u32 alloc_size; /* total buffer size actually allocated */
    + u32 n_bufs; /* number of sub-buffers in channel */
    + u32 bufs_produced; /* current count of sub-buffers produced */
    + u32 bufs_consumed; /* current count of sub-buffers consumed */
    + u32 buf_id; /* buf_id of current sub-buffer */
    + int buffer_complete[RELAY_MAX_BUFS]; /* boolean per sub-buffer */
    + int unused_bytes[RELAY_MAX_BUFS]; /* count per sub-buffer */
    +};
    +
    +/*
    + * Relay channel client callbacks
    + */
    +struct rchan_callbacks
    +{
    + /*
    + * buffer_start - called at the beginning of a new sub-buffer
    + * @rchan_id: the channel id
    + * @current_write_pos: position in sub-buffer client should write to
    + * @buffer_id: the id of the new sub-buffer
    + * @start_time: the timestamp associated with the start of sub-buffer
    + * @start_tsc: the TSC associated with the timestamp, if using_tsc
    + * @using_tsc: boolean, indicates whether start_tsc is valid
    + *
    + * Return value should be the number of bytes written by the client.
    + *
    + * See Documentation/filesystems/relayfs.txt for details.
    + */
    + int (*buffer_start) (int rchan_id,
    + char *current_write_pos,
    + u32 buffer_id,
    + struct timeval start_time,
    + u32 start_tsc,
    + int using_tsc);
    +
    + /*
    + * buffer_end - called at the end of a sub-buffer
    + * @rchan_id: the channel id
    + * @current_write_pos: position in sub-buffer of end of data
    + * @end_of_buffer: the position of the end of the sub-buffer
    + * @end_time: the timestamp associated with the end of the sub-buffer
    + * @end_tsc: the TSC associated with the end_time, if using_tsc
    + * @using_tsc: boolean, indicates whether end_tsc is valid
    + *
    + * Return value should be the number of bytes written by the client.
    + *
    + * See Documentation/filesystems/relayfs.txt for details.
    + */
    + int (*buffer_end) (int rchan_id,
    + char *current_write_pos,
    + char *end_of_buffer,
    + struct timeval end_time,
    + u32 end_tsc,
    + int using_tsc);
    +
    + /*
    + * deliver - called when data is ready for the client
    + * @rchan_id: the channel id
    + * @from: the start of the delivered data
    + * @len: the length of the delivered data
    + *
    + * See Documentation/filesystems/relayfs.txt for details.
    + */
    + void (*deliver) (int rchan_id, char *from, u32 len);
    +
    + /*
    + * user_deliver - called when data has been written from userspace
    + * @rchan_id: the channel id
    + * @from: the start of the delivered data
    + * @len: the length of the delivered data
    + *
    + * See Documentation/filesystems/relayfs.txt for details.
    + */
    + void (*user_deliver) (int rchan_id, char *from, u32 len);
    +
    + /*
    + * needs_resize - called when a resizing event occurs
    + * @rchan_id: the channel id
    + * @resize_type: the type of resizing event
    + * @suggested_buf_size: the suggested new sub-buffer size
    + * @suggested_buf_size: the suggested new number of sub-buffers
    + *
    + * See Documentation/filesystems/relayfs.txt for details.
    + */
    + void (*needs_resize)(int rchan_id,
    + int resize_type,
    + u32 suggested_buf_size,
    + u32 suggested_n_bufs);
    +
    + /*
    + * fileop_notify - called on open/close/mmap/munmap of a relayfs file
    + * @rchan_id: the channel id
    + * @filp: relayfs file pointer
    + * @fileop: which file operation is in progress
    + *
    + * The return value can direct the outcome of the operation.
    + *
    + * See Documentation/filesystems/relayfs.txt for details.
    + */
    + int (*fileop_notify)(int rchan_id,
    + struct file *filp,
    + enum relay_fileop fileop);
    +};
    +
    +/*
    + * Lockless scheme-specific data
    + */
    +struct lockless_rchan
    +{
    + u8 bufno_bits; /* # bits used for sub-buffer id */
    + u8 offset_bits; /* # bits used for offset within sub-buffer */
    + u32 index; /* current index = sub-buffer id and offset */
    + u32 offset_mask; /* used to obtain offset portion of index */
    + u32 index_mask; /* used to mask off unused bits index */
    + atomic_t fill_count[RELAY_MAX_BUFS]; /* fill count per sub-buffer */
    +};
    +
    +/*
    + * Locking scheme-specific data
    + */
    +struct locking_rchan
    +{
    + char *write_buf; /* start of write sub-buffer */
    + char *write_buf_end; /* end of write sub-buffer */
    + char *current_write_pos; /* current write pointer */
    + char *write_limit; /* takes reserves into account */
    + char *in_progress_event_pos; /* used for interrupted writes */
    + u16 in_progress_event_size; /* used for interrupted writes */
    + char *interrupted_pos; /* used for interrupted writes */
    + u16 interrupting_size; /* used for interrupted writes */
    + spinlock_t lock; /* channel lock for locking scheme */
    +};
    +
    +struct relay_ops;
    +
    +/*
    + * Offset resizing data structure
    + */
    +struct resize_offset
    +{
    + u32 ge;
    + u32 le;
    + int delta;
    +};
    +
    +#define MAX_RESIZE_OFFSETS 3
    +
    +/*
    + * Relay channel data structure
    + */
    +struct rchan
    +{
    + u32 version; /* the version of this struct */
    + char *buf; /* the channel buffer */
    + union
    + {
    + struct lockless_rchan lockless;
    + struct locking_rchan locking;
    + } scheme; /* scheme-specific channel data */
    +
    + int id; /* the channel id */
    + struct rchan_callbacks *callbacks; /* client callbacks */
    + u32 flags; /* relay channel attributes */
    + u32 buf_id; /* current sub-buffer id */
    + u32 buf_idx; /* current sub-buffer index */
    +
    + atomic_t mapped; /* map count */
    +
    + atomic_t suspended; /* channel suspended i.e full? */
    + int half_switch; /* used internally for suspend */
    +
    + struct timeval buf_start_time; /* current sub-buffer start time */
    + u32 buf_start_tsc; /* current sub-buffer start TSC */
    +
    + u32 buf_size; /* sub-buffer size */
    + u32 alloc_size; /* total buffer size allocated */
    + u32 n_bufs; /* number of sub-buffers */
    +
    + u32 bufs_produced; /* count of sub-buffers produced */
    + u32 bufs_consumed; /* count of sub-buffers consumed */
    + u32 bytes_consumed; /* bytes consumed in cur sub-buffer */
    +
    + int initialized; /* first buffer initialized? */
    + int finalized; /* channel finalized? */
    +
    + u32 start_reserve; /* reserve at start of sub-buffers */
    + u32 end_reserve; /* reserve at end of sub-buffers */
    + u32 rchan_start_reserve; /* additional reserve sub-buffer 0 */
    +
    + struct dentry *dentry; /* channel file dentry */
    +
    + wait_queue_head_t read_wait; /* VFS read wait queue */
    + wait_queue_head_t write_wait; /* VFS write wait queue */
    + struct work_struct wake_readers; /* reader wake-up work struct */
    + struct work_struct wake_writers; /* reader wake-up work struct */
    + atomic_t refcount; /* channel refcount */
    +
    + struct relay_ops *relay_ops; /* scheme-specific channel ops */
    +
    + int unused_bytes[RELAY_MAX_BUFS]; /* unused count per sub-buffer */
    +
    + struct semaphore resize_sem; /* serializes alloc/repace */
    + struct work_struct work; /* resize allocation work struct */
    +
    + struct list_head open_readers; /* open readers for this channel */
    + rwlock_t open_readers_lock; /* protection for open_readers list */
    +
    + u32 resize_min; /* minimum resized total buffer size */
    + u32 resize_max; /* maximum resized total buffer size */
    + char *resize_buf; /* for autosize alloc/free */
    + u32 resize_buf_size; /* resized sub-buffer size */
    + u32 resize_n_bufs; /* resized number of sub-buffers */
    + u32 resize_alloc_size; /* resized actual total size */
    + int resizing; /* is resizing in progress? */
    + int resize_err; /* resizing err code */
    + int resize_failures; /* number of resize failures */
    + int replace_buffer; /* is the alloced buffer ready? */
    + struct resize_offset resize_offsets[MAX_RESIZE_OFFSETS];
    + unsigned offset_change_count; /* number of offset changes */
    + struct timer_list shrink_timer; /* timer used for shrinking */
    + int resize_order; /* size of last resize */
    +
    + struct page **buf_page_array; /* array of current buffer pages */
    + int buf_page_count; /* number of current buffer pages */
    + struct page **expand_page_array;/* new pages to be inserted */
    + int expand_page_count; /* number of new pages */
    + struct page **shrink_page_array;/* old pages to be freed */
    + int shrink_page_count; /* number of old pages */
    + struct page **resize_page_array;/* will become current pages */
    + int resize_page_count; /* number of resize pages */
    + struct page **old_buf_page_array; /* hold for freeing */
    +} ____cacheline_aligned;
    +
    +/*
    + * Relay channel reader struct
    + */
    +struct rchan_reader
    +{
    + struct list_head list; /* for list inclusion */
    + struct rchan *rchan; /* the channel we're reading from */
    + int auto_consume; /* does this reader auto-consume? */
    + u32 bufs_consumed; /* buffers this reader has consumed */
    + u32 bytes_consumed; /* bytes consumed in cur sub-buffer */
    + int offset_changed; /* have channel offsets changed? */
    + int vfs_reader; /* are we a VFS reader? */
    + int map_reader; /* are we an mmap reader? */
    +
    + union
    + {
    + struct file *file;
    + u32 f_pos;
    + } pos; /* current read offset */
    +};
    +
    +/*
    + * These help make union member access less tedious
    + */
    +#define channel_buffer(rchan) ((rchan)->buf)
    +#define idx(rchan) ((rchan)->scheme.lockless.index)
    +#define bufno_bits(rchan) ((rchan)->scheme.lockless.bufno_bits)
    +#define offset_bits(rchan) ((rchan)->scheme.lockless.offset_bits)
    +#define offset_mask(rchan) ((rchan)->scheme.lockless.offset_mask)
    +#define idx_mask(rchan) ((rchan)->scheme.lockless.index_mask)
    +#define bulk_delivery(rchan) (((rchan)->flags & RELAY_DELIVERY_BULK) ? 1 : 0)
    +#define packet_delivery(rchan) (((rchan)->flags & RELAY_DELIVERY_PACKET) ? 1 : 0)
    +#define using_lockless(rchan) (((rchan)->flags & RELAY_SCHEME_LOCKLESS) ? 1 : 0)
    +#define using_locking(rchan) (((rchan)->flags & RELAY_SCHEME_LOCKING) ? 1 : 0)
    +#define using_tsc(rchan) (((rchan)->flags & RELAY_TIMESTAMP_TSC) ? 1 : 0)
    +#define using_gettimeofday(rchan) (((rchan)->flags & RELAY_TIMESTAMP_GETTIMEOFDAY) ? 1 : 0)
    +#define usage_smp(rchan) (((rchan)->flags & RELAY_USAGE_SMP) ? 1 : 0)
    +#define usage_global(rchan) (((rchan)->flags & RELAY_USAGE_GLOBAL) ? 1 : 0)
    +#define mode_continuous(rchan) (((rchan)->flags & RELAY_MODE_CONTINUOUS) ? 1 : 0)
    +#define fill_count(rchan, i) ((rchan)->scheme.lockless.fill_count[(i)])
    +#define write_buf(rchan) ((rchan)->scheme.locking.write_buf)
    +#define read_buf(rchan) ((rchan)->scheme.locking.read_buf)
    +#define write_buf_end(rchan) ((rchan)->scheme.locking.write_buf_end)
    +#define read_buf_end(rchan) ((rchan)->scheme.locking.read_buf_end)
    +#define cur_write_pos(rchan) ((rchan)->scheme.locking.current_write_pos)
    +#define read_limit(rchan) ((rchan)->scheme.locking.read_limit)
    +#define write_limit(rchan) ((rchan)->scheme.locking.write_limit)
    +#define in_progress_event_pos(rchan) ((rchan)->scheme.locking.in_progress_event_pos)
    +#define in_progress_event_size(rchan) ((rchan)->scheme.locking.in_progress_event_size)
    +#define interrupted_pos(rchan) ((rchan)->scheme.locking.interrupted_pos)
    +#define interrupting_size(rchan) ((rchan)->scheme.locking.interrupting_size)
    +#define channel_lock(rchan) ((rchan)->scheme.locking.lock)
    +
    +/**
    + * calc_time_delta - utility function for time delta calculation
    + * @now: current time
    + * @start: start time
    + *
    + * Returns the time delta produced by subtracting start time from now.
    + */
    +static inline u32
    +calc_time_delta(struct timeval *now,
    + struct timeval *start)
    +{
    + return (now->tv_sec - start->tv_sec) * 1000000
    + + (now->tv_usec - start->tv_usec);
    +}
    +
    +/**
    + * recalc_time_delta - utility function for time delta recalculation
    + * @now: current time
    + * @new_delta: the new time delta calculated
    + * @cpu: the associated CPU id
    + */
    +static inline void
    +recalc_time_delta(struct timeval *now,
    + u32 *new_delta,
    + struct rchan *rchan)
    +{
    + if (using_tsc(rchan) == 0)
    + *new_delta = calc_time_delta(now, &rchan->buf_start_time);
    +}
    +
    +/**
    + * have_cmpxchg - does this architecture have a cmpxchg?
    + *
    + * Returns 1 if this architecture has a cmpxchg useable by
    + * the lockless scheme, 0 otherwise.
    + */
    +static inline int
    +have_cmpxchg(void)
    +{
    +#if defined(__HAVE_ARCH_CMPXCHG)
    + return 1;
    +#else
    + return 0;
    +#endif
    +}
    +
    +/**
    + * relay_write_direct - write data directly into destination buffer
    + */
    +#define relay_write_direct(DEST, SRC, SIZE) \
    +do\
    +{\
    + memcpy(DEST, SRC, SIZE);\
    + DEST += SIZE;\
    +} while (0);
    +
    +/**
    + * relay_lock_channel - lock the relay channel if applicable
    + *
    + * This macro only affects the locking scheme. If the locking scheme
    + * is in use and the channel usage is SMP, does a local_irq_save. If the
    + * locking sheme is in use and the channel usage is GLOBAL, uses
    + * spin_lock_irqsave. FLAGS is initialized to 0 since we know that
    + * it is being initialized prior to use and we avoid the compiler warning.
    + */
    +#define relay_lock_channel(RCHAN, FLAGS) \
    +do\
    +{\
    + FLAGS = 0;\
    + if (using_locking(RCHAN)) {\
    + if (usage_smp(RCHAN)) {\
    + local_irq_save(FLAGS); \
    + } else {\
    + spin_lock_irqsave(&(RCHAN)->scheme.locking.lock, FLAGS); \
    + }\
    + }\
    +} while (0);
    +
    +/**
    + * relay_unlock_channel - unlock the relay channel if applicable
    + *
    + * This macro only affects the locking scheme. See relay_lock_channel.
    + */
    +#define relay_unlock_channel(RCHAN, FLAGS) \
    +do\
    +{\
    + if (using_locking(RCHAN)) {\
    + if (usage_smp(RCHAN)) {\
    + local_irq_restore(FLAGS); \
    + } else {\
    + spin_unlock_irqrestore(&(RCHAN)->scheme.locking.lock, FLAGS); \
    + }\
    + }\
    +} while (0);
    +
    +/*
    + * Define cmpxchg if we don't have it
    + */
    +#ifndef __HAVE_ARCH_CMPXCHG
    +#define cmpxchg(p,o,n) 0
    +#endif
    +
    +/*
    + * High-level relayfs kernel API, fs/relayfs/relay.c
    + */
    +extern int
    +relay_open(const char *chanpath,
    + int bufsize,
    + int nbufs,
    + u32 flags,
    + struct rchan_callbacks *channel_callbacks,
    + u32 start_reserve,
    + u32 end_reserve,
    + u32 rchan_start_reserve,
    + u32 resize_min,
    + u32 resize_max,
    + int mode);
    +
    +extern int
    +relay_close(int rchan_id);
    +
    +extern int
    +relay_write(int rchan_id,
    + const void *data_ptr,
    + size_t count,
    + int td_offset,
    + void **wrote_pos);
    +
    +ssize_t
    +relay_read(struct rchan_reader *reader,
    + char *buf,
    + size_t count,
    + int wait,
    + u32 *actual_read_offset);
    +
    +extern struct rchan_reader *
    +add_rchan_reader(int rchan_id, int autoconsume);
    +
    +extern int
    +remove_rchan_reader(struct rchan_reader *reader);
    +
    +struct rchan_reader *
    +add_map_reader(int rchan_id);
    +
    +extern int
    +remove_map_reader(struct rchan_reader *reader);
    +
    +extern int
    +relay_info(int rchan_id, struct rchan_info *rchan_info);
    +
    +extern void
    +relay_buffers_consumed(struct rchan_reader *reader, u32 buffers_consumed);
    +
    +extern void
    +relay_bytes_consumed(struct rchan_reader *reader, u32 bytes_consumed, u32 read_offset);
    +
    +ssize_t
    +relay_bytes_avail(struct rchan_reader *reader);
    +
    +extern int
    +relay_realloc_buffer(int rchan_id, u32 new_nbufs, int in_background);
    +
    +extern int
    +relay_replace_buffer(int rchan_id);
    +
    +extern int
    +rchan_empty(struct rchan_reader *reader);
    +
    +extern int
    +rchan_full(struct rchan_reader *reader);
    +
    +extern void
    +update_readers_consumed(struct rchan *rchan, u32 bufs_consumed, u32 bytes_consumed);
    +
    +extern int
    +__relay_mmap_buffer(struct rchan *rchan, struct vm_area_struct *vma);
    +
    +struct rchan_reader *
    +__add_rchan_reader(struct rchan *rchan, struct file *filp, int auto_consume, int map_reader);
    +
    +extern void
    +__remove_rchan_reader(struct rchan_reader *reader);
    +
    +/*
    + * Low-level relayfs kernel API, fs/relayfs/relay.c
    + */
    +extern struct rchan *
    +rchan_get(int rchan_id);
    +
    +extern void
    +rchan_put(struct rchan *rchan);
    +
    +extern char *
    +relay_reserve(struct rchan *rchan,
    + u32 data_len,
    + struct timeval *time_stamp,
    + u32 *time_delta,
    + int *errcode,
    + int *interrupting);
    +
    +extern void
    +relay_commit(struct rchan *rchan,
    + char *from,
    + u32 len,
    + int reserve_code,
    + int interrupting);
    +
    +extern u32
    +relay_get_offset(struct rchan *rchan, u32 *max_offset);
    +
    +extern int
    +relay_reset(int rchan_id);
    +
    +/*
    + * VFS functions, fs/relayfs/inode.c
    + */
    +extern int
    +relayfs_create_dir(const char *name,
    + struct dentry *parent,
    + struct dentry **dentry);
    +
    +extern int
    +relayfs_create_file(const char * name,
    + struct dentry *parent,
    + struct dentry **dentry,
    + void * data,
    + int mode);
    +
    +extern int
    +relayfs_remove_file(struct dentry *dentry);
    +
    +extern int
    +reset_index(struct rchan *rchan, u32 old_index);
    +
    +
    +/*
    + * klog functions, fs/relayfs/klog.c
    + */
    +extern int
    +create_klog_channel(void);
    +
    +extern int
    +remove_klog_channel(void);
    +
    +/*
    + * Scheme-specific channel ops
    + */
    +struct relay_ops
    +{
    + char * (*reserve) (struct rchan *rchan,
    + u32 slot_len,
    + struct timeval *time_stamp,
    + u32 *tsc,
    + int * errcode,
    + int * interrupting);
    +
    + void (*commit) (struct rchan *rchan,
    + char *from,
    + u32 len,
    + int deliver,
    + int interrupting);
    +
    + u32 (*get_offset) (struct rchan *rchan,
    + u32 *max_offset);
    +
    + void (*resume) (struct rchan *rchan);
    + void (*finalize) (struct rchan *rchan);
    + void (*reset) (struct rchan *rchan,
    + int init);
    + int (*reset_index) (struct rchan *rchan,
    + u32 old_index);
    +};
    +
    +#endif /* _LINUX_RELAYFS_FS_H */
    +
    +
    +
    +
    +

    -- 
    Regards,
    Tom Zanussi <zanussi@us.ibm.com>
    IBM Linux Technology Center/RAS
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at  http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at  http://www.tux.org/lkml/
    

  • Next message: Markus Hästbacka: "[OT] Rootkit queston"

    Relevant Pages