PERFORCE change 96374 for review

Marcel Moolenaar marcel at FreeBSD.org
Sat Apr 29 18:54:18 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=96374

Change 96374 by marcel at marcel_nfs on 2006/04/29 18:53:48

	IFC @96372

Affected files ...

.. //depot/projects/uart/amd64/amd64/pmap.c#36 integrate
.. //depot/projects/uart/kern/tty_pts.c#3 integrate
.. //depot/projects/uart/kern/vfs_lookup.c#13 integrate
.. //depot/projects/uart/kern/vfs_vnops.c#18 integrate
.. //depot/projects/uart/net/if_bridge.c#8 integrate

Differences ...

==== //depot/projects/uart/amd64/amd64/pmap.c#36 (text+ko) ====

@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.551 2006/04/27 21:26:25 alc Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.552 2006/04/29 00:59:15 alc Exp $");
 
 /*
  *	Manages physical address maps.
@@ -1546,6 +1546,7 @@
 	struct pv_chunk *pc;
 	int idx, field, bit;
 
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	PV_STAT(pv_entry_frees++);
 	PV_STAT(pv_entry_spare++);
 	pv_entry_count--;
@@ -1567,9 +1568,7 @@
 	TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
 	m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
 	dump_drop_page(m->phys_addr);
-	vm_page_lock_queues();
 	vm_page_free(m);
-	vm_page_unlock_queues();
 }
 
 /*
@@ -2802,14 +2801,12 @@
 			TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
 			m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
 			dump_drop_page(m->phys_addr);
-			vm_page_lock_queues();
 			vm_page_free(m);
-			vm_page_unlock_queues();
 		}
 	}
+	vm_page_unlock_queues();
 	pmap_invalidate_all(pmap);
 	PMAP_UNLOCK(pmap);
-	vm_page_unlock_queues();
 }
 
 /*

==== //depot/projects/uart/kern/tty_pts.c#3 (text+ko) ====

@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/tty_pts.c,v 1.7 2006/01/31 22:19:37 csjp Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/tty_pts.c,v 1.8 2006/04/28 21:39:57 rwatson Exp $");
 
 /*
  * Pseudo-teletype Driver
@@ -829,6 +829,9 @@
 	struct pt_desc *pt;
 	struct cdev *devc;
 
+	if (!use_pts)
+		return;
+
 	if (*dev != NULL)
 		return;
 

==== //depot/projects/uart/kern/vfs_lookup.c#13 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/vfs_lookup.c,v 1.90 2006/04/28 00:59:48 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/vfs_lookup.c,v 1.91 2006/04/29 07:13:49 kris Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_mac.h"
@@ -508,6 +508,7 @@
 			    dp == rootvnode) {
 				ndp->ni_dvp = dp;
 				ndp->ni_vp = dp;
+				vfslocked = VFS_LOCK_GIANT(dp->v_mount);
 				VREF(dp);
 				goto nextname;
 			}

==== //depot/projects/uart/kern/vfs_vnops.c#18 (text+ko) ====

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/kern/vfs_vnops.c,v 1.241 2006/03/31 03:54:19 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/kern/vfs_vnops.c,v 1.242 2006/04/28 21:54:05 pjd Exp $");
 
 #include "opt_mac.h"
 
@@ -404,7 +404,7 @@
 		if (auio.uio_resid && error == 0)
 			error = EIO;
 	if ((ioflg & IO_NODELOCKED) == 0) {
-		if (rw == UIO_WRITE)
+		if (rw == UIO_WRITE && vp->v_type != VCHR)
 			vn_finished_write(mp);
 		VOP_UNLOCK(vp, 0, td);
 	}
@@ -569,7 +569,8 @@
 		fp->f_offset = uio->uio_offset;
 	fp->f_nextoff = uio->uio_offset;
 	VOP_UNLOCK(vp, 0, td);
-	vn_finished_write(mp);
+	if (vp->v_type != VCHR)
+		vn_finished_write(mp);
 unlock:
 	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);

==== //depot/projects/uart/net/if_bridge.c#8 (text+ko) ====

@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.58 2006/03/26 20:52:47 thompsa Exp $");
+__FBSDID("$FreeBSD: src/sys/net/if_bridge.c,v 1.59 2006/04/29 05:37:25 thompsa Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -263,6 +263,8 @@
 # ifdef INET6
 static int	bridge_ip6_checkbasic(struct mbuf **mp);
 # endif /* INET6 */
+static int	bridge_fragment(struct ifnet *, struct mbuf *,
+		    struct ether_header *, int, struct llc *);
 
 SYSCTL_DECL(_net_link);
 SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW, 0, "Bridge");
@@ -1497,13 +1499,22 @@
 __inline void
 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
 {
-	int len, err;
+	int len, err = 0;
 	short mflags;
+	struct mbuf *m0;
 
 	len = m->m_pkthdr.len;
 	mflags = m->m_flags;
 
-	IFQ_ENQUEUE(&dst_ifp->if_snd, m, err);
+	/* We may be sending a framgment so traverse the mbuf */
+	for (; m; m = m0) {
+		m0 = m->m_nextpkt;
+		m->m_nextpkt = NULL;
+		
+		if (err == 0)
+			IFQ_ENQUEUE(&dst_ifp->if_snd, m, err);
+	}
+
 	if (err == 0) {
 
 		sc->sc_ifp->if_opackets++;
@@ -2761,12 +2772,23 @@
 			error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
 					dir, NULL);
 
+		if (*mp == NULL || error != 0) /* filter may consume */
+			break;
+
+		/* check if we need to fragment the packet */
+		if (pfil_member && ifp != NULL && dir == PFIL_OUT) {
+			i = (*mp)->m_pkthdr.len;
+			if (i > ifp->if_mtu) {
+				error = bridge_fragment(ifp, *mp, &eh2, snap,
+					    &llc1);
+				return (error);
+			}
+		}
+
 		/* Restore ip and the fields ntohs()'d. */
-		if (*mp != NULL && error == 0) {
-			ip = mtod(*mp, struct ip *);
-			ip->ip_len = htons(ip->ip_len);
-			ip->ip_off = htons(ip->ip_off);
-		}
+		ip = mtod(*mp, struct ip *);
+		ip->ip_len = htons(ip->ip_len);
+		ip->ip_off = htons(ip->ip_off);
 
 		break;
 # ifdef INET6
@@ -2979,3 +3001,59 @@
 	return -1;
 }
 # endif /* INET6 */
+
+/*
+ * bridge_fragment:
+ *
+ *	Return a fragmented mbuf chain.
+ */
+static int
+bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh,
+    int snap, struct llc *llc)
+{
+	struct mbuf *m0;
+	struct ip *ip;
+	int error = -1;
+
+	if (m->m_len < sizeof(struct ip) &&
+	    (m = m_pullup(m, sizeof(struct ip))) == NULL)
+		goto out;
+	ip = mtod(m, struct ip *);
+
+	error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist,
+		    CSUM_DELAY_IP);
+	if (error)
+		goto out;
+
+	/* walk the chain and re-add the Ethernet header */
+	for (m0 = m; m0; m0 = m0->m_nextpkt) {
+		if (error == 0) {
+			if (snap) {
+				M_PREPEND(m0, sizeof(struct llc), M_DONTWAIT);
+				if (m0 == NULL) {
+					error = ENOBUFS;
+					continue;
+				}
+				bcopy(llc, mtod(m0, caddr_t),
+				    sizeof(struct llc));
+			}
+			M_PREPEND(m0, ETHER_HDR_LEN, M_DONTWAIT);
+			if (m0 == NULL) {
+				error = ENOBUFS;
+				continue;
+			}
+			bcopy(eh, mtod(m0, caddr_t), ETHER_HDR_LEN);
+		} else 
+			m_freem(m);
+	}
+
+	if (error == 0)
+		ipstat.ips_fragmented++;
+
+	return (error);
+
+out:
+	if (m != NULL)
+		m_freem(m);
+	return (error);
+}


More information about the p4-projects mailing list