root/usr/src/uts/common/sys/fs/fifonode.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/*        All Rights Reserved   */


#ifndef _SYS_FS_FIFONODE_H
#define _SYS_FS_FIFONODE_H

#if defined(_KERNEL)
#include <sys/vfs_opreg.h>
#endif

#ifdef  __cplusplus
extern "C" {
#endif


/*
 * Each FIFOFS object is identified by a struct fifonode/vnode pair.
 * This is also the hierarchy
 * flk_lock protects:
 *              fn_mp
 *              fn_tail
 *              fn_count
 *              fn_flag
 *              fn_wcnt
 *              fn_rcnt
 *              fn_open
 *              fn_rsynccnt
 *              fn_wsynccnt
 *              fn_wwaitcnt
 *              fn_atime
 *              fn_mtime
 *              fn_ctime
 *              fn_insync
 *              flk_ref
 *              flk_ocsync
 * ftable lock protects         - actually this is independent
 *              fifoalloc[]
 *              fn_nextp
 *              fn_backp
 */
typedef struct fifolock {
        kmutex_t        flk_lock;       /* fifo lock */
        int             flk_ref;        /* number of fifonodes using this */
        short           flk_ocsync;     /* sync open/close */
        kcondvar_t      flk_wait_cv;    /* conditional for flk_ocsync */
        uint_t          flk_fill[4];    /* cache align lock structure */
} fifolock_t;

typedef struct fifonode fifonode_t;

struct fifonode {
        struct vnode    *fn_vnode;      /* represents the fifo/pipe */
        struct vnode    *fn_realvp;     /* node being shadowed by fifo */
        ino_t           fn_ino;         /* node id for pipes */
        fifonode_t      *fn_dest;       /* the other end of a pipe */
        struct msgb     *fn_mp;         /* message waiting to be read */
        struct msgb     *fn_tail;       /* last message to read */
        fifolock_t      *fn_lock;       /* pointer to per fifo lock */
        uint_t          fn_count;       /* Number of bytes on fn_mp */
        kcondvar_t      fn_wait_cv;     /* fifo conditional variable */
        ushort_t        fn_wcnt;        /* number of writers */
        ushort_t        fn_rcnt;        /* number of readers */
        ushort_t        fn_open;        /* open count of node */
        ushort_t        fn_wsynccnt;    /* fifos waiting for open write sync */
        ushort_t        fn_rsynccnt;    /* fifos waiting for open read sync */
        ushort_t        fn_wwaitcnt;    /* threads waiting to write data */
        timestruc_t     fn_atime;       /* access times */
        timestruc_t     fn_mtime;       /* modification time */
        timestruc_t     fn_ctime;       /* change time */
        fifonode_t      *fn_nextp;      /* next link in the linked list */
        fifonode_t      *fn_backp;      /* back link in linked list */
        struct cred     *fn_pcredp;     /* credential associated with peer */
        pid_t           fn_cpid;        /* original peer pid */
        int             fn_insync;
        uint_t          fn_flag;        /* flags as defined below */
};


typedef struct fifodata {
        fifolock_t      fifo_lock;
        fifonode_t      fifo_fnode[2];
} fifodata_t;

/*
 * Valid flags for fifonodes.
 */
#define ISPIPE          0x0001  /* fifonode is that of a pipe */
#define FIFOSEND        0x0002  /* file descriptor at stream head of pipe */
#define FIFOOPEN        0x0004  /* fifo is opening */
#define FIFOCLOSE       0x0008  /* fifo is closing */
#define FIFOCONNLD      0x0010  /* connld pushed on pipe */
#define FIFOFAST        0x0020  /* FIFO in fast mode */
#define FIFOWANTR       0x0040  /* reader waiting for data */
#define FIFOWANTW       0x0080  /* writer waiting to write */
#define FIFOSETSIG      0x0100  /* I_SETSIG ioctl was issued */
#define FIFOHIWATW      0x0200  /* We have gone over hi water mark */
#define FIFORWBUSY      0x0400  /* Fifo is busy in read or write */
#define FIFOPOLLW       0x0800  /* process waiting on poll write */
#define FIFOPOLLR       0x1000  /* process waiting on poll read */
#define FIFOISOPEN      0x2000  /* pipe is open */
#define FIFOSYNC        0x4000  /* FIFO is waiting for open sync */
#define FIFOWOCR        0x8000  /* Write open occurred */
#define FIFOROCR        0x10000 /* Read open occurred */
/*
 * process waiting on poll read on band data
 * this can only occur if we go to streams
 * mode
 */
#define FIFOPOLLRBAND   0x20000
#define FIFOSTAYFAST    0x40000 /* don't turn into stream mode */
#define FIFOWAITMODE    0x80000 /* waiting for the possibility to change mode */

#define FIFOHIWAT       (16 * 1024)
#define FIFOLOWAT       (0)

/*
 * Macros to convert a vnode to a fifnode, and vice versa.
 */
#define VTOF(vp) ((struct fifonode *)((vp)->v_data))
#define FTOV(fp) ((fp)->fn_vnode)

#if defined(_KERNEL)

/*
 * Fifohiwat defined as a variable is to allow tuning of the high
 * water mark if needed. It is not meant to be released.
 */
#if FIFODEBUG
extern int Fifohiwat;
#else /* FIFODEBUG */
#define Fifohiwat       FIFOHIWAT
#endif /* FIFODEBUG */

extern struct vnodeops *fifo_vnodeops;
extern const struct fs_operation_def fifo_vnodeops_template[];
extern struct kmem_cache *fnode_cache;
extern struct kmem_cache *pipe_cache;

struct vfssw;
struct queue;

extern int      fifoinit(int, char *);
extern int      fifo_stropen(vnode_t **, int, cred_t *, int, int);
extern int      fifo_open(vnode_t **, int, cred_t *, caller_context_t *);
extern int      fifo_close(vnode_t *, int, int, offset_t, cred_t *,
                        caller_context_t *);
extern void     fifo_cleanup(vnode_t *, int);
extern void     fiforemove(fifonode_t *);
extern ino_t    fifogetid(void);
extern vnode_t  *fifovp(vnode_t *, cred_t *);
extern void     makepipe(vnode_t **, vnode_t **);
extern void     fifo_fastflush(fifonode_t *);
extern void     fifo_vfastoff(vnode_t *);
extern void     fifo_fastoff(fifonode_t *);
extern struct streamtab *fifo_getinfo();
extern void     fifo_wakereader(fifonode_t *, fifolock_t *);
extern void     fifo_wakewriter(fifonode_t *, fifolock_t *);

#endif /* _KERNEL */

#ifdef  __cplusplus
}
#endif

#endif  /* _SYS_FS_FIFONODE_H */