Date: Sat, 29 Apr 2006 18:54:08 GMT From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 96374 for review Message-ID: <200604291854.k3TIs8r5036411@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=96374 Change 96374 by marcel@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); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604291854.k3TIs8r5036411>