PERFORCE change 162206 for review
Zhao Shuai
zhaoshuai at FreeBSD.org
Sun May 17 12:26:34 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=162206
Change 162206 by zhaoshuai at zhaoshuai on 2009/05/17 12:25:57
some changes in the pipe code
first version of fifo, incomplete
Affected files ...
.. //depot/projects/soc2009/fifo/sys/fs/fifofs/fifo.c#2 edit
.. //depot/projects/soc2009/fifo/sys/kern/sys_pipe.c#2 edit
.. //depot/projects/soc2009/fifo/sys/sys/pipe.h#2 edit
Differences ...
==== //depot/projects/soc2009/fifo/sys/fs/fifofs/fifo.c#2 (text+ko) ====
@@ -54,7 +54,7 @@
static fo_close_t fifo_close_f;
static fo_truncate_t fifo_truncate_f;
-struct fileops file_ops_f = {
+struct fileops fifo_ops_f = {
.fo_read = fifo_read_f;
.fo_write = fifo_write_f;
.fo_truncate = fifo_truncate_f;
@@ -66,6 +66,50 @@
.fo_flags = DFLAG_PASSABLE
};
+/*
+ * This structure is associated with the FIFO vnode and stores
+ * the state associated with the FIFO.
+ */
+struct fifoinfo {
+ struct pipepair *fi_pp;
+ long fi_readers;
+ long fi_writers;
+};
+
+static vop_print_t fifo_print;
+static vop_open_t fifo_open;
+static vop_close_t fifo_close;
+static vop_pathconf_t fifo_pathconf;
+static vop_advlock_t fifo_advlock;
+
+struct vop_vector fifo_specops = {
+ .vop_default = &default_vndeops.
+ .vop_access = VOP_EBADF,
+ .vop_advlock = fifo_advlock,
+ .vop_close = fifo_close.
+ .vop_create = VOP_PANIC.
+ .vop_getattr = VOP_EBADF,
+ .vop_ioctl = VOP_PANIC,
+ .vop_kqfilter = VOP_PANIC,
+ .vop_lease = VOP_NULL,
+ .vop_link = VOP_PANIC,
+ .vop_mkdir = VOP_PANIC,
+ .vop_mknod = VOP_PANIC,
+ .vop_open = fifo_open,
+ .vop_pathconf = fifo_pathconf,
+ .vop_print = fifo_print,
+ .vop_read = VOP_PANIC,
+ .vop_readdir = VOP_PANIC,
+ .vop_readlink = VOP_PANIC,
+ .vop_reallocblks = VOP_PANIC,
+ .vop_reclaim = VOP_NULL,
+ .vop_remove = VOP_PANIC,
+ .vop_rename = VOP_PANIC,
+ .vop_rmdir = VOP_PANIC,
+ .vop_setattr = VOP_EBADF,
+ .vop_symlink = VOP_PANIC,
+ .vop_write = VOP_PANIC,
+};
/*
* Open called to set up a new instance of a fifo or
@@ -83,5 +127,181 @@
} */ *ap;
{
struct vnode *vp = ap->a_vp;
+ struct fifoinfo *fip;
+ struct thread *td = ap->a_td;
+ struct ucred *cred = ap->a_cred;
+ struct file *fp = ap->a_fp;
+ struct pipepair *pp;
+
+ ASSERT_VOP_ELOCKED(vp, "fifo_open");
+ if (fp == NULL)
+ return (EINVAL);
+ if ((fip = vp->v_fifoinfo) == NULL) {
+ fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
+ if ((pp = pipepair_create()) == NULL) {
+ free(fip, M_VNODE);
+ return (ENOMEM);
+ }
+ fip->fi_pp = pp;
+ fip->fi_readers = fip->fi_writers = 0;
+ KASSERT(vp->v_fifoinfo == NULL, ("fifo_open: v_fifoinfo race"));
+ vp->v_fifoinfo = fip;
+ }
+
+ /*
+ * General access to fi_readers and fi_writers is protected using
+ * the vnode lock.
+ */
+ if (ap->a_mode & FREAD)
+ fip->fi_readers++;
+ if (ap->a_mode & FWRITE) {
+ if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0)
+ return (ENXIO);
+ fip->fi_writers++;
+ }
+
+ KASSERT(fp != NULL, ("can't fifo/vnode bypass"));
+ KASSERT(fp->f_ops == &badfileops, ("not badfileops in fifo_open"));
+ finit(fp, fp->f_flag, DTYPE_FIFO, fip, &fifo_ops_f);
+ return (0);
+}
+
+/*
+ * Device close routine
+ */
+/* ARGSUSED */
+static int
+fifo_close(ap)
+ struct vop_close_args /* {
+ struct vnode *a_vp;
+ int a_fflag;
+ struct ucred *a_cred;
+ struct thread *a_td;
+ } */ ap;
+{
+ struct vnode *vp = ap->a_vp;
+ struct fifoinfo *fip = vp->v_fifoinfo;
+
+ ASSERT_VOP_ELOCKED(vp, "fifo_close");
+ if (ap->a_fflag & FREAD)
+ fip->fi_readers--;
+ if (ap->a_fflag & FWRITE)
+ fip->fi_writers--;
+ if (fip->fi_readers == 0 && fip->fi_writers == 0) {
+
+ }
+ return (0);
+}
+/*
+ * Print out the contents of a fifo vnode
+ */
+static int
+fifo_print(ap)
+ struct vop_print_args /* {
+ struct vnode *a_vp;
+ } */ ap;
+{
+ struct fifoinfo *fip = ap->a_vp->v_fifoinfo;
+
+ if (fip == NULL) {
+ printf(", NULL v_fifoinfo");
+ return (0);
+ }
+ printf(", fifo with %ld readers and %ld writers",
+ fip->fi_readers, fip->fi_writers);
+ printf("\n");
+ return (0);
+}
+
+/*
+ * Return POSIX pathconf information applicable to fifo's.
+ */
+static int
+fifo_pathconf(ap)
+ struct vop_pathconf_args /* {
+ struct vnode *a_vp;
+ int a_name;
+ int *a_retval;
+ } */ *ap;
+{
+ return (0);
+}
+
+/*
+ * FIFO advisory byte-level locks.
+ */
+static int
+fifo_advlock(ap)
+ struct vop_advlock_args /* {
+ struct vnode *a_vp;
+ caddr_t a_id;
+ int a_op;
+ struct flock *a_fl;
+ int a_flags;
+ } */ *ap;
+{
+ return (ap->a_flags & F_FLOCK ? EOPNOTSUPPP : EINVAL);
}
+
+static int
+fifo_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
+{
+ int error;
+ struct fifoinfo *fip = fp->f_data;
+ fp->f_data = &fip->fi_pp->rpipe;
+ error = pipe_read(fp, uio, cred, flags, td);
+ fp->f_data = fip;
+
+ return (error);
+}
+
+static int
+fifo_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
+{
+ int error;
+ struct fifoinfo *fip = fp->f_data;
+ fp->f_data = &fip->fi_pp->wpipe;
+ error = pipe_write(fp, uio, cred, flags, td);
+ fp->f_data = fip;
+
+ return (error);
+}
+
+static int
+fifo_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
+{
+ return (vnops.fo_stat(fp, sb, cred, td));
+}
+
+static int
+fifo_truncate_f(struct file *fp, off_t length, struct ucred *cred, struct thread *td)
+{
+ return (vnops.fo_truncate(fp, length, cred, td));
+}
+
+static int
+fifo_close_f(struct file *fp, struct thread *td)
+{
+ return (vnops.fo_close(fp, td));
+}
+
+static int
+fifo_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred,
+ struct thread *td)
+{
+ return (0);
+}
+
+static int
+fifo_kqfilter_f(struct file *fp, struct knote *kn)
+{
+ return (0);
+}
+
+static int
+fifo_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
+{
+ return (0);
+}
+
==== //depot/projects/soc2009/fifo/sys/kern/sys_pipe.c#2 (text+ko) ====
@@ -138,9 +138,12 @@
/*
* interfaces to the outside world
+ * pipe_read and pipe_write is no longer static, they are used by FIFO
*/
-static fo_rdwr_t pipe_read;
-static fo_rdwr_t pipe_write;
+/*
+fo_rdwr_t pipe_read;
+fo_rdwr_t pipe_write;
+*/
static fo_truncate_t pipe_truncate;
static fo_ioctl_t pipe_ioctl;
static fo_poll_t pipe_poll;
@@ -562,7 +565,7 @@
}
/* ARGSUSED */
-static int
+int
pipe_read(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
@@ -964,7 +967,7 @@
}
#endif
-static int
+int
pipe_write(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
@@ -1641,3 +1644,36 @@
PIPE_UNLOCK(rpipe);
return (kn->kn_data >= PIPE_BUF);
}
+
+/*
+ * The following functions are used by FIFO
+ * see fs/fifo_vnops.c
+ */
+struct pipepair *
+pipepair_create(void)
+{
+ struct pipepair *pp;
+ struct pipe *rpipe, *wpipe;
+
+ pp = uma_zalloc(pipe_zone, M_WAITOK);
+ rpipe = &pp->pp_rpipe;
+ wpipe = &pp->pp_wpipe;
+
+ /* TODO: do we really need this ? */
+ knlist_init(&rpipe->pipe_sel.si_note, PIPE_MTX(rpipe), NULL, NULL,
+ NULL);
+ knlist_init(&wpipe->pipe_sel.si_note, PIPE_MTX(wpipe), NULL, NULL,
+ NULL);
+
+ if (pipe_create(rpipe, 1) != 0 ||
+ pipe_create(wpipe, 0) != 0) {
+ pipeclose(rpipe);
+ pipeclose(wpipe);
+ return NULL;
+ }
+
+ rpipe->pipe_state |= PIPE_DIRECTOK;
+ wpipe->pipe_state |= PIPE_DIRECTOK;
+
+ return pp;
+}
==== //depot/projects/soc2009/fifo/sys/sys/pipe.h#2 (text+ko) ====
@@ -28,6 +28,8 @@
#error "no user-servicable parts inside"
#endif
+#include <sys/file.h>
+
/*
* Pipe buffer size, keep moderate in value, pipes take kva space.
*/
@@ -137,5 +139,13 @@
#define PIPE_UNLOCK(pipe) mtx_unlock(PIPE_MTX(pipe))
#define PIPE_LOCK_ASSERT(pipe, type) mtx_assert(PIPE_MTX(pipe), (type))
+/*
+ * The following functions are used by FIFO,
+ * see fs/fifo_vnops.c
+ */
+struct pipepair *pipepair_create(void);
+fo_rdwr_t pipe_read;
+fo_rdwr_t pipe_write;
+
#endif /* !_SYS_PIPE_H_ */
More information about the p4-projects
mailing list