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>