Author: kib
Date: Wed Mar  7 07:31:50 2012
New Revision: 232641
URL: http://svn.freebsd.org/changeset/base/232641

Log:
  The pipe_poll() performs lockless access to the vnode to test
  fifo_iseof() condition, allowing the v_fifoinfo to be reset and freed
  by fifo_cleanup().
  
  Precalculate EOF at the places were fo_wgen is changed, and cache the
  state in a new pipe state flag PIPE_SAMEWGEN.
  
  Reported and tested by:       bf
  Submitted by: gianni
  MFC after:    1 week (a backport)

Modified:
  head/sys/fs/fifofs/fifo.h
  head/sys/fs/fifofs/fifo_vnops.c
  head/sys/kern/sys_pipe.c
  head/sys/sys/pipe.h

Modified: head/sys/fs/fifofs/fifo.h
==============================================================================
--- head/sys/fs/fifofs/fifo.h   Wed Mar  7 07:22:53 2012        (r232640)
+++ head/sys/fs/fifofs/fifo.h   Wed Mar  7 07:31:50 2012        (r232641)
@@ -33,7 +33,6 @@
 /*
  * Prototypes for fifo operations on vnodes.
  */
-int    fifo_iseof(struct file *);
 int    fifo_vnoperate(struct vop_generic_args *);
 int    fifo_printinfo(struct vnode *);
 

Modified: head/sys/fs/fifofs/fifo_vnops.c
==============================================================================
--- head/sys/fs/fifofs/fifo_vnops.c     Wed Mar  7 07:22:53 2012        
(r232640)
+++ head/sys/fs/fifofs/fifo_vnops.c     Wed Mar  7 07:31:50 2012        
(r232641)
@@ -67,8 +67,16 @@ struct fifoinfo {
        long    fi_readers;
        long    fi_writers;
        int     fi_wgen;
+       int     fi_seqcount;
 };
 
+#define FIFO_UPDWGEN(fip, pip) do { \
+       if ((fip)->fi_wgen == (fip)->fi_seqcount)                       \
+               (pip)->pipe_state |= PIPE_SAMEWGEN;                     \
+       else                                                            \
+               (pip)->pipe_state &= ~PIPE_SAMEWGEN;                    \
+} while (0)
+
 static vop_print_t     fifo_print;
 static vop_open_t      fifo_open;
 static vop_close_t     fifo_close;
@@ -174,7 +182,8 @@ fifo_open(ap)
                        if (fip->fi_writers > 0)
                                wakeup(&fip->fi_writers);
                }
-               fp->f_seqcount = fip->fi_wgen - fip->fi_writers;
+               fip->fi_seqcount = fip->fi_wgen - fip->fi_writers;
+               FIFO_UPDWGEN(fip, fpipe);
        }
        if (ap->a_mode & FWRITE) {
                if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
@@ -228,6 +237,7 @@ fifo_open(ap)
                                        if (fpipe->pipe_state & PIPE_WANTR)
                                                wakeup(fpipe);
                                        fip->fi_wgen++;
+                                       FIFO_UPDWGEN(fip, fpipe);
                                        PIPE_UNLOCK(fpipe);
                                        fifo_cleanup(vp);
                                }
@@ -287,6 +297,7 @@ fifo_close(ap)
                        if (cpipe->pipe_state & PIPE_WANTR)
                                wakeup(cpipe);
                        fip->fi_wgen++;
+                       FIFO_UPDWGEN(fip, cpipe);
                        PIPE_UNLOCK(cpipe);
                }
        }
@@ -373,15 +384,3 @@ fifo_advlock(ap)
        return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
 }
 
-int
-fifo_iseof(struct file *fp)
-{
-       struct fifoinfo *fip;
-
-       KASSERT(fp->f_vnode != NULL, ("fifo_iseof: no vnode info"));
-       KASSERT(fp->f_vnode->v_fifoinfo != NULL, ("fifo_iseof: no fifoinfo"));
-       fip = fp->f_vnode->v_fifoinfo;
-       PIPE_LOCK_ASSERT(fip->fi_pipe, MA_OWNED);
-       return (fp->f_seqcount == fip->fi_wgen);
-}
-

Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c    Wed Mar  7 07:22:53 2012        (r232640)
+++ head/sys/kern/sys_pipe.c    Wed Mar  7 07:31:50 2012        (r232641)
@@ -1430,7 +1430,7 @@ pipe_poll(fp, events, active_cred, td)
        levents = events &
            (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
        if (rpipe->pipe_state & PIPE_NAMED && fp->f_flag & FREAD && levents &&
-           fifo_iseof(fp))
+           rpipe->pipe_state & PIPE_SAMEWGEN)
                events |= POLLINIGNEOF;
 
        if ((events & POLLINIGNEOF) == 0) {

Modified: head/sys/sys/pipe.h
==============================================================================
--- head/sys/sys/pipe.h Wed Mar  7 07:22:53 2012        (r232640)
+++ head/sys/sys/pipe.h Wed Mar  7 07:31:50 2012        (r232641)
@@ -96,6 +96,7 @@ struct pipemapping {
 #define PIPE_DIRECTW   0x400   /* Pipe direct write active. */
 #define PIPE_DIRECTOK  0x800   /* Direct mode ok. */
 #define PIPE_NAMED     0x1000  /* Is a named pipe. */
+#define PIPE_SAMEWGEN  0x2000  /* same write generation for named pipes. */
 
 /*
  * Per-pipe data structure.
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to