Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Aug 2002 01:50:31 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        stable@freebsd.org
Cc:        jlemon@freebsd.org
Subject:   PATCH2: Better kqueue patches
Message-ID:  <3D5E0E57.3CCF4F70@mindspring.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------28F74B3623B344F226551D0F
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

OK, these patches still add support for System V message queue
integration into kqueue.  They also fix the problems I noted
before, by adding a third parameter to KNOTE(), and fixing up
the kn_fop->f_event() functions to take a third parameter.

This fixes the message queue ID > 65536 problem, and also fixes
the event/hint mux problem with signal and proc notes (particularly,
it allows for more than 20 bits of PID, if that's ever considered
desirable at some point).

It also adds support for a virtual event, if the System V message
queue was not empty when the filter is first attached, to avoid
the need to do the poll-after-attach, and to poll on reads to avoid
the potential race condition (you would still need this for multiple
readers on the same queue, though... obviously).

I think this code is OK to commit, if someone want to review it and
commit it.

Context diffs vs. -STABLE attached.

-- Terry
--------------28F74B3623B344F226551D0F
Content-Type: text/plain; charset=us-ascii;
 name="kqueue.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="kqueue.diff"

Index: kern/kern_event.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.2.2.8
diff -c -r1.2.2.8 kern_event.c
*** kern/kern_event.c	14 Dec 2001 19:24:42 -0000	1.2.2.8
--- kern/kern_event.c	17 Aug 2002 06:41:39 -0000
***************
*** 86,100 ****
  static void 	knote_free(struct knote *kn);
  
  static void	filt_kqdetach(struct knote *kn);
! static int	filt_kqueue(struct knote *kn, long hint);
  static int	filt_procattach(struct knote *kn);
  static void	filt_procdetach(struct knote *kn);
! static int	filt_proc(struct knote *kn, long hint);
  static int	filt_fileattach(struct knote *kn);
  static void	filt_timerexpire(void *knx);
  static int	filt_timerattach(struct knote *kn);
  static void	filt_timerdetach(struct knote *kn);
! static int	filt_timer(struct knote *kn, long hint);
  
  static struct filterops file_filtops =
  	{ 1, filt_fileattach, NULL, NULL };
--- 86,100 ----
  static void 	knote_free(struct knote *kn);
  
  static void	filt_kqdetach(struct knote *kn);
! static int	filt_kqueue(struct knote *kn, long hint, long id);
  static int	filt_procattach(struct knote *kn);
  static void	filt_procdetach(struct knote *kn);
! static int	filt_proc(struct knote *kn, long hint, long id);
  static int	filt_fileattach(struct knote *kn);
  static void	filt_timerexpire(void *knx);
  static int	filt_timerattach(struct knote *kn);
  static void	filt_timerdetach(struct knote *kn);
! static int	filt_timer(struct knote *kn, long hint, long id);
  
  static struct filterops file_filtops =
  	{ 1, filt_fileattach, NULL, NULL };
***************
*** 122,127 ****
--- 122,128 ----
  
  extern struct filterops aio_filtops;
  extern struct filterops sig_filtops;
+ extern struct filterops sysvmsg_filtops;
  
  /*
   * Table for for all system-defined filters.
***************
*** 134,139 ****
--- 135,141 ----
  	&proc_filtops,			/* EVFILT_PROC */
  	&sig_filtops,			/* EVFILT_SIGNAL */
  	&timer_filtops,			/* EVFILT_TIMER */
+ 	&sysvmsg_filtops,		/* EVFILT_SYSVMSG */
  };
  
  static int
***************
*** 167,173 ****
  
  /*ARGSUSED*/
  static int
! filt_kqueue(struct knote *kn, long hint)
  {
  	struct kqueue *kq = (struct kqueue *)kn->kn_fp->f_data;
  
--- 169,175 ----
  
  /*ARGSUSED*/
  static int
! filt_kqueue(struct knote *kn, long hint, long id)
  {
  	struct kqueue *kq = (struct kqueue *)kn->kn_fp->f_data;
  
***************
*** 225,231 ****
  }
  
  static int
! filt_proc(struct knote *kn, long hint)
  {
  	u_int event;
  
--- 227,233 ----
  }
  
  static int
! filt_proc(struct knote *kn, long hint, long id)
  {
  	u_int event;
  
***************
*** 261,267 ****
  		/*
  		 * register knote with new process.
  		 */
! 		kev.ident = hint & NOTE_PDATAMASK;	/* pid */
  		kev.filter = kn->kn_filter;
  		kev.flags = kn->kn_flags | EV_ADD | EV_ENABLE | EV_FLAG1;
  		kev.fflags = kn->kn_sfflags;
--- 263,269 ----
  		/*
  		 * register knote with new process.
  		 */
! 		kev.ident = id;				/* pid */
  		kev.filter = kn->kn_filter;
  		kev.flags = kn->kn_flags | EV_ADD | EV_ENABLE | EV_FLAG1;
  		kev.fflags = kn->kn_sfflags;
***************
*** 335,341 ****
  }
  
  static int
! filt_timer(struct knote *kn, long hint)
  {
  
  	return (kn->kn_data != 0);
--- 337,343 ----
  }
  
  static int
! filt_timer(struct knote *kn, long hint, long id)
  {
  
  	return (kn->kn_data != 0);
***************
*** 542,548 ****
  		}
  
  		s = splhigh();
! 		if (kn->kn_fop->f_event(kn, 0))
  			KNOTE_ACTIVATE(kn);
  		splx(s);
  
--- 544,550 ----
  		}
  
  		s = splhigh();
! 		if (kn->kn_fop->f_event(kn, 0, 0))
  			KNOTE_ACTIVATE(kn);
  		splx(s);
  
***************
*** 656,662 ****
  			continue;
  		}
  		if ((kn->kn_flags & EV_ONESHOT) == 0 &&
! 		    kn->kn_fop->f_event(kn, 0) == 0) {
  			kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
  			kq->kq_count--;
  			continue;
--- 658,664 ----
  			continue;
  		}
  		if ((kn->kn_flags & EV_ONESHOT) == 0 &&
! 		    kn->kn_fop->f_event(kn, 0, 0) == 0) {
  			kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
  			kq->kq_count--;
  			continue;
***************
*** 823,841 ****
  		kq->kq_state &= ~KQ_SEL;
  		selwakeup(&kq->kq_sel);
  	}
! 	KNOTE(&kq->kq_sel.si_note, 0);
  }
  
  /*
   * walk down a list of knotes, activating them if their event has triggered.
   */
  void
! knote(struct klist *list, long hint)
  {
  	struct knote *kn;
  
  	SLIST_FOREACH(kn, list, kn_selnext)
! 		if (kn->kn_fop->f_event(kn, hint))
  			KNOTE_ACTIVATE(kn);
  }
  
--- 825,843 ----
  		kq->kq_state &= ~KQ_SEL;
  		selwakeup(&kq->kq_sel);
  	}
! 	KNOTE(&kq->kq_sel.si_note, 0, 0);
  }
  
  /*
   * walk down a list of knotes, activating them if their event has triggered.
   */
  void
! knote(struct klist *list, long hint, long id)
  {
  	struct knote *kn;
  
  	SLIST_FOREACH(kn, list, kn_selnext)
! 		if (kn->kn_fop->f_event(kn, hint, id))
  			KNOTE_ACTIVATE(kn);
  }
  
Index: kern/kern_exec.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_exec.c,v
retrieving revision 1.107.2.15
diff -c -r1.107.2.15 kern_exec.c
*** kern/kern_exec.c	30 Jul 2002 15:40:46 -0000	1.107.2.15
--- kern/kern_exec.c	17 Aug 2002 06:39:09 -0000
***************
*** 366,372 ****
           * Notify others that we exec'd, and clear the P_INEXEC flag
           * as we're now a bona fide freshly-execed process.
           */
! 	KNOTE(&p->p_klist, NOTE_EXEC);
  	p->p_flag &= ~P_INEXEC;
  
  	/*
--- 366,372 ----
           * Notify others that we exec'd, and clear the P_INEXEC flag
           * as we're now a bona fide freshly-execed process.
           */
! 	KNOTE(&p->p_klist, NOTE_EXEC, 0);
  	p->p_flag &= ~P_INEXEC;
  
  	/*
Index: kern/kern_exit.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.92.2.10
diff -c -r1.92.2.10 kern_exit.c
*** kern/kern_exit.c	29 Apr 2002 09:42:35 -0000	1.92.2.10
--- kern/kern_exit.c	17 Aug 2002 06:40:30 -0000
***************
*** 320,326 ****
  	/*
  	 * notify interested parties of our demise.
  	 */
! 	KNOTE(&p->p_klist, NOTE_EXIT);
  
  	/*
  	 * Notify parent that we're gone.  If parent has the PS_NOCLDWAIT
--- 320,326 ----
  	/*
  	 * notify interested parties of our demise.
  	 */
! 	KNOTE(&p->p_klist, NOTE_EXIT, 0);
  
  	/*
  	 * Notify parent that we're gone.  If parent has the PS_NOCLDWAIT
Index: kern/kern_fork.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.72.2.11
diff -c -r1.72.2.11 kern_fork.c
*** kern/kern_fork.c	30 Jul 2002 19:05:00 -0000	1.72.2.11
--- kern/kern_fork.c	17 Aug 2002 06:41:00 -0000
***************
*** 528,534 ****
  	/*
  	 * tell any interested parties about the new process
  	 */
! 	KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid);
  
  	/*
  	 * Preserve synchronization semantics of vfork.  If waiting for
--- 528,534 ----
  	/*
  	 * tell any interested parties about the new process
  	 */
! 	KNOTE(&p1->p_klist, NOTE_FORK, p2->p_pid);
  
  	/*
  	 * Preserve synchronization semantics of vfork.  If waiting for
Index: kern/kern_sig.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.72.2.16
diff -c -r1.72.2.16 kern_sig.c
*** kern/kern_sig.c	3 Jul 2002 14:43:27 -0000	1.72.2.16
--- kern/kern_sig.c	17 Aug 2002 06:43:10 -0000
***************
*** 84,90 ****
  
  static int	filt_sigattach(struct knote *kn);
  static void	filt_sigdetach(struct knote *kn);
! static int	filt_signal(struct knote *kn, long hint);
  
  struct filterops sig_filtops =
  	{ 0, filt_sigattach, filt_sigdetach, filt_signal };
--- 84,90 ----
  
  static int	filt_sigattach(struct knote *kn);
  static void	filt_sigdetach(struct knote *kn);
! static int	filt_signal(struct knote *kn, long hint, long id);
  
  struct filterops sig_filtops =
  	{ 0, filt_sigattach, filt_sigdetach, filt_signal };
***************
*** 1012,1018 ****
  	}
  
  	s = splhigh();
! 	KNOTE(&p->p_klist, NOTE_SIGNAL | sig);
  	splx(s);
  
  	prop = sigprop(sig);
--- 1012,1018 ----
  	}
  
  	s = splhigh();
! 	KNOTE(&p->p_klist, NOTE_SIGNAL, sig);
  	splx(s);
  
  	prop = sigprop(sig);
***************
*** 1748,1760 ****
   * isn't worth the trouble.
   */
  static int
! filt_signal(struct knote *kn, long hint)
  {
  
  	if (hint & NOTE_SIGNAL) {
! 		hint &= ~NOTE_SIGNAL;
! 
! 		if (kn->kn_id == hint)
  			kn->kn_data++;
  	}
  	return (kn->kn_data != 0);
--- 1748,1758 ----
   * isn't worth the trouble.
   */
  static int
! filt_signal(struct knote *kn, long hint, long id)
  {
  
  	if (hint & NOTE_SIGNAL) {
! 		if (kn->kn_id == id)
  			kn->kn_data++;
  	}
  	return (kn->kn_data != 0);
Index: kern/sys_pipe.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/sys_pipe.c,v
retrieving revision 1.60.2.13
diff -c -r1.60.2.13 sys_pipe.c
*** kern/sys_pipe.c	5 Aug 2002 15:05:15 -0000	1.60.2.13
--- kern/sys_pipe.c	17 Aug 2002 06:44:40 -0000
***************
*** 105,112 ****
  };
  
  static void	filt_pipedetach(struct knote *kn);
! static int	filt_piperead(struct knote *kn, long hint);
! static int	filt_pipewrite(struct knote *kn, long hint);
  
  static struct filterops pipe_rfiltops =
  	{ 1, NULL, filt_pipedetach, filt_piperead };
--- 105,112 ----
  };
  
  static void	filt_pipedetach(struct knote *kn);
! static int	filt_piperead(struct knote *kn, long hint, long id);
! static int	filt_pipewrite(struct knote *kn, long hint, long id);
  
  static struct filterops pipe_rfiltops =
  	{ 1, NULL, filt_pipedetach, filt_piperead };
***************
*** 382,388 ****
  	}
  	if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_sigio)
  		pgsigio(cpipe->pipe_sigio, SIGIO, 0);
! 	KNOTE(&cpipe->pipe_sel.si_note, 0);
  }
  
  /* ARGSUSED */
--- 382,388 ----
  	}
  	if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_sigio)
  		pgsigio(cpipe->pipe_sigio, SIGIO, 0);
! 	KNOTE(&cpipe->pipe_sel.si_note, 0, 0);
  }
  
  /* ARGSUSED */
***************
*** 1213,1219 ****
  
  			ppipe->pipe_state |= PIPE_EOF;
  			wakeup(ppipe);
! 			KNOTE(&ppipe->pipe_sel.si_note, 0);
  			ppipe->pipe_peer = NULL;
  		}
  		/*
--- 1213,1219 ----
  
  			ppipe->pipe_state |= PIPE_EOF;
  			wakeup(ppipe);
! 			KNOTE(&ppipe->pipe_sel.si_note, 0, 0);
  			ppipe->pipe_peer = NULL;
  		}
  		/*
***************
*** 1260,1266 ****
  
  /*ARGSUSED*/
  static int
! filt_piperead(struct knote *kn, long hint)
  {
  	struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
  	struct pipe *wpipe = rpipe->pipe_peer;
--- 1260,1266 ----
  
  /*ARGSUSED*/
  static int
! filt_piperead(struct knote *kn, long hint, long id)
  {
  	struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
  	struct pipe *wpipe = rpipe->pipe_peer;
***************
*** 1279,1285 ****
  
  /*ARGSUSED*/
  static int
! filt_pipewrite(struct knote *kn, long hint)
  {
  	struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
  	struct pipe *wpipe = rpipe->pipe_peer;
--- 1279,1285 ----
  
  /*ARGSUSED*/
  static int
! filt_pipewrite(struct knote *kn, long hint, long id)
  {
  	struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
  	struct pipe *wpipe = rpipe->pipe_peer;
Index: kern/sysv_msg.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/sysv_msg.c,v
retrieving revision 1.23.2.3
diff -c -r1.23.2.3 sysv_msg.c
*** kern/sysv_msg.c	1 Nov 2000 17:58:06 -0000	1.23.2.3
--- kern/sysv_msg.c	17 Aug 2002 06:48:29 -0000
***************
*** 40,45 ****
--- 40,46 ----
  #undef MSG_DEBUG_OK
  
  static void msg_freehdr __P((struct msg *msghdr));
+ static struct msqid_ds *msqid_to_msqptr __P((int umsqid));
  
  /* XXX casting to (sy_call_t *) is bogus, as usual. */
  static sy_call_t *msgcalls[] = {
***************
*** 112,118 ****
      				/* 0..(MSGSEG-1) -> index of next segment */
  };
  
! #define MSG_LOCKED	01000	/* Is this msqid_ds locked? */
  
  static int nfree_msgmaps;	/* # of free map entries */
  static short free_msgmaps;	/* head of linked list of free map entries */
--- 113,124 ----
      				/* 0..(MSGSEG-1) -> index of next segment */
  };
  
! struct i_msqid_ds {
! 	struct msqid_ds	e;		/* externally visable */
! 	struct klist	q_klist;	/* filters on this message queue */
! };
! 
! #define MSG_LOCKED	01000	/* Is this i_msqid_ds locked? */
  
  static int nfree_msgmaps;	/* # of free map entries */
  static short free_msgmaps;	/* head of linked list of free map entries */
***************
*** 120,126 ****
  static char *msgpool;		/* MSGMAX byte long msg buffer pool */
  static struct msgmap *msgmaps;	/* MSGSEG msgmap structures */
  static struct msg *msghdrs;	/* MSGTQL msg headers */
! static struct msqid_ds *msqids;	/* MSGMNI msqid_ds struct's */
  
  static void
  msginit(dummy)
--- 126,132 ----
  static char *msgpool;		/* MSGMAX byte long msg buffer pool */
  static struct msgmap *msgmaps;	/* MSGSEG msgmap structures */
  static struct msg *msghdrs;	/* MSGTQL msg headers */
! static struct i_msqid_ds *i_msqids;	/* MSGMNI i_msqid_ds struct's */
  
  static void
  msginit(dummy)
***************
*** 137,145 ****
  	msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
  	if (msghdrs == NULL)
  		panic("msghdrs is NULL");
! 	msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK);
! 	if (msqids == NULL)
! 		panic("msqids is NULL");
  
  	/*
  	 * msginfo.msgssz should be a power of two for efficiency reasons.
--- 143,151 ----
  	msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
  	if (msghdrs == NULL)
  		panic("msghdrs is NULL");
! 	i_msqids = malloc(sizeof(struct i_msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK);
! 	if (i_msqids == NULL)
! 		panic("i_msqids is NULL");
  
  	/*
  	 * msginfo.msgssz should be a power of two for efficiency reasons.
***************
*** 183,195 ****
      	}
  	free_msghdrs = &msghdrs[0];
  
! 	if (msqids == NULL)
! 		panic("msqids is NULL");
  
  	for (i = 0; i < msginfo.msgmni; i++) {
! 		msqids[i].msg_qbytes = 0;	/* implies entry is available */
! 		msqids[i].msg_perm.seq = 0;	/* reset to a known value */
! 		msqids[i].msg_perm.mode = 0;
  	}
  }
  SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL)
--- 189,201 ----
      	}
  	free_msghdrs = &msghdrs[0];
  
! 	if (i_msqids == NULL)
! 		panic("i_msqids is NULL");
  
  	for (i = 0; i < msginfo.msgmni; i++) {
! 		i_msqids[i].e.msg_qbytes = 0;	/* implies entry is available */
! 		i_msqids[i].e.msg_perm.seq = 0;	/* reset to a known value */
! 		i_msqids[i].e.msg_perm.mode = 0;
  	}
  }
  SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL)
***************
*** 243,248 ****
--- 249,288 ----
  	free_msghdrs = msghdr;
  }
  
+ static struct msqid_ds *   
+ msqid_to_msqptr(umsqid)
+ 	int umsqid;
+ {
+ 	int msqid;
+ 	struct msqid_ds *msqptr = 0;
+ 
+ 	msqid = IPCID_TO_IX(umsqid);
+ 
+ 	if (msqid < 0 || msqid >= msginfo.msgmni) {
+ #ifdef MSG_DEBUG_OK
+ 		printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
+ 		    msginfo.msgmni);
+ #endif
+ 	} else {
+ 
+ 		msqptr = (struct msqid_ds *)&i_msqids[msqid];
+ 
+ 		if (msqptr->msg_qbytes == 0) {
+ #ifdef MSG_DEBUG_OK
+ 			printf("no such msqid\n");
+ #endif
+ 			msqptr = NULL;
+ 		} else if (msqptr->msg_perm.seq != IPCID_TO_SEQ(umsqid)) {
+ #ifdef MSG_DEBUG_OK
+ 			printf("wrong sequence number\n");
+ 			msqptr = NULL;
+ #endif
+ 		}
+ 	}
+ 
+ 	return(msqptr);
+ }
+ 
  #ifndef _SYS_SYSPROTO_H_
  struct msgctl_args {
  	int	msqid;
***************
*** 256,262 ****
  	struct proc *p;
  	register struct msgctl_args *uap;
  {
- 	int msqid = uap->msqid;
  	int cmd = uap->cmd;
  	struct msqid_ds *user_msqptr = uap->buf;
  	int rval, eval;
--- 296,301 ----
***************
*** 270,299 ****
  	if (!jail_sysvipc_allowed && p->p_prison != NULL)
  		return (ENOSYS);
  
! 	msqid = IPCID_TO_IX(msqid);
! 
! 	if (msqid < 0 || msqid >= msginfo.msgmni) {
! #ifdef MSG_DEBUG_OK
! 		printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
! 		    msginfo.msgmni);
! #endif
  		return(EINVAL);
- 	}
- 
- 	msqptr = &msqids[msqid];
- 
- 	if (msqptr->msg_qbytes == 0) {
- #ifdef MSG_DEBUG_OK
- 		printf("no such msqid\n");
- #endif
- 		return(EINVAL);
- 	}
- 	if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
- #ifdef MSG_DEBUG_OK
- 		printf("wrong sequence number\n");
- #endif
- 		return(EINVAL);
- 	}
  
  	eval = 0;
  	rval = 0;
--- 309,316 ----
  	if (!jail_sysvipc_allowed && p->p_prison != NULL)
  		return (ENOSYS);
  
! 	if ((msqptr = msqid_to_msqptr(uap->msqid)) == NULL)
  		return(EINVAL);
  
  	eval = 0;
  	rval = 0;
***************
*** 303,310 ****
--- 320,335 ----
  	case IPC_RMID:
  	{
  		struct msg *msghdr;
+ 		int s;
  		if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)))
  			return(eval);
+ 
+ 		/* notify intent before actually removing message queue */
+ 		s = splhigh();
+ 		KNOTE(&((struct i_msqid_ds *)msqptr)->q_klist,
+ 						NOTE_IPC_RMID, uap->msqid);
+ 		splx(s);
+ 
  		/* Free the message headers */
  		msghdr = msqptr->msg_first;
  		while (msghdr != NULL) {
***************
*** 411,417 ****
  
  	if (key != IPC_PRIVATE) {
  		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
! 			msqptr = &msqids[msqid];
  			if (msqptr->msg_qbytes != 0 &&
  			    msqptr->msg_perm.key == key)
  				break;
--- 436,442 ----
  
  	if (key != IPC_PRIVATE) {
  		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
! 			msqptr = (struct msqid_ds *)&i_msqids[msqid];
  			if (msqptr->msg_qbytes != 0 &&
  			    msqptr->msg_perm.key == key)
  				break;
***************
*** 448,454 ****
  			 * they are copying the message in/out.  We can't
  			 * re-use the entry until they release it.
  			 */
! 			msqptr = &msqids[msqid];
  			if (msqptr->msg_qbytes == 0 &&
  			    (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
  				break;
--- 473,479 ----
  			 * they are copying the message in/out.  We can't
  			 * re-use the entry until they release it.
  			 */
! 			msqptr = (struct msqid_ds *)&i_msqids[msqid];
  			if (msqptr->msg_qbytes == 0 &&
  			    (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
  				break;
***************
*** 480,485 ****
--- 505,511 ----
  		msqptr->msg_stime = 0;
  		msqptr->msg_rtime = 0;
  		msqptr->msg_ctime = time_second;
+ 		bzero(&((struct i_msqid_ds *)msqptr)->q_klist, sizeof(struct klist));
  	} else {
  #ifdef MSG_DEBUG_OK
  		printf("didn't find it and wasn't asked to create it\n");
***************
*** 507,513 ****
  	struct proc *p;
  	register struct msgsnd_args *uap;
  {
- 	int msqid = uap->msqid;
  	void *user_msgp = uap->msgp;
  	size_t msgsz = uap->msgsz;
  	int msgflg = uap->msgflg;
--- 533,538 ----
***************
*** 515,520 ****
--- 540,546 ----
  	register struct msqid_ds *msqptr;
  	register struct msg *msghdr;
  	short next;
+ 	int s;
  
  #ifdef MSG_DEBUG_OK
  	printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
***************
*** 524,552 ****
  	if (!jail_sysvipc_allowed && p->p_prison != NULL)
  		return (ENOSYS);
  
! 	msqid = IPCID_TO_IX(msqid);
! 
! 	if (msqid < 0 || msqid >= msginfo.msgmni) {
! #ifdef MSG_DEBUG_OK
! 		printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
! 		    msginfo.msgmni);
! #endif
! 		return(EINVAL);
! 	}
! 
! 	msqptr = &msqids[msqid];
! 	if (msqptr->msg_qbytes == 0) {
! #ifdef MSG_DEBUG_OK
! 		printf("no such message queue id\n");
! #endif
  		return(EINVAL);
- 	}
- 	if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
- #ifdef MSG_DEBUG_OK
- 		printf("wrong sequence number\n");
- #endif
- 		return(EINVAL);
- 	}
  
  	if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
  #ifdef MSG_DEBUG_OK
--- 550,557 ----
  	if (!jail_sysvipc_allowed && p->p_prison != NULL)
  		return (ENOSYS);
  
! 	if ((msqptr = msqid_to_msqptr(uap->msqid)) == NULL)
  		return(EINVAL);
  
  	if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
  #ifdef MSG_DEBUG_OK
***************
*** 812,817 ****
--- 817,827 ----
  	msqptr->msg_lspid = p->p_pid;
  	msqptr->msg_stime = time_second;
  
+ 	s = splhigh();
+ 	KNOTE(&((struct i_msqid_ds *)msqptr)->q_klist,
+ 						NOTE_SYSVMSG, uap->msqid);
+ 	splx(s);
+ 
  	wakeup((caddr_t)msqptr);
  	p->p_retval[0] = 0;
  	return(0);
***************
*** 832,838 ****
  	struct proc *p;
  	register struct msgrcv_args *uap;
  {
- 	int msqid = uap->msqid;
  	void *user_msgp = uap->msgp;
  	size_t msgsz = uap->msgsz;
  	long msgtyp = uap->msgtyp;
--- 842,847 ----
***************
*** 851,879 ****
  	if (!jail_sysvipc_allowed && p->p_prison != NULL)
  		return (ENOSYS);
  
! 	msqid = IPCID_TO_IX(msqid);
! 
! 	if (msqid < 0 || msqid >= msginfo.msgmni) {
! #ifdef MSG_DEBUG_OK
! 		printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
! 		    msginfo.msgmni);
! #endif
! 		return(EINVAL);
! 	}
! 
! 	msqptr = &msqids[msqid];
! 	if (msqptr->msg_qbytes == 0) {
! #ifdef MSG_DEBUG_OK
! 		printf("no such message queue id\n");
! #endif
! 		return(EINVAL);
! 	}
! 	if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
! #ifdef MSG_DEBUG_OK
! 		printf("wrong sequence number\n");
! #endif
  		return(EINVAL);
- 	}
  
  	if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
  #ifdef MSG_DEBUG_OK
--- 860,867 ----
  	if (!jail_sysvipc_allowed && p->p_prison != NULL)
  		return (ENOSYS);
  
! 	if ((msqptr = msqid_to_msqptr(uap->msqid)) == NULL)
  		return(EINVAL);
  
  	if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
  #ifdef MSG_DEBUG_OK
***************
*** 1099,1101 ****
--- 1087,1194 ----
  	p->p_retval[0] = msgsz;
  	return(0);
  }
+ 
+ static int
+ filt_sysvmsgattach(struct knote *kn)
+ {
+ 	int msqid = kn->kn_id;
+ 	register struct i_msqid_ds *i_msqptr;
+ 
+ 	if ((i_msqptr = (struct i_msqid_ds *)msqid_to_msqptr(msqid)) == NULL)
+ 		return (ESRCH);
+ 
+ 	kn->kn_flags |= EV_CLEAR;		/* automatically set */
+ 
+ 	/* XXX locking?  this might compete with another process. */
+ 	SLIST_INSERT_HEAD(&i_msqptr->q_klist, kn, kn_selnext);
+ 
+ 	/*
+ 	 * If the note being attached is watching for message insertion,
+ 	 * and there are messages already present in the queue, then we
+ 	 * force insertion of a matching event automatically.  This *must*
+ 	 * be done via KNOTE() to ensure that the ,essage ID is passed; it
+ 	 * is a kludge to work around the 0 valued hint argument to the
+ 	 * f_event() call through to filt_sysvmsg().
+ 	 */
+ 	if ((kn->kn_sfflags & NOTE_SYSVMSG) && i_msqptr->e.msg_qnum != 0) {
+ 		int s = splhigh();
+ 		KNOTE(&i_msqptr->q_klist, NOTE_SYSVMSG, msqid);
+ 		splx(s);
+ 	}
+ 
+ 	return (0);
+ }
+ 
+ /*
+  * The knote may be attached to a message queue which is deleted out
+  * from under us by another process, leaving nothing for the knote to
+  * be attached to.  So when the ,essage queue is deleted, the knote
+  * is marked as DETACHED and also flagged as ONESHOT so it will be
+  * deleted when read out.  However, as part of the knote deletion,
+  * this routine is called, so a check is needed to avoid actually
+  * performing a detach, because the original message queue does not
+  * exist any more.  Note that reusing the queue ID will bzero the list
+  * head, orphaning the events which were linked to it, so this does
+  * not have to be tracked (thought it seems a bit messy, this is what
+  * kqueue already does for exiting processes, FWIW).
+  */
+ static void
+ filt_sysvmsgdetach(struct knote *kn)
+ {
+ 	int msqid = kn->kn_id;
+ 	register struct i_msqid_ds *i_msqptr;
+ 
+ 	if (kn->kn_status & KN_DETACHED)
+ 		return;
+ 
+ 	if ((i_msqptr = (struct i_msqid_ds *)msqid_to_msqptr(msqid)) == NULL)
+ 		return;
+ 
+ 	/* XXX locking?  this might compete with another process. */
+ 	SLIST_REMOVE(&i_msqptr->q_klist, kn, knote, kn_selnext);
+ }
+ 
+ /*
+  * Handle events on a given message queue object; called once for
+  * each object.
+  */
+ static int
+ filt_sysvmsg(struct knote *kn, long hint, long id)
+ {
+ 	u_int event;
+ 	register struct msqid_ds *msqptr;
+ 
+ 	/*
+ 	 * mask data out of "hint".
+ 	 */
+ 	event = (u_int)hint;
+ 
+ 	if (kn->kn_id != id)
+ 		return(0);
+ 
+ 	if ((msqptr = msqid_to_msqptr(id)) == NULL)
+ 		return(0);
+ 
+ 	/*
+ 	 * if the user is interested in this event, record it.
+ 	 */
+ 	if (kn->kn_sfflags & event)
+ 		kn->kn_fflags |= event;
+ 
+ 	switch( event) {
+ 	case NOTE_IPC_RMID:	/* message queue is being removed */
+ 		/* flag the event as finished */
+ 		kn->kn_status |= KN_DETACHED;
+ 		kn->kn_flags |= (EV_EOF | EV_ONESHOT); 
+ 		break;
+ 
+ 	case NOTE_SYSVMSG:	/* a message was enqueued */
+ 		kn->kn_data = msqptr->msg_qnum;	/* # of messages now in queue */
+ 		break;
+ 	}
+ 
+ 	return (kn->kn_fflags != 0);
+ }
+ 
+ struct filterops sysvmsg_filtops =
+ 	{ 0, filt_sysvmsgattach, filt_sysvmsgdetach, filt_sysvmsg };
Index: kern/tty.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/tty.c,v
retrieving revision 1.129.2.5
diff -c -r1.129.2.5 tty.c
*** kern/tty.c	11 Mar 2002 01:32:31 -0000	1.129.2.5
--- kern/tty.c	17 Aug 2002 06:50:10 -0000
***************
*** 109,117 ****
  static void	ttyrubo __P((struct tty *tp, int cnt));
  static void	ttyunblock __P((struct tty *tp));
  static int	ttywflush __P((struct tty *tp));
! static int	filt_ttyread __P((struct knote *kn, long hint));
  static void 	filt_ttyrdetach __P((struct knote *kn));
! static int	filt_ttywrite __P((struct knote *kn, long hint));
  static void 	filt_ttywdetach __P((struct knote *kn));
  
  /*
--- 109,117 ----
  static void	ttyrubo __P((struct tty *tp, int cnt));
  static void	ttyunblock __P((struct tty *tp));
  static int	ttywflush __P((struct tty *tp));
! static int	filt_ttyread __P((struct knote *kn, long hint, long id));
  static void 	filt_ttyrdetach __P((struct knote *kn));
! static int	filt_ttywrite __P((struct knote *kn, long hint, long id));
  static void 	filt_ttywdetach __P((struct knote *kn));
  
  /*
***************
*** 1137,1143 ****
  }
  
  static int
! filt_ttyread(struct knote *kn, long hint)
  {
  	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
  
--- 1137,1143 ----
  }
  
  static int
! filt_ttyread(struct knote *kn, long hint, long id)
  {
  	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
  
***************
*** 1160,1168 ****
  }
  
  static int
! filt_ttywrite(kn, hint)
  	struct knote *kn;
  	long hint;
  {
  	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
  
--- 1160,1169 ----
  }
  
  static int
! filt_ttywrite(kn, hint, id)
  	struct knote *kn;
  	long hint;
+ 	long id;
  {
  	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
  
***************
*** 2181,2187 ****
  	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
  		pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
  	wakeup(TSA_HUP_OR_INPUT(tp));
! 	KNOTE(&tp->t_rsel.si_note, 0);
  }
  
  /*
--- 2182,2188 ----
  	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
  		pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
  	wakeup(TSA_HUP_OR_INPUT(tp));
! 	KNOTE(&tp->t_rsel.si_note, 0, 0);
  }
  
  /*
***************
*** 2206,2212 ****
  		CLR(tp->t_state, TS_SO_OLOWAT);
  		wakeup(TSA_OLOWAT(tp));
  	}
! 	KNOTE(&tp->t_wsel.si_note, 0);
  }
  
  /*
--- 2207,2213 ----
  		CLR(tp->t_state, TS_SO_OLOWAT);
  		wakeup(TSA_OLOWAT(tp));
  	}
! 	KNOTE(&tp->t_wsel.si_note, 0, 0);
  }
  
  /*
Index: kern/uipc_socket.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.68.2.21
diff -c -r1.68.2.21 uipc_socket.c
*** kern/uipc_socket.c	1 May 2002 03:27:35 -0000	1.68.2.21
--- kern/uipc_socket.c	17 Aug 2002 06:51:37 -0000
***************
*** 65,74 ****
  #endif /* INET */
  
  static void 	filt_sordetach(struct knote *kn);
! static int 	filt_soread(struct knote *kn, long hint);
  static void 	filt_sowdetach(struct knote *kn);
! static int	filt_sowrite(struct knote *kn, long hint);
! static int	filt_solisten(struct knote *kn, long hint);
  
  static struct filterops solisten_filtops = 
  	{ 1, NULL, filt_sordetach, filt_solisten };
--- 65,74 ----
  #endif /* INET */
  
  static void 	filt_sordetach(struct knote *kn);
! static int 	filt_soread(struct knote *kn, long hint, long id);
  static void 	filt_sowdetach(struct knote *kn);
! static int	filt_sowrite(struct knote *kn, long hint, long id);
! static int	filt_solisten(struct knote *kn, long hint, long id);
  
  static struct filterops solisten_filtops = 
  	{ 1, NULL, filt_sordetach, filt_solisten };
***************
*** 1583,1589 ****
  
  /*ARGSUSED*/
  static int
! filt_soread(struct knote *kn, long hint)
  {
  	struct socket *so = (struct socket *)kn->kn_fp->f_data;
  
--- 1583,1589 ----
  
  /*ARGSUSED*/
  static int
! filt_soread(struct knote *kn, long hint, long id)
  {
  	struct socket *so = (struct socket *)kn->kn_fp->f_data;
  
***************
*** 1614,1620 ****
  
  /*ARGSUSED*/
  static int
! filt_sowrite(struct knote *kn, long hint)
  {
  	struct socket *so = (struct socket *)kn->kn_fp->f_data;
  
--- 1614,1620 ----
  
  /*ARGSUSED*/
  static int
! filt_sowrite(struct knote *kn, long hint, long id)
  {
  	struct socket *so = (struct socket *)kn->kn_fp->f_data;
  
***************
*** 1636,1642 ****
  
  /*ARGSUSED*/
  static int
! filt_solisten(struct knote *kn, long hint)
  {
  	struct socket *so = (struct socket *)kn->kn_fp->f_data;
  
--- 1636,1642 ----
  
  /*ARGSUSED*/
  static int
! filt_solisten(struct knote *kn, long hint, long id)
  {
  	struct socket *so = (struct socket *)kn->kn_fp->f_data;
  
Index: kern/uipc_socket2.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.55.2.15
diff -c -r1.55.2.15 uipc_socket2.c
*** kern/uipc_socket2.c	21 May 2002 18:03:16 -0000	1.55.2.15
--- kern/uipc_socket2.c	17 Aug 2002 06:52:01 -0000
***************
*** 313,319 ****
  		(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
  	if (sb->sb_flags & SB_AIO)
  		aio_swake(so, sb);
! 	KNOTE(&sb->sb_sel.si_note, 0);
  }
  
  /*
--- 313,319 ----
  		(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
  	if (sb->sb_flags & SB_AIO)
  		aio_swake(so, sb);
! 	KNOTE(&sb->sb_sel.si_note, 0, 0);
  }
  
  /*
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.65.2.14
diff -c -r1.65.2.14 uipc_syscalls.c
*** kern/uipc_syscalls.c	14 Aug 2002 22:23:05 -0000	1.65.2.14
--- kern/uipc_syscalls.c	17 Aug 2002 06:53:30 -0000
***************
*** 272,278 ****
  	p->p_retval[0] = fd;
  
  	/* connection has been removed from the listen queue */
! 	KNOTE(&head->so_rcv.sb_sel.si_note, 0);
  
  	so->so_state &= ~SS_COMP;
  	so->so_head = NULL;
--- 272,278 ----
  	p->p_retval[0] = fd;
  
  	/* connection has been removed from the listen queue */
! 	KNOTE(&head->so_rcv.sb_sel.si_note, 0, 0);
  
  	so->so_state &= ~SS_COMP;
  	so->so_head = NULL;
Index: miscfs/fifofs/fifo_vnops.c
===================================================================
RCS file: /usr/cvs/src/sys/miscfs/fifofs/Attic/fifo_vnops.c,v
retrieving revision 1.45.2.3
diff -c -r1.45.2.3 fifo_vnops.c
*** miscfs/fifofs/fifo_vnops.c	15 Jun 2001 21:20:55 -0000	1.45.2.3
--- miscfs/fifofs/fifo_vnops.c	17 Aug 2002 06:54:50 -0000
***************
*** 78,86 ****
  static int	fifo_advlock __P((struct vop_advlock_args *));
  
  static void	filt_fifordetach(struct knote *kn);
! static int	filt_fiforead(struct knote *kn, long hint);
  static void	filt_fifowdetach(struct knote *kn);
! static int	filt_fifowrite(struct knote *kn, long hint);
  
  static struct filterops fiforead_filtops =
  	{ 1, NULL, filt_fifordetach, filt_fiforead };
--- 78,86 ----
  static int	fifo_advlock __P((struct vop_advlock_args *));
  
  static void	filt_fifordetach(struct knote *kn);
! static int	filt_fiforead(struct knote *kn, long hint, long id);
  static void	filt_fifowdetach(struct knote *kn);
! static int	filt_fifowrite(struct knote *kn, long hint, long id);
  
  static struct filterops fiforead_filtops =
  	{ 1, NULL, filt_fifordetach, filt_fiforead };
***************
*** 405,411 ****
  }
  
  static int
! filt_fiforead(struct knote *kn, long hint)
  {
  	struct socket *so = (struct socket *)kn->kn_hook;
  
--- 405,411 ----
  }
  
  static int
! filt_fiforead(struct knote *kn, long hint, long id)
  {
  	struct socket *so = (struct socket *)kn->kn_hook;
  
***************
*** 429,435 ****
  }
  
  static int
! filt_fifowrite(struct knote *kn, long hint)
  {
  	struct socket *so = (struct socket *)kn->kn_hook;
  
--- 429,435 ----
  }
  
  static int
! filt_fifowrite(struct knote *kn, long hint, long id)
  {
  	struct socket *so = (struct socket *)kn->kn_hook;
  
Index: sys/event.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/event.h,v
retrieving revision 1.5.2.5
diff -c -r1.5.2.5 event.h
*** sys/event.h	14 Dec 2001 19:21:22 -0000	1.5.2.5
--- sys/event.h	17 Aug 2002 07:12:04 -0000
***************
*** 36,43 ****
  #define EVFILT_PROC		(-5)	/* attached to struct proc */
  #define EVFILT_SIGNAL		(-6)	/* attached to struct proc */
  #define EVFILT_TIMER		(-7)	/* timers */
  
! #define EVFILT_SYSCOUNT		7
  
  #define EV_SET(kevp, a, b, c, d, e, f) do {	\
  	(kevp)->ident = (a);			\
--- 36,44 ----
  #define EVFILT_PROC		(-5)	/* attached to struct proc */
  #define EVFILT_SIGNAL		(-6)	/* attached to struct proc */
  #define EVFILT_TIMER		(-7)	/* timers */
+ #define	EVFILT_SYSVMSG		(-8)	/* System V messages */
  
! #define EVFILT_SYSCOUNT		8
  
  #define EV_SET(kevp, a, b, c, d, e, f) do {	\
  	(kevp)->ident = (a);			\
***************
*** 105,110 ****
--- 106,117 ----
  #define	NOTE_CHILD	0x00000004		/* am a child process */
  
  /*
+  * data/hint flags for EVFILT_SYSVMSG, shared with userspace
+  */
+ #define	NOTE_IPC_RMID	0x80000000		/* message queue deleted */
+ #define	NOTE_SYSVMSG	0x40000000		/* message enqueued */
+ 
+ /*
   * This is currently visible to userland to work around broken
   * programs which pull in <sys/proc.h> or <sys/select.h>.
   */
***************
*** 118,124 ****
  MALLOC_DECLARE(M_KQUEUE);
  #endif
  
! #define KNOTE(list, hint)	if ((list) != NULL) knote(list, hint)
  
  /*
   * Flag indicating hint is a signal.  Used by EVFILT_SIGNAL, and also
--- 125,131 ----
  MALLOC_DECLARE(M_KQUEUE);
  #endif
  
! #define KNOTE(list, hint,id)	if ((list) != NULL) knote(list, hint, id)
  
  /*
   * Flag indicating hint is a signal.  Used by EVFILT_SIGNAL, and also
***************
*** 130,136 ****
  	int	f_isfd;		/* true if ident == filedescriptor */
  	int	(*f_attach)	__P((struct knote *kn));
  	void	(*f_detach)	__P((struct knote *kn));
! 	int	(*f_event)	__P((struct knote *kn, long hint));
  };
  
  struct knote {
--- 137,143 ----
  	int	f_isfd;		/* true if ident == filedescriptor */
  	int	(*f_attach)	__P((struct knote *kn));
  	void	(*f_detach)	__P((struct knote *kn));
! 	int	(*f_event)	__P((struct knote *kn, long hint, long id));
  };
  
  struct knote {
***************
*** 163,169 ****
  
  struct proc;
  
! extern void	knote(struct klist *list, long hint);
  extern void	knote_remove(struct proc *p, struct klist *list);
  extern void	knote_fdclose(struct proc *p, int fd);
  extern int 	kqueue_register(struct kqueue *kq,
--- 170,176 ----
  
  struct proc;
  
! extern void	knote(struct klist *list, long hint, long id);
  extern void	knote_remove(struct proc *p, struct klist *list);
  extern void	knote_fdclose(struct proc *p, int fd);
  extern int 	kqueue_register(struct kqueue *kq,
Index: ufs/ufs/ufs_readwrite.c
===================================================================
RCS file: /usr/cvs/src/sys/ufs/ufs/Attic/ufs_readwrite.c,v
retrieving revision 1.65.2.11
diff -c -r1.65.2.11 ufs_readwrite.c
*** ufs/ufs/ufs_readwrite.c	22 Jun 2002 18:08:04 -0000	1.65.2.11
--- ufs/ufs/ufs_readwrite.c	17 Aug 2002 06:55:50 -0000
***************
*** 51,57 ****
  #include <sys/vmmeter.h>
  
  #define VN_KNOTE(vp, b) \
! 	KNOTE((struct klist *)&vp->v_pollinfo.vpi_selinfo.si_note, (b))
  
  /*
   * Vnode op for reading.
--- 51,57 ----
  #include <sys/vmmeter.h>
  
  #define VN_KNOTE(vp, b) \
! 	KNOTE((struct klist *)&vp->v_pollinfo.vpi_selinfo.si_note, (b), 0)
  
  /*
   * Vnode op for reading.
Index: ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /usr/cvs/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.131.2.7
diff -c -r1.131.2.7 ufs_vnops.c
*** ufs/ufs/ufs_vnops.c	5 Feb 2002 18:35:04 -0000	1.131.2.7
--- ufs/ufs/ufs_vnops.c	17 Aug 2002 06:57:07 -0000
***************
*** 108,116 ****
  static int ufsspec_close __P((struct vop_close_args *));
  static int ufsspec_read __P((struct vop_read_args *));
  static int ufsspec_write __P((struct vop_write_args *));
! static int filt_ufsread __P((struct knote *kn, long hint));
! static int filt_ufswrite __P((struct knote *kn, long hint));
! static int filt_ufsvnode __P((struct knote *kn, long hint));
  static void filt_ufsdetach __P((struct knote *kn));
  static int ufs_kqfilter __P((struct vop_kqfilter_args *ap));
  
--- 108,116 ----
  static int ufsspec_close __P((struct vop_close_args *));
  static int ufsspec_read __P((struct vop_read_args *));
  static int ufsspec_write __P((struct vop_write_args *));
! static int filt_ufsread __P((struct knote *kn, long hint, long id));
! static int filt_ufswrite __P((struct knote *kn, long hint, long id));
! static int filt_ufsvnode __P((struct knote *kn, long hint, long id));
  static void filt_ufsdetach __P((struct knote *kn));
  static int ufs_kqfilter __P((struct vop_kqfilter_args *ap));
  
***************
*** 131,137 ****
  	(q) = tmp.qcvt; \
  }
  #define VN_KNOTE(vp, b) \
! 	KNOTE(&vp->v_pollinfo.vpi_selinfo.si_note, (b))
  
  /*
   * A virgin directory (no blushing please).
--- 131,137 ----
  	(q) = tmp.qcvt; \
  }
  #define VN_KNOTE(vp, b) \
! 	KNOTE(&vp->v_pollinfo.vpi_selinfo.si_note, (b), 0)
  
  /*
   * A virgin directory (no blushing please).
***************
*** 2275,2281 ****
  
  /*ARGSUSED*/
  static int
! filt_ufsread(struct knote *kn, long hint)
  {
  	struct vnode *vp = (struct vnode *)kn->kn_hook;
  	struct inode *ip = VTOI(vp);
--- 2275,2281 ----
  
  /*ARGSUSED*/
  static int
! filt_ufsread(struct knote *kn, long hint, long id)
  {
  	struct vnode *vp = (struct vnode *)kn->kn_hook;
  	struct inode *ip = VTOI(vp);
***************
*** 2295,2301 ****
  
  /*ARGSUSED*/
  static int
! filt_ufswrite(struct knote *kn, long hint)
  {
  
  	/*
--- 2295,2301 ----
  
  /*ARGSUSED*/
  static int
! filt_ufswrite(struct knote *kn, long hint, long id)
  {
  
  	/*
***************
*** 2310,2316 ****
  }
  
  static int
! filt_ufsvnode(struct knote *kn, long hint)
  {
  
  	if (kn->kn_sfflags & hint)
--- 2310,2316 ----
  }
  
  static int
! filt_ufsvnode(struct knote *kn, long hint, long id)
  {
  
  	if (kn->kn_sfflags & hint)

--------------28F74B3623B344F226551D0F--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




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