Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 May 2009 12:26:33 GMT
From:      Zhao Shuai <zhaoshuai@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 162206 for review
Message-ID:  <200905171226.n4HCQXS9011874@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=162206

Change 162206 by zhaoshuai@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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905171226.n4HCQXS9011874>