mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
MFC
This commit is contained in:
commit
3ac3f6002b
28 changed files with 535 additions and 295 deletions
|
|
@ -341,6 +341,17 @@ control_status(struct nv *nv)
|
|||
printf(" dirty: %ju (%NB)\n",
|
||||
(uintmax_t)nv_get_uint64(nv, "dirty%u", ii),
|
||||
(intmax_t)nv_get_uint64(nv, "dirty%u", ii));
|
||||
printf(" statistics:\n");
|
||||
printf(" reads: %ju\n",
|
||||
(uint64_t)nv_get_uint64(nv, "stat_read%u", ii));
|
||||
printf(" writes: %ju\n",
|
||||
(uint64_t)nv_get_uint64(nv, "stat_write%u", ii));
|
||||
printf(" deletes: %ju\n",
|
||||
(uint64_t)nv_get_uint64(nv, "stat_delete%u", ii));
|
||||
printf(" flushes: %ju\n",
|
||||
(uint64_t)nv_get_uint64(nv, "stat_flush%u", ii));
|
||||
printf(" activemap updates: %ju\n",
|
||||
(uint64_t)nv_get_uint64(nv, "stat_activemap_update%u", ii));
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,6 +199,16 @@ control_status_worker(struct hast_resource *res, struct nv *nvout,
|
|||
"extentsize%u", no);
|
||||
nv_add_uint32(nvout, nv_get_uint32(cnvin, "keepdirty"),
|
||||
"keepdirty%u", no);
|
||||
nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_read"),
|
||||
"stat_read%u", no);
|
||||
nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_write"),
|
||||
"stat_write%u", no);
|
||||
nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_delete"),
|
||||
"stat_delete%u", no);
|
||||
nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_flush"),
|
||||
"stat_flush%u", no);
|
||||
nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_activemap_update"),
|
||||
"stat_activemap_update%u", no);
|
||||
end:
|
||||
if (cnvin != NULL)
|
||||
nv_free(cnvin);
|
||||
|
|
@ -446,6 +456,13 @@ ctrl_thread(void *arg)
|
|||
nv_add_uint32(nvout, (uint32_t)0, "keepdirty");
|
||||
nv_add_uint64(nvout, (uint64_t)0, "dirty");
|
||||
}
|
||||
nv_add_uint64(nvout, res->hr_stat_read, "stat_read");
|
||||
nv_add_uint64(nvout, res->hr_stat_write, "stat_write");
|
||||
nv_add_uint64(nvout, res->hr_stat_delete,
|
||||
"stat_delete");
|
||||
nv_add_uint64(nvout, res->hr_stat_flush, "stat_flush");
|
||||
nv_add_uint64(nvout, res->hr_stat_activemap_update,
|
||||
"stat_activemap_update");
|
||||
nv_add_int16(nvout, 0, "error");
|
||||
break;
|
||||
case CONTROL_RELOAD:
|
||||
|
|
|
|||
|
|
@ -218,6 +218,17 @@ struct hast_resource {
|
|||
/* Locked used to synchronize access to hr_amp. */
|
||||
pthread_mutex_t hr_amp_lock;
|
||||
|
||||
/* Number of BIO_READ requests. */
|
||||
uint64_t hr_stat_read;
|
||||
/* Number of BIO_WRITE requests. */
|
||||
uint64_t hr_stat_write;
|
||||
/* Number of BIO_DELETE requests. */
|
||||
uint64_t hr_stat_delete;
|
||||
/* Number of BIO_FLUSH requests. */
|
||||
uint64_t hr_stat_flush;
|
||||
/* Number of activemap updates. */
|
||||
uint64_t hr_stat_activemap_update;
|
||||
|
||||
/* Next resource. */
|
||||
TAILQ_ENTRY(hast_resource) hr_next;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1117,6 +1117,7 @@ ggate_recv_thread(void *arg)
|
|||
*/
|
||||
switch (ggio->gctl_cmd) {
|
||||
case BIO_READ:
|
||||
res->hr_stat_read++;
|
||||
pjdlog_debug(2,
|
||||
"ggate_recv: (%p) Moving request to the send queue.",
|
||||
hio);
|
||||
|
|
@ -1145,6 +1146,7 @@ ggate_recv_thread(void *arg)
|
|||
QUEUE_INSERT1(hio, send, ncomp);
|
||||
break;
|
||||
case BIO_WRITE:
|
||||
res->hr_stat_write++;
|
||||
if (res->hr_resuid == 0) {
|
||||
/*
|
||||
* This is first write, initialize localcnt and
|
||||
|
|
@ -1183,12 +1185,21 @@ ggate_recv_thread(void *arg)
|
|||
mtx_lock(&res->hr_amp_lock);
|
||||
if (activemap_write_start(res->hr_amp,
|
||||
ggio->gctl_offset, ggio->gctl_length)) {
|
||||
res->hr_stat_activemap_update++;
|
||||
(void)hast_activemap_flush(res);
|
||||
}
|
||||
mtx_unlock(&res->hr_amp_lock);
|
||||
/* FALLTHROUGH */
|
||||
case BIO_DELETE:
|
||||
case BIO_FLUSH:
|
||||
switch (ggio->gctl_cmd) {
|
||||
case BIO_DELETE:
|
||||
res->hr_stat_delete++;
|
||||
break;
|
||||
case BIO_FLUSH:
|
||||
res->hr_stat_flush++;
|
||||
break;
|
||||
}
|
||||
pjdlog_debug(2,
|
||||
"ggate_recv: (%p) Moving request to the send queues.",
|
||||
hio);
|
||||
|
|
|
|||
|
|
@ -612,6 +612,20 @@ recv_thread(void *arg)
|
|||
QUEUE_INSERT(send, hio);
|
||||
continue;
|
||||
}
|
||||
switch (hio->hio_cmd) {
|
||||
case HIO_READ:
|
||||
res->hr_stat_read++;
|
||||
break;
|
||||
case HIO_WRITE:
|
||||
res->hr_stat_write++;
|
||||
break;
|
||||
case HIO_DELETE:
|
||||
res->hr_stat_delete++;
|
||||
break;
|
||||
case HIO_FLUSH:
|
||||
res->hr_stat_flush++;
|
||||
break;
|
||||
}
|
||||
reqlog(LOG_DEBUG, 2, -1, hio,
|
||||
"recv: (%p) Got request header: ", hio);
|
||||
if (hio->hio_cmd == HIO_KEEPALIVE) {
|
||||
|
|
|
|||
|
|
@ -224,7 +224,13 @@ drop_privs(struct hast_resource *res)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
if (res == NULL || res->hr_role != HAST_ROLE_PRIMARY)
|
||||
/*
|
||||
* Until capsicum doesn't allow ioctl(2) we cannot use it to sandbox
|
||||
* primary and secondary worker processes, as primary uses GGATE
|
||||
* ioctls and secondary uses ioctls to handle BIO_DELETE and BIO_FLUSH.
|
||||
* For now capsicum is only used to sandbox hastctl.
|
||||
*/
|
||||
if (res == NULL)
|
||||
capsicum = (cap_enter() == 0);
|
||||
else
|
||||
capsicum = false;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 23, 2010
|
||||
.Dd May 23, 2011
|
||||
.Dt MSK 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -195,6 +195,8 @@ Marvell Yukon 88E8071 Gigabit Ethernet
|
|||
.It
|
||||
Marvell Yukon 88E8072 Gigabit Ethernet
|
||||
.It
|
||||
Marvell Yukon 88E8075 Gigabit Ethernet
|
||||
.It
|
||||
SysKonnect SK-9Sxx Gigabit Ethernet
|
||||
.It
|
||||
SysKonnect SK-9Exx Gigabit Ethernet
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ kernel-install:
|
|||
mkdir -p ${DESTDIR}${KODIR}
|
||||
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}
|
||||
.if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \
|
||||
(defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes")
|
||||
(defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no")
|
||||
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
|
||||
.endif
|
||||
.if defined(KERNEL_EXTRA_INSTALL)
|
||||
|
|
@ -241,7 +241,7 @@ kernel-reinstall:
|
|||
@-chflags -R noschg ${DESTDIR}${KODIR}
|
||||
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}
|
||||
.if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \
|
||||
(defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes")
|
||||
(defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no")
|
||||
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
|
||||
.endif
|
||||
|
||||
|
|
|
|||
|
|
@ -286,8 +286,8 @@ realinstall: _kmodinstall
|
|||
_kmodinstall:
|
||||
${INSTALL} -o ${KMODOWN} -g ${KMODGRP} -m ${KMODMODE} \
|
||||
${_INSTALLFLAGS} ${PROG} ${DESTDIR}${KMODDIR}
|
||||
.if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \
|
||||
(defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes")
|
||||
.if defined(DEBUG_FLAGS) && !defined(INSTALL_NODEBUG) && \
|
||||
(defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no")
|
||||
${INSTALL} -o ${KMODOWN} -g ${KMODGRP} -m ${KMODMODE} \
|
||||
${_INSTALLFLAGS} ${PROG}.symbols ${DESTDIR}${KMODDIR}
|
||||
.endif
|
||||
|
|
|
|||
|
|
@ -139,4 +139,4 @@ int osreldate = ${RELDATE};
|
|||
char kern_ident[] = "${i}";
|
||||
EOF
|
||||
|
||||
echo `expr ${v} + 1` > version
|
||||
echo $((v + 1)) > version
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ hpet_attach(device_t dev)
|
|||
sc->tc.tc_get_timecount = hpet_get_timecount,
|
||||
sc->tc.tc_counter_mask = ~0u,
|
||||
sc->tc.tc_name = "HPET",
|
||||
sc->tc.tc_quality = 900,
|
||||
sc->tc.tc_quality = 950,
|
||||
sc->tc.tc_frequency = sc->freq;
|
||||
sc->tc.tc_priv = sc;
|
||||
tc_init(&sc->tc);
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ acpi_timer_probe(device_t dev)
|
|||
if (j == 10) {
|
||||
acpi_timer_timecounter.tc_name = "ACPI-fast";
|
||||
acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount;
|
||||
acpi_timer_timecounter.tc_quality = 1000;
|
||||
acpi_timer_timecounter.tc_quality = 900;
|
||||
} else {
|
||||
acpi_timer_timecounter.tc_name = "ACPI-safe";
|
||||
acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount_safe;
|
||||
|
|
|
|||
|
|
@ -221,6 +221,10 @@ static struct msk_product {
|
|||
"Marvell Yukon 88E8071 Gigabit Ethernet" },
|
||||
{ VENDORID_MARVELL, DEVICEID_MRVL_436C,
|
||||
"Marvell Yukon 88E8072 Gigabit Ethernet" },
|
||||
{ VENDORID_MARVELL, DEVICEID_MRVL_436D,
|
||||
"Marvell Yukon 88E8055 Gigabit Ethernet" },
|
||||
{ VENDORID_MARVELL, DEVICEID_MRVL_4370,
|
||||
"Marvell Yukon 88E8075 Gigabit Ethernet" },
|
||||
{ VENDORID_MARVELL, DEVICEID_MRVL_4380,
|
||||
"Marvell Yukon 88E8057 Gigabit Ethernet" },
|
||||
{ VENDORID_MARVELL, DEVICEID_MRVL_4381,
|
||||
|
|
@ -1030,7 +1034,10 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
|||
}
|
||||
}
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
msk_init_locked(sc_if);
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
msk_init_locked(sc_if);
|
||||
}
|
||||
}
|
||||
MSK_IF_UNLOCK(sc_if);
|
||||
break;
|
||||
|
|
@ -1212,37 +1219,30 @@ msk_phy_power(struct msk_softc *sc, int mode)
|
|||
*/
|
||||
CSR_WRITE_1(sc, B2_Y2_CLK_GATE, val);
|
||||
|
||||
val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
|
||||
val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
|
||||
our = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
|
||||
our &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_XL) {
|
||||
if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
|
||||
/* Deassert Low Power for 1st PHY. */
|
||||
val |= PCI_Y2_PHY1_COMA;
|
||||
our |= PCI_Y2_PHY1_COMA;
|
||||
if (sc->msk_num_port > 1)
|
||||
val |= PCI_Y2_PHY2_COMA;
|
||||
our |= PCI_Y2_PHY2_COMA;
|
||||
}
|
||||
}
|
||||
/* Release PHY from PowerDown/COMA mode. */
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val);
|
||||
switch (sc->msk_hw_id) {
|
||||
case CHIP_ID_YUKON_EC_U:
|
||||
case CHIP_ID_YUKON_EX:
|
||||
case CHIP_ID_YUKON_FE_P:
|
||||
case CHIP_ID_YUKON_UL_2:
|
||||
case CHIP_ID_YUKON_OPT:
|
||||
CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF);
|
||||
|
||||
/* Enable all clocks. */
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
|
||||
our = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
|
||||
our &= (PCI_FORCE_ASPM_REQUEST|PCI_ASPM_GPHY_LINK_DOWN|
|
||||
PCI_ASPM_INT_FIFO_EMPTY|PCI_ASPM_CLKRUN_REQUEST);
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_EX ||
|
||||
sc->msk_hw_id >= CHIP_ID_YUKON_FE_P) {
|
||||
val = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
|
||||
val &= (PCI_FORCE_ASPM_REQUEST |
|
||||
PCI_ASPM_GPHY_LINK_DOWN | PCI_ASPM_INT_FIFO_EMPTY |
|
||||
PCI_ASPM_CLKRUN_REQUEST);
|
||||
/* Set all bits to 0 except bits 15..12. */
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, our);
|
||||
our = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
|
||||
our &= PCI_CTL_TIM_VMAIN_AV_MSK;
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, our);
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, val);
|
||||
val = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
|
||||
val &= PCI_CTL_TIM_VMAIN_AV_MSK;
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, val);
|
||||
CSR_PCI_WRITE_4(sc, PCI_CFG_REG_1, 0);
|
||||
CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_ON);
|
||||
/*
|
||||
* Disable status race, workaround for
|
||||
* Yukon EC Ultra & Yukon EX.
|
||||
|
|
@ -1251,10 +1251,10 @@ msk_phy_power(struct msk_softc *sc, int mode)
|
|||
val |= GLB_GPIO_STAT_RACE_DIS;
|
||||
CSR_WRITE_4(sc, B2_GP_IO, val);
|
||||
CSR_READ_4(sc, B2_GP_IO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Release PHY from PowerDown/COMA mode. */
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, our);
|
||||
|
||||
for (i = 0; i < sc->msk_num_port; i++) {
|
||||
CSR_WRITE_2(sc, MR_ADDR(i, GMAC_LINK_CTRL),
|
||||
GMLC_RST_SET);
|
||||
|
|
@ -1300,28 +1300,33 @@ mskc_reset(struct msk_softc *sc)
|
|||
bus_addr_t addr;
|
||||
uint16_t status;
|
||||
uint32_t val;
|
||||
int i;
|
||||
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
|
||||
int i, initram;
|
||||
|
||||
/* Disable ASF. */
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX) {
|
||||
status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR);
|
||||
/* Clear AHB bridge & microcontroller reset. */
|
||||
status &= ~(Y2_ASF_HCU_CCSR_AHB_RST |
|
||||
Y2_ASF_HCU_CCSR_CPU_RST_MODE);
|
||||
/* Clear ASF microcontroller state. */
|
||||
status &= ~ Y2_ASF_HCU_CCSR_UC_STATE_MSK;
|
||||
CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status);
|
||||
} else
|
||||
CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
|
||||
CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
|
||||
|
||||
/*
|
||||
* Since we disabled ASF, S/W reset is required for Power Management.
|
||||
*/
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
|
||||
if (sc->msk_hw_id >= CHIP_ID_YUKON_XL &&
|
||||
sc->msk_hw_id <= CHIP_ID_YUKON_SUPR) {
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_SUPR) {
|
||||
CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0);
|
||||
status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR);
|
||||
/* Clear AHB bridge & microcontroller reset. */
|
||||
status &= ~(Y2_ASF_HCU_CCSR_AHB_RST |
|
||||
Y2_ASF_HCU_CCSR_CPU_RST_MODE);
|
||||
/* Clear ASF microcontroller state. */
|
||||
status &= ~Y2_ASF_HCU_CCSR_UC_STATE_MSK;
|
||||
status &= ~Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE_MSK;
|
||||
CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status);
|
||||
CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0);
|
||||
} else
|
||||
CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
|
||||
CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
|
||||
/*
|
||||
* Since we disabled ASF, S/W reset is required for
|
||||
* Power Management.
|
||||
*/
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
|
||||
}
|
||||
|
||||
/* Clear all error bits in the PCI status register. */
|
||||
status = pci_read_config(sc->msk_dev, PCIR_STATUS, 2);
|
||||
|
|
@ -1362,17 +1367,22 @@ mskc_reset(struct msk_softc *sc)
|
|||
/* Reset GPHY/GMAC Control */
|
||||
for (i = 0; i < sc->msk_num_port; i++) {
|
||||
/* GPHY Control reset. */
|
||||
CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET);
|
||||
CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR);
|
||||
CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET);
|
||||
CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR);
|
||||
/* GMAC Control reset. */
|
||||
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_SET);
|
||||
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_CLR);
|
||||
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_F_LOOPB_OFF);
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
|
||||
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL),
|
||||
GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
|
||||
GMC_BYP_RETR_ON);
|
||||
}
|
||||
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_SUPR &&
|
||||
sc->msk_hw_rev > CHIP_REV_YU_SU_B0)
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, PCI_CLK_MACSEC_DIS);
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_OPT && sc->msk_hw_rev == 0) {
|
||||
/* Disable PCIe PHY powerdown(reg 0x80, bit7). */
|
||||
CSR_WRITE_4(sc, Y2_PEX_PHY_DATA, (0x0080 << 16) | 0x0080);
|
||||
|
|
@ -1396,8 +1406,14 @@ mskc_reset(struct msk_softc *sc)
|
|||
CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_STOP);
|
||||
CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
|
||||
|
||||
initram = 0;
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_XL ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_EC ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_FE)
|
||||
initram++;
|
||||
|
||||
/* Configure timeout values. */
|
||||
for (i = 0; i < sc->msk_num_port; i++) {
|
||||
for (i = 0; initram > 0 && i < sc->msk_num_port; i++) {
|
||||
CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_SET);
|
||||
CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
|
||||
CSR_WRITE_1(sc, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1),
|
||||
|
|
@ -1706,13 +1722,15 @@ mskc_attach(device_t dev)
|
|||
}
|
||||
}
|
||||
|
||||
/* Enable all clocks before accessing any registers. */
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
|
||||
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
|
||||
sc->msk_hw_id = CSR_READ_1(sc, B2_CHIP_ID);
|
||||
sc->msk_hw_rev = (CSR_READ_1(sc, B2_MAC_CFG) >> 4) & 0x0f;
|
||||
/* Bail out if chip is not recognized. */
|
||||
if (sc->msk_hw_id < CHIP_ID_YUKON_XL ||
|
||||
sc->msk_hw_id > CHIP_ID_YUKON_OPT ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_SUPR ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_UNKNOWN) {
|
||||
device_printf(dev, "unknown device: id=0x%02x, rev=0x%02x\n",
|
||||
sc->msk_hw_id, sc->msk_hw_rev);
|
||||
|
|
@ -1746,9 +1764,6 @@ mskc_attach(device_t dev)
|
|||
resource_int_value(device_get_name(dev), device_get_unit(dev),
|
||||
"int_holdoff", &sc->msk_int_holdoff);
|
||||
|
||||
/* Soft reset. */
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
|
||||
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
|
||||
sc->msk_pmd = CSR_READ_1(sc, B2_PMD_TYP);
|
||||
/* Check number of MACs. */
|
||||
sc->msk_num_port = 1;
|
||||
|
|
@ -1822,6 +1837,11 @@ mskc_attach(device_t dev)
|
|||
sc->msk_clock = 156; /* 156 MHz */
|
||||
sc->msk_pflags |= MSK_FLAG_JUMBO;
|
||||
break;
|
||||
case CHIP_ID_YUKON_SUPR:
|
||||
sc->msk_clock = 125; /* 125 MHz */
|
||||
sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2 |
|
||||
MSK_FLAG_AUTOTX_CSUM;
|
||||
break;
|
||||
case CHIP_ID_YUKON_UL_2:
|
||||
sc->msk_clock = 125; /* 125 MHz */
|
||||
sc->msk_pflags |= MSK_FLAG_JUMBO;
|
||||
|
|
@ -2963,6 +2983,7 @@ mskc_resume(device_t dev)
|
|||
|
||||
MSK_LOCK(sc);
|
||||
|
||||
CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
|
||||
mskc_reset(sc);
|
||||
for (i = 0; i < sc->msk_num_port; i++) {
|
||||
if (sc->msk_if[i] != NULL && sc->msk_if[i]->msk_ifp != NULL &&
|
||||
|
|
@ -3654,37 +3675,24 @@ msk_set_tx_stfwd(struct msk_if_softc *sc_if)
|
|||
|
||||
ifp = sc_if->msk_ifp;
|
||||
sc = sc_if->msk_softc;
|
||||
switch (sc->msk_hw_id) {
|
||||
case CHIP_ID_YUKON_EX:
|
||||
if (sc->msk_hw_rev == CHIP_REV_YU_EX_A0)
|
||||
goto yukon_ex_workaround;
|
||||
if (ifp->if_mtu > ETHERMTU)
|
||||
CSR_WRITE_4(sc,
|
||||
MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
|
||||
TX_JUMBO_ENA | TX_STFW_ENA);
|
||||
else
|
||||
CSR_WRITE_4(sc,
|
||||
MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
|
||||
TX_JUMBO_DIS | TX_STFW_ENA);
|
||||
break;
|
||||
default:
|
||||
yukon_ex_workaround:
|
||||
if ((sc->msk_hw_id == CHIP_ID_YUKON_EX &&
|
||||
sc->msk_hw_rev != CHIP_REV_YU_EX_A0) ||
|
||||
sc->msk_hw_id >= CHIP_ID_YUKON_SUPR) {
|
||||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
|
||||
TX_STFW_ENA);
|
||||
} else {
|
||||
if (ifp->if_mtu > ETHERMTU) {
|
||||
/* Set Tx GMAC FIFO Almost Empty Threshold. */
|
||||
CSR_WRITE_4(sc,
|
||||
MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR),
|
||||
MSK_ECU_JUMBO_WM << 16 | MSK_ECU_AE_THR);
|
||||
/* Disable Store & Forward mode for Tx. */
|
||||
CSR_WRITE_4(sc,
|
||||
MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
|
||||
TX_JUMBO_ENA | TX_STFW_DIS);
|
||||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
|
||||
TX_STFW_DIS);
|
||||
} else {
|
||||
/* Enable Store & Forward mode for Tx. */
|
||||
CSR_WRITE_4(sc,
|
||||
MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
|
||||
TX_JUMBO_DIS | TX_STFW_ENA);
|
||||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
|
||||
TX_STFW_ENA);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3737,7 +3745,8 @@ msk_init_locked(struct msk_if_softc *sc_if)
|
|||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
|
||||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
|
||||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
|
||||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL),
|
||||
GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
|
||||
GMC_BYP_RETR_ON);
|
||||
|
|
@ -3932,7 +3941,8 @@ msk_init_locked(struct msk_if_softc *sc_if)
|
|||
msk_stop(sc_if);
|
||||
return;
|
||||
}
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX) {
|
||||
if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
|
||||
sc->msk_hw_id == CHIP_ID_YUKON_SUPR) {
|
||||
/* Disable flushing of non-ASF packets. */
|
||||
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T),
|
||||
GMF_RX_MACSEC_FLUSH_OFF);
|
||||
|
|
|
|||
|
|
@ -144,6 +144,8 @@
|
|||
#define DEVICEID_MRVL_436A 0x436A
|
||||
#define DEVICEID_MRVL_436B 0x436B
|
||||
#define DEVICEID_MRVL_436C 0x436C
|
||||
#define DEVICEID_MRVL_436D 0x436D
|
||||
#define DEVICEID_MRVL_4370 0x4370
|
||||
#define DEVICEID_MRVL_4380 0x4380
|
||||
#define DEVICEID_MRVL_4381 0x4381
|
||||
|
||||
|
|
@ -321,6 +323,9 @@
|
|||
#define PCI_OS_SPD_X100 2 /* PCI-X 100MHz Bus */
|
||||
#define PCI_OS_SPD_X133 3 /* PCI-X 133MHz Bus */
|
||||
|
||||
/* PCI_OUR_REG_3 32 bit Our Register 3 (Yukon-ECU only) */
|
||||
#define PCI_CLK_MACSEC_DIS BIT_17 /* Disable Clock MACSec. */
|
||||
|
||||
/* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */
|
||||
#define PCI_TIMER_VALUE_MSK (0xff<<16) /* Bit 23..16: Timer Value Mask */
|
||||
#define PCI_FORCE_ASPM_REQUEST BIT_15 /* Force ASPM Request (A1 only) */
|
||||
|
|
@ -677,6 +682,7 @@
|
|||
/* ASF Subsystem Registers (Yukon-2 only) */
|
||||
#define B28_Y2_SMB_CONFIG 0x0e40 /* 32 bit ASF SMBus Config Register */
|
||||
#define B28_Y2_SMB_CSD_REG 0x0e44 /* 32 bit ASF SMB Control/Status/Data */
|
||||
#define B28_Y2_CPU_WDOG 0x0e48 /* 32 bit Watchdog Register */
|
||||
#define B28_Y2_ASF_IRQ_V_BASE 0x0e60 /* 32 bit ASF IRQ Vector Base */
|
||||
#define B28_Y2_ASF_STAT_CMD 0x0e68 /* 32 bit ASF Status and Command Reg */
|
||||
#define B28_Y2_ASF_HCU_CCSR 0x0e68 /* 32 bit ASF HCU CCSR (Yukon EX) */
|
||||
|
|
@ -918,6 +924,10 @@
|
|||
#define CHIP_REV_YU_EX_A0 1 /* Chip Rev. for Yukon-2 EX A0 */
|
||||
#define CHIP_REV_YU_EX_B0 2 /* Chip Rev. for Yukon-2 EX B0 */
|
||||
|
||||
#define CHIP_REV_YU_SU_A0 0 /* Chip Rev. for Yukon-2 SUPR A0 */
|
||||
#define CHIP_REV_YU_SU_B0 1 /* Chip Rev. for Yukon-2 SUPR B0 */
|
||||
#define CHIP_REV_YU_SU_B1 3 /* Chip Rev. for Yukon-2 SUPR B1 */
|
||||
|
||||
/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */
|
||||
#define Y2_STATUS_LNK2_INAC BIT_7 /* Status Link 2 inactiv (0 = activ) */
|
||||
#define Y2_CLK_GAT_LNK2_DIS BIT_6 /* Disable clock gating Link 2 */
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ FEATURE(nfscl, "NFSv4 client");
|
|||
extern int nfscl_ticks;
|
||||
extern struct timeval nfsboottime;
|
||||
extern struct nfsstats newnfsstats;
|
||||
extern int nfsrv_useacl;
|
||||
|
||||
MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header");
|
||||
MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct");
|
||||
|
|
@ -1331,6 +1332,15 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
|
|||
if (argp->flags & NFSMNT_NFSV3)
|
||||
ncl_fsinfo(nmp, *vpp, cred, td);
|
||||
|
||||
/* Mark if the mount point supports NFSv4 ACLs. */
|
||||
if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
|
||||
ret == 0 &&
|
||||
NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag |= MNT_NFS4ACLS;
|
||||
MNT_IUNLOCK(mp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lose the lock but keep the ref.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ g_gate_start(struct bio *bp)
|
|||
break;
|
||||
case BIO_DELETE:
|
||||
case BIO_WRITE:
|
||||
case BIO_FLUSH:
|
||||
/* XXX: Hack to allow read-only mounts. */
|
||||
if ((sc->sc_flags & G_GATE_FLAG_READONLY) != 0) {
|
||||
g_io_deliver(bp, EPERM);
|
||||
|
|
@ -580,6 +581,7 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa
|
|||
switch (bp->bio_cmd) {
|
||||
case BIO_READ:
|
||||
case BIO_DELETE:
|
||||
case BIO_FLUSH:
|
||||
break;
|
||||
case BIO_WRITE:
|
||||
error = copyout(bp->bio_data, ggio->gctl_data,
|
||||
|
|
@ -643,6 +645,7 @@ start_end:
|
|||
break;
|
||||
case BIO_DELETE:
|
||||
case BIO_WRITE:
|
||||
case BIO_FLUSH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,13 +225,19 @@ static void
|
|||
init_dynamic_kenv(void *data __unused)
|
||||
{
|
||||
char *cp;
|
||||
int len, i;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
kenvp = malloc((KENV_SIZE + 1) * sizeof(char *), M_KENV,
|
||||
M_WAITOK | M_ZERO);
|
||||
i = 0;
|
||||
for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) {
|
||||
len = strlen(cp) + 1;
|
||||
if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) {
|
||||
printf("WARNING: too long kenv string, ignoring %s\n",
|
||||
cp);
|
||||
continue;
|
||||
}
|
||||
if (i < KENV_SIZE) {
|
||||
kenvp[i] = malloc(len, M_KENV, M_WAITOK);
|
||||
strcpy(kenvp[i++], cp);
|
||||
|
|
|
|||
|
|
@ -654,7 +654,7 @@ bufinit(void)
|
|||
* To support extreme low-memory systems, make sure hidirtybuffers cannot
|
||||
* eat up all available buffer space. This occurs when our minimum cannot
|
||||
* be met. We try to size hidirtybuffers to 3/4 our buffer space assuming
|
||||
* BKVASIZE'd (8K) buffers.
|
||||
* BKVASIZE'd buffers.
|
||||
*/
|
||||
while ((long)hidirtybuffers * BKVASIZE > 3 * hibufspace / 4) {
|
||||
hidirtybuffers >>= 1;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@
|
|||
* Copyright (c) 1982, 1986, 1991, 1993, 1995
|
||||
* The Regents of the University of California.
|
||||
* Copyright (c) 2007-2009 Robert N. M. Watson
|
||||
* Copyright (c) 2010-2011 Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Robert N. M. Watson under
|
||||
* contract to Juniper Networks, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
|
@ -50,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/socketvar.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
|
@ -287,7 +292,7 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
|
|||
#endif
|
||||
INP_WLOCK(inp);
|
||||
inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
|
||||
inp->inp_refcount = 1; /* Reference from the inpcbinfo */
|
||||
refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */
|
||||
#if defined(IPSEC) || defined(MAC)
|
||||
out:
|
||||
if (error != 0) {
|
||||
|
|
@ -329,7 +334,7 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
|
|||
#if defined(INET) || defined(INET6)
|
||||
int
|
||||
in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
|
||||
struct ucred *cred, int wild)
|
||||
struct ucred *cred, int lookupflags)
|
||||
{
|
||||
struct inpcbinfo *pcbinfo;
|
||||
struct inpcb *tmpinp;
|
||||
|
|
@ -424,14 +429,14 @@ in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
|
|||
#ifdef INET6
|
||||
if ((inp->inp_vflag & INP_IPV6) != 0)
|
||||
tmpinp = in6_pcblookup_local(pcbinfo,
|
||||
&inp->in6p_laddr, lport, wild, cred);
|
||||
&inp->in6p_laddr, lport, lookupflags, cred);
|
||||
#endif
|
||||
#if defined(INET) && defined(INET6)
|
||||
else
|
||||
#endif
|
||||
#ifdef INET
|
||||
tmpinp = in_pcblookup_local(pcbinfo, laddr,
|
||||
lport, wild, cred);
|
||||
lport, lookupflags, cred);
|
||||
#endif
|
||||
} while (tmpinp != NULL);
|
||||
|
||||
|
|
@ -464,7 +469,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
|||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
|
||||
struct in_addr laddr;
|
||||
u_short lport = 0;
|
||||
int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
|
||||
int lookupflags = 0, reuseport = (so->so_options & SO_REUSEPORT);
|
||||
int error;
|
||||
|
||||
/*
|
||||
|
|
@ -480,7 +485,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
|||
if (nam != NULL && laddr.s_addr != INADDR_ANY)
|
||||
return (EINVAL);
|
||||
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
|
||||
wild = INPLOOKUP_WILDCARD;
|
||||
lookupflags = INPLOOKUP_WILDCARD;
|
||||
if (nam == NULL) {
|
||||
if ((error = prison_local_ip4(cred, &laddr)) != 0)
|
||||
return (error);
|
||||
|
|
@ -561,7 +566,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
|||
return (EADDRINUSE);
|
||||
}
|
||||
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
|
||||
lport, wild, cred);
|
||||
lport, lookupflags, cred);
|
||||
if (t && (t->inp_flags & INP_TIMEWAIT)) {
|
||||
/*
|
||||
* XXXRW: If an incpb has had its timewait
|
||||
|
|
@ -590,7 +595,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
|||
if (*lportp != 0)
|
||||
lport = *lportp;
|
||||
if (lport == 0) {
|
||||
error = in_pcb_lport(inp, &laddr, &lport, cred, wild);
|
||||
error = in_pcb_lport(inp, &laddr, &lport, cred, lookupflags);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
|
|
@ -1028,26 +1033,121 @@ in_pcbdetach(struct inpcb *inp)
|
|||
}
|
||||
|
||||
/*
|
||||
* in_pcbfree_internal() frees an inpcb that has been detached from its
|
||||
* socket, and whose reference count has reached 0. It will also remove the
|
||||
* inpcb from any global lists it might remain on.
|
||||
* in_pcbref() bumps the reference count on an inpcb in order to maintain
|
||||
* stability of an inpcb pointer despite the inpcb lock being released. This
|
||||
* is used in TCP when the inpcbinfo lock needs to be acquired or upgraded,
|
||||
* but where the inpcb lock is already held.
|
||||
*
|
||||
* in_pcbref() should be used only to provide brief memory stability, and
|
||||
* must always be followed by a call to INP_WLOCK() and in_pcbrele() to
|
||||
* garbage collect the inpcb if it has been in_pcbfree()'d from another
|
||||
* context. Until in_pcbrele() has returned that the inpcb is still valid,
|
||||
* lock and rele are the *only* safe operations that may be performed on the
|
||||
* inpcb.
|
||||
*
|
||||
* While the inpcb will not be freed, releasing the inpcb lock means that the
|
||||
* connection's state may change, so the caller should be careful to
|
||||
* revalidate any cached state on reacquiring the lock. Drop the reference
|
||||
* using in_pcbrele().
|
||||
*/
|
||||
static void
|
||||
in_pcbfree_internal(struct inpcb *inp)
|
||||
void
|
||||
in_pcbref(struct inpcb *inp)
|
||||
{
|
||||
struct inpcbinfo *ipi = inp->inp_pcbinfo;
|
||||
|
||||
KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
|
||||
KASSERT(inp->inp_refcount == 0, ("%s: refcount !0", __func__));
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(ipi);
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
|
||||
|
||||
refcount_acquire(&inp->inp_refcount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop a refcount on an inpcb elevated using in_pcbref(); because a call to
|
||||
* in_pcbfree() may have been made between in_pcbref() and in_pcbrele(), we
|
||||
* return a flag indicating whether or not the inpcb remains valid. If it is
|
||||
* valid, we return with the inpcb lock held.
|
||||
*
|
||||
* Notice that, unlike in_pcbref(), the inpcb lock must be held to drop a
|
||||
* reference on an inpcb. Historically more work was done here (actually, in
|
||||
* in_pcbfree_internal()) but has been moved to in_pcbfree() to avoid the
|
||||
* need for the pcbinfo lock in in_pcbrele(). Deferring the free is entirely
|
||||
* about memory stability (and continued use of the write lock).
|
||||
*/
|
||||
int
|
||||
in_pcbrele_rlocked(struct inpcb *inp)
|
||||
{
|
||||
struct inpcbinfo *pcbinfo;
|
||||
|
||||
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
|
||||
|
||||
INP_RLOCK_ASSERT(inp);
|
||||
|
||||
if (refcount_release(&inp->inp_refcount) == 0)
|
||||
return (0);
|
||||
|
||||
KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
|
||||
|
||||
INP_RUNLOCK(inp);
|
||||
pcbinfo = inp->inp_pcbinfo;
|
||||
uma_zfree(pcbinfo->ipi_zone, inp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
in_pcbrele_wlocked(struct inpcb *inp)
|
||||
{
|
||||
struct inpcbinfo *pcbinfo;
|
||||
|
||||
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
|
||||
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
if (refcount_release(&inp->inp_refcount) == 0)
|
||||
return (0);
|
||||
|
||||
KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
|
||||
|
||||
INP_WUNLOCK(inp);
|
||||
pcbinfo = inp->inp_pcbinfo;
|
||||
uma_zfree(pcbinfo->ipi_zone, inp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporary wrapper.
|
||||
*/
|
||||
int
|
||||
in_pcbrele(struct inpcb *inp)
|
||||
{
|
||||
|
||||
return (in_pcbrele_wlocked(inp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Unconditionally schedule an inpcb to be freed by decrementing its
|
||||
* reference count, which should occur only after the inpcb has been detached
|
||||
* from its socket. If another thread holds a temporary reference (acquired
|
||||
* using in_pcbref()) then the free is deferred until that reference is
|
||||
* released using in_pcbrele(), but the inpcb is still unlocked. Almost all
|
||||
* work, including removal from global lists, is done in this context, where
|
||||
* the pcbinfo lock is held.
|
||||
*/
|
||||
void
|
||||
in_pcbfree(struct inpcb *inp)
|
||||
{
|
||||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
|
||||
|
||||
KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(pcbinfo);
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
/* XXXRW: Do as much as possible here. */
|
||||
#ifdef IPSEC
|
||||
if (inp->inp_sp != NULL)
|
||||
ipsec_delete_pcbpolicy(inp);
|
||||
#endif /* IPSEC */
|
||||
inp->inp_gencnt = ++ipi->ipi_gencnt;
|
||||
inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
|
||||
in_pcbremlists(inp);
|
||||
#ifdef INET6
|
||||
if (inp->inp_vflag & INP_IPV6PROTO) {
|
||||
|
|
@ -1064,82 +1164,10 @@ in_pcbfree_internal(struct inpcb *inp)
|
|||
#endif
|
||||
inp->inp_vflag = 0;
|
||||
crfree(inp->inp_cred);
|
||||
|
||||
#ifdef MAC
|
||||
mac_inpcb_destroy(inp);
|
||||
#endif
|
||||
INP_WUNLOCK(inp);
|
||||
uma_zfree(ipi->ipi_zone, inp);
|
||||
}
|
||||
|
||||
/*
|
||||
* in_pcbref() bumps the reference count on an inpcb in order to maintain
|
||||
* stability of an inpcb pointer despite the inpcb lock being released. This
|
||||
* is used in TCP when the inpcbinfo lock needs to be acquired or upgraded,
|
||||
* but where the inpcb lock is already held.
|
||||
*
|
||||
* While the inpcb will not be freed, releasing the inpcb lock means that the
|
||||
* connection's state may change, so the caller should be careful to
|
||||
* revalidate any cached state on reacquiring the lock. Drop the reference
|
||||
* using in_pcbrele().
|
||||
*/
|
||||
void
|
||||
in_pcbref(struct inpcb *inp)
|
||||
{
|
||||
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
|
||||
|
||||
inp->inp_refcount++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop a refcount on an inpcb elevated using in_pcbref(); because a call to
|
||||
* in_pcbfree() may have been made between in_pcbref() and in_pcbrele(), we
|
||||
* return a flag indicating whether or not the inpcb remains valid. If it is
|
||||
* valid, we return with the inpcb lock held.
|
||||
*/
|
||||
int
|
||||
in_pcbrele(struct inpcb *inp)
|
||||
{
|
||||
#ifdef INVARIANTS
|
||||
struct inpcbinfo *ipi = inp->inp_pcbinfo;
|
||||
#endif
|
||||
|
||||
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(ipi);
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
inp->inp_refcount--;
|
||||
if (inp->inp_refcount > 0)
|
||||
return (0);
|
||||
in_pcbfree_internal(inp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unconditionally schedule an inpcb to be freed by decrementing its
|
||||
* reference count, which should occur only after the inpcb has been detached
|
||||
* from its socket. If another thread holds a temporary reference (acquired
|
||||
* using in_pcbref()) then the free is deferred until that reference is
|
||||
* released using in_pcbrele(), but the inpcb is still unlocked.
|
||||
*/
|
||||
void
|
||||
in_pcbfree(struct inpcb *inp)
|
||||
{
|
||||
#ifdef INVARIANTS
|
||||
struct inpcbinfo *ipi = inp->inp_pcbinfo;
|
||||
#endif
|
||||
|
||||
KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL",
|
||||
__func__));
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(ipi);
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
if (!in_pcbrele(inp))
|
||||
if (!in_pcbrele_wlocked(inp))
|
||||
INP_WUNLOCK(inp);
|
||||
}
|
||||
|
||||
|
|
@ -1307,7 +1335,7 @@ in_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp)
|
|||
#define INP_LOOKUP_MAPPED_PCB_COST 3
|
||||
struct inpcb *
|
||||
in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
|
||||
u_short lport, int wild_okay, struct ucred *cred)
|
||||
u_short lport, int lookupflags, struct ucred *cred)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
#ifdef INET6
|
||||
|
|
@ -1317,9 +1345,12 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
|
|||
#endif
|
||||
int wildcard;
|
||||
|
||||
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
||||
("%s: invalid lookup flags %d", __func__, lookupflags));
|
||||
|
||||
INP_INFO_LOCK_ASSERT(pcbinfo);
|
||||
|
||||
if (!wild_okay) {
|
||||
if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
|
||||
struct inpcbhead *head;
|
||||
/*
|
||||
* Look for an unconnected (wildcard foreign addr) PCB that
|
||||
|
|
@ -1425,13 +1456,16 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
|
|||
*/
|
||||
struct inpcb *
|
||||
in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
||||
u_int fport_arg, struct in_addr laddr, u_int lport_arg, int wildcard,
|
||||
u_int fport_arg, struct in_addr laddr, u_int lport_arg, int lookupflags,
|
||||
struct ifnet *ifp)
|
||||
{
|
||||
struct inpcbhead *head;
|
||||
struct inpcb *inp, *tmpinp;
|
||||
u_short fport = fport_arg, lport = lport_arg;
|
||||
|
||||
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
||||
("%s: invalid lookup flags %d", __func__, lookupflags));
|
||||
|
||||
INP_INFO_LOCK_ASSERT(pcbinfo);
|
||||
|
||||
/*
|
||||
|
|
@ -1467,7 +1501,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
|||
/*
|
||||
* Then look for a wildcard match, if requested.
|
||||
*/
|
||||
if (wildcard == INPLOOKUP_WILDCARD) {
|
||||
if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
|
||||
struct inpcb *local_wild = NULL, *local_exact = NULL;
|
||||
#ifdef INET6
|
||||
struct inpcb *local_wild_mapped = NULL;
|
||||
|
|
@ -1538,7 +1572,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
|||
if (local_wild_mapped != NULL)
|
||||
return (local_wild_mapped);
|
||||
#endif /* defined(INET6) */
|
||||
} /* if (wildcard == INPLOOKUP_WILDCARD) */
|
||||
} /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
/*-
|
||||
* Copyright (c) 1982, 1986, 1990, 1993
|
||||
* The Regents of the University of California.
|
||||
* Copyright (c) 2010-2011 Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Robert N. M. Watson under
|
||||
* contract to Juniper Networks, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
|
@ -260,53 +264,70 @@ struct inpcbport {
|
|||
u_short phd_port;
|
||||
};
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Global data structure for each high-level protocol (UDP, TCP, ...) in both
|
||||
* IPv4 and IPv6. Holds inpcb lists and information for managing them.
|
||||
*
|
||||
* Each pcbinfo is protected by ipi_lock, covering mutable global fields (such
|
||||
* as the global pcb list) and hashed lookup tables. The lock order is:
|
||||
*
|
||||
* ipi_lock (before) inpcb locks
|
||||
*
|
||||
* Locking key:
|
||||
*
|
||||
* (c) Constant or nearly constant after initialisation
|
||||
* (g) Locked by ipi_lock
|
||||
* (h) Read using either ipi_lock or inpcb lock; write requires both.
|
||||
* (x) Synchronisation properties poorly defined
|
||||
*/
|
||||
struct inpcbinfo {
|
||||
/*
|
||||
* Global lock protecting global inpcb list, inpcb count, hash tables,
|
||||
* etc.
|
||||
*/
|
||||
struct rwlock ipi_lock;
|
||||
|
||||
/*
|
||||
* Global list of inpcbs on the protocol.
|
||||
*/
|
||||
struct inpcbhead *ipi_listhead;
|
||||
u_int ipi_count;
|
||||
struct inpcbhead *ipi_listhead; /* (g) */
|
||||
u_int ipi_count; /* (g) */
|
||||
|
||||
/*
|
||||
* Generation count -- incremented each time a connection is allocated
|
||||
* or freed.
|
||||
*/
|
||||
u_quad_t ipi_gencnt; /* (g) */
|
||||
|
||||
/*
|
||||
* Fields associated with port lookup and allocation.
|
||||
*/
|
||||
u_short ipi_lastport; /* (x) */
|
||||
u_short ipi_lastlow; /* (x) */
|
||||
u_short ipi_lasthi; /* (x) */
|
||||
|
||||
/*
|
||||
* UMA zone from which inpcbs are allocated for this protocol.
|
||||
*/
|
||||
struct uma_zone *ipi_zone; /* (c) */
|
||||
|
||||
/*
|
||||
* Global hash of inpcbs, hashed by local and foreign addresses and
|
||||
* port numbers.
|
||||
*/
|
||||
struct inpcbhead *ipi_hashbase;
|
||||
u_long ipi_hashmask;
|
||||
struct inpcbhead *ipi_hashbase; /* (g) */
|
||||
u_long ipi_hashmask; /* (g) */
|
||||
|
||||
/*
|
||||
* Global hash of inpcbs, hashed by only local port number.
|
||||
*/
|
||||
struct inpcbporthead *ipi_porthashbase;
|
||||
u_long ipi_porthashmask;
|
||||
|
||||
/*
|
||||
* Fields associated with port lookup and allocation.
|
||||
*/
|
||||
u_short ipi_lastport;
|
||||
u_short ipi_lastlow;
|
||||
u_short ipi_lasthi;
|
||||
|
||||
/*
|
||||
* UMA zone from which inpcbs are allocated for this protocol.
|
||||
*/
|
||||
struct uma_zone *ipi_zone;
|
||||
|
||||
/*
|
||||
* Generation count--incremented each time a connection is allocated
|
||||
* or freed.
|
||||
*/
|
||||
u_quad_t ipi_gencnt;
|
||||
struct rwlock ipi_lock;
|
||||
struct inpcbporthead *ipi_porthashbase; /* (g) */
|
||||
u_long ipi_porthashmask; /* (g) */
|
||||
|
||||
/*
|
||||
* Pointer to network stack instance
|
||||
*/
|
||||
struct vnet *ipi_vnet;
|
||||
struct vnet *ipi_vnet; /* (c) */
|
||||
|
||||
/*
|
||||
* general use 2
|
||||
|
|
@ -513,6 +534,8 @@ void in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr,
|
|||
void in_pcbref(struct inpcb *);
|
||||
void in_pcbrehash(struct inpcb *);
|
||||
int in_pcbrele(struct inpcb *);
|
||||
int in_pcbrele_rlocked(struct inpcb *);
|
||||
int in_pcbrele_wlocked(struct inpcb *);
|
||||
void in_pcbsetsolabel(struct socket *so);
|
||||
int in_getpeeraddr(struct socket *so, struct sockaddr **nam);
|
||||
int in_getsockaddr(struct socket *so, struct sockaddr **nam);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,8 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
|||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
|
||||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
|
||||
u_short lport = 0;
|
||||
int error, wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
|
||||
int error, lookupflags = 0;
|
||||
int reuseport = (so->so_options & SO_REUSEPORT);
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(pcbinfo);
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
|
@ -121,7 +122,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
|||
if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
|
||||
return (EINVAL);
|
||||
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
|
||||
wild = INPLOOKUP_WILDCARD;
|
||||
lookupflags = INPLOOKUP_WILDCARD;
|
||||
if (nam == NULL) {
|
||||
if ((error = prison_local_ip6(cred, &inp->in6p_laddr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
|
||||
|
|
@ -226,7 +227,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
|||
#endif
|
||||
}
|
||||
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
|
||||
lport, wild, cred);
|
||||
lport, lookupflags, cred);
|
||||
if (t && (reuseport & ((t->inp_flags & INP_TIMEWAIT) ?
|
||||
intotw(t)->tw_so_options :
|
||||
t->inp_socket->so_options)) == 0)
|
||||
|
|
@ -238,7 +239,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
|||
|
||||
in6_sin6_2_sin(&sin, sin6);
|
||||
t = in_pcblookup_local(pcbinfo, sin.sin_addr,
|
||||
lport, wild, cred);
|
||||
lport, lookupflags, cred);
|
||||
if (t && t->inp_flags & INP_TIMEWAIT) {
|
||||
if ((reuseport &
|
||||
intotw(t)->tw_so_options) == 0 &&
|
||||
|
|
@ -652,14 +653,17 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst,
|
|||
*/
|
||||
struct inpcb *
|
||||
in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr,
|
||||
u_short lport, int wild_okay, struct ucred *cred)
|
||||
u_short lport, int lookupflags, struct ucred *cred)
|
||||
{
|
||||
register struct inpcb *inp;
|
||||
int matchwild = 3, wildcard;
|
||||
|
||||
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
||||
("%s: invalid lookup flags %d", __func__, lookupflags));
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(pcbinfo);
|
||||
|
||||
if (!wild_okay) {
|
||||
if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
|
||||
struct inpcbhead *head;
|
||||
/*
|
||||
* Look for an unconnected (wildcard foreign addr) PCB that
|
||||
|
|
@ -815,7 +819,7 @@ in6_rtchange(struct inpcb *inp, int errno)
|
|||
*/
|
||||
struct inpcb *
|
||||
in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
||||
u_int fport_arg, struct in6_addr *laddr, u_int lport_arg, int wildcard,
|
||||
u_int fport_arg, struct in6_addr *laddr, u_int lport_arg, int lookupflags,
|
||||
struct ifnet *ifp)
|
||||
{
|
||||
struct inpcbhead *head;
|
||||
|
|
@ -823,6 +827,9 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
|||
u_short fport = fport_arg, lport = lport_arg;
|
||||
int faith;
|
||||
|
||||
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
||||
("%s: invalid lookup flags %d", __func__, lookupflags));
|
||||
|
||||
INP_INFO_LOCK_ASSERT(pcbinfo);
|
||||
|
||||
if (faithprefix_p != NULL)
|
||||
|
|
@ -862,7 +869,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
|||
/*
|
||||
* Then look for a wildcard match, if requested.
|
||||
*/
|
||||
if (wildcard == INPLOOKUP_WILDCARD) {
|
||||
if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
|
||||
struct inpcb *local_wild = NULL, *local_exact = NULL;
|
||||
struct inpcb *jail_wild = NULL;
|
||||
int injail;
|
||||
|
|
@ -919,7 +926,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
|||
return (local_exact);
|
||||
if (local_wild != NULL)
|
||||
return (local_wild);
|
||||
} /* if (wildcard == INPLOOKUP_WILDCARD) */
|
||||
} /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */
|
||||
|
||||
/*
|
||||
* Not found.
|
||||
|
|
|
|||
|
|
@ -851,7 +851,7 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
|
|||
{
|
||||
struct socket *so = inp->inp_socket;
|
||||
u_int16_t lport = 0;
|
||||
int error, wild = 0;
|
||||
int error, lookupflags = 0;
|
||||
#ifdef INVARIANTS
|
||||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
|
||||
#endif
|
||||
|
|
@ -866,11 +866,11 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
|
|||
|
||||
/* XXX: this is redundant when called from in6_pcbbind */
|
||||
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
|
||||
wild = INPLOOKUP_WILDCARD;
|
||||
lookupflags = INPLOOKUP_WILDCARD;
|
||||
|
||||
inp->inp_flags |= INP_ANONPORT;
|
||||
|
||||
error = in_pcb_lport(inp, NULL, &lport, cred, wild);
|
||||
error = in_pcb_lport(inp, NULL, &lport, cred, lookupflags);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.10 2006/05/12 02:01:15 mrg Exp $
|
||||
# $NetBSD: Makefile,v 1.13 2009/04/14 22:15:20 lukem Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd April 27, 2010
|
||||
.Dd May 23, 2011
|
||||
.Dt GZIP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -127,9 +127,9 @@ stream, leaving files intact.
|
|||
This option selects decompression rather than compression.
|
||||
.It Fl f , -force
|
||||
This option turns on force mode.
|
||||
This allows files with multiple links, overwriting of pre-existing
|
||||
files, reading from or writing to a terminal, and when combined
|
||||
with the
|
||||
This allows files with multiple links, symbolic links to regular files,
|
||||
overwriting of pre-existing files, reading from or writing to a terminal,
|
||||
and when combined with the
|
||||
.Fl c
|
||||
option, allowing non-compressed data to pass through unchanged.
|
||||
.It Fl h , -help
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: gzip.c,v 1.97 2009/10/11 09:17:21 mrg Exp $ */
|
||||
/* $NetBSD: gzip.c,v 1.99 2011/03/23 12:59:44 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006\
|
||||
Matthew R. Green. All rights reserved.");
|
||||
__RCSID("$FreeBSD$");
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
|
@ -146,7 +146,7 @@ static suffixes_t suffixes[] = {
|
|||
#define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0])
|
||||
#define SUFFIX_MAXLEN 30
|
||||
|
||||
static const char gzip_version[] = "FreeBSD gzip 20100407";
|
||||
static const char gzip_version[] = "FreeBSD gzip 20110523";
|
||||
|
||||
#ifndef SMALL
|
||||
static const char gzip_copyright[] = \
|
||||
|
|
@ -314,7 +314,7 @@ main(int argc, char **argv)
|
|||
dflag = cflag = 1;
|
||||
|
||||
#ifdef SMALL
|
||||
#define OPT_LIST "123456789cdhltV"
|
||||
#define OPT_LIST "123456789cdhlV"
|
||||
#else
|
||||
#define OPT_LIST "123456789acdfhklLNnqrS:tVv"
|
||||
#endif
|
||||
|
|
@ -918,6 +918,7 @@ gz_uncompress(int in, int out, char *pre, size_t prelen, off_t *gsizep,
|
|||
case Z_BUF_ERROR:
|
||||
if (z.avail_out > 0 && !done_reading)
|
||||
continue;
|
||||
|
||||
case Z_STREAM_END:
|
||||
case Z_OK:
|
||||
break;
|
||||
|
|
@ -1781,7 +1782,7 @@ handle_pathname(char *path)
|
|||
}
|
||||
|
||||
retry:
|
||||
if (stat(path, &sb) != 0) {
|
||||
if (stat(path, &sb) != 0 || (fflag == 0 && lstat(path, &sb) != 0)) {
|
||||
/* lets try <path>.gz if we're decompressing */
|
||||
if (dflag && s == NULL && errno == ENOENT) {
|
||||
len = strlen(path);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
#!/bin/sh -
|
||||
#
|
||||
# $NetBSD: zdiff,v 1.3 2004/03/29 10:01:00 wiz Exp $
|
||||
# $NetBSD: zdiff,v 1.5 2010/04/14 20:30:28 joerg Exp $
|
||||
#
|
||||
# $OpenBSD: zdiff,v 1.2 2003/07/29 07:42:44 otto Exp $
|
||||
#
|
||||
#-
|
||||
# Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
# Copyright (c) 2010 Joerg Sonnenberger <joerg@NetBSD.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -31,7 +33,57 @@ case $0 in
|
|||
*) prog=diff
|
||||
;;
|
||||
esac
|
||||
USAGE="usage: z$prog [options] file1 [file2]"
|
||||
USAGE="usage: $0 [options] file1 [file2]"
|
||||
|
||||
check_suffix() {
|
||||
case "$1" in
|
||||
*[._-][Zz])
|
||||
setvar $2 "${1%??}"
|
||||
setvar $3 "gzip -cdqf"
|
||||
;;
|
||||
*[._-]bz)
|
||||
setvar $2 "${1%???}"
|
||||
setvar $3 "bzip2 -cdqf"
|
||||
;;
|
||||
*[._-]gz)
|
||||
setvar $2 "${1%???}"
|
||||
setvar $3 "gzip -cdqf"
|
||||
;;
|
||||
*[._-]xz)
|
||||
setvar $2 "${1%???}"
|
||||
setvar $3 "xz -cdqf"
|
||||
;;
|
||||
*[._-]bz2)
|
||||
setvar $2 "${1%????}"
|
||||
setvar $3 "bzip2 -cdqf"
|
||||
;;
|
||||
*[._-]lzma)
|
||||
setvar $2 "${1%?????}"
|
||||
setvar $3 "xz -cdqf"
|
||||
;;
|
||||
*.t[ag]z)
|
||||
setvar $2 "${1%??}"ar
|
||||
setvar $3 "gzip -cdqf"
|
||||
;;
|
||||
*.tbz)
|
||||
setvar $2 "${1%??}"ar
|
||||
setvar $3 "bzip2 -cdqf"
|
||||
;;
|
||||
*.tbz2)
|
||||
setvar $2 "${1%???}"ar
|
||||
setvar $3 "bzip2 -cdqf"
|
||||
;;
|
||||
*.t[lx]z)
|
||||
setvar $2 "${1%??}"ar
|
||||
setvar $3 "xz -cdqf"
|
||||
;;
|
||||
*)
|
||||
setvar $2 "$1"
|
||||
setvar $3 ""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
# Pull out any command line flags so we can pass them to diff/cmp
|
||||
# XXX - assumes there is no optarg
|
||||
|
|
@ -42,6 +94,9 @@ while test $# -ne 0; do
|
|||
shift
|
||||
break
|
||||
;;
|
||||
-)
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
flags="$flags $1"
|
||||
shift
|
||||
|
|
@ -55,52 +110,28 @@ done
|
|||
if [ $# -eq 1 ]; then
|
||||
# One file given, compare compressed to uncompressed
|
||||
files="$1"
|
||||
case "$1" in
|
||||
*[._-][Zz])
|
||||
files="${1%??}"
|
||||
;;
|
||||
*[._-]gz)
|
||||
files="${1%???}"
|
||||
;;
|
||||
*.t[ag]z)
|
||||
files="${1%??}"ar
|
||||
;;
|
||||
*) echo "z$prog: unknown suffix" 1>&2
|
||||
exit 1
|
||||
esac
|
||||
gzip -cdfq "$1" | $prog $flags - "$files"
|
||||
check_suffix "$1" files filt
|
||||
if [ -z "$filt" ]; then
|
||||
echo "z$prog: unknown suffix" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
$filt -- "$1" | $prog $flags -- - "$files"
|
||||
status=$?
|
||||
elif [ $# -eq 2 ]; then
|
||||
# Two files given, compare the two uncompressing as needed
|
||||
case "$1" in
|
||||
*[._-][Zz]|*[._-]gz|*.t[ag]z)
|
||||
files=-
|
||||
filt="gzip -cdfq $1"
|
||||
;;
|
||||
*)
|
||||
files="$1"
|
||||
;;
|
||||
esac
|
||||
case "$2" in
|
||||
*[._-][Zz]|*[._-]gz|*.t[ag]z)
|
||||
if [ "$files" = "-" ]; then
|
||||
tmp=`mktemp -t z$prog.XXXXXXXXXX` || exit 1
|
||||
trap "rm -f $tmp" 0 1 2 3 13 15
|
||||
gzip -cdfq "$2" > $tmp
|
||||
files="$files $tmp"
|
||||
else
|
||||
files="$files -"
|
||||
filt="gzip -cdfq $2"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
files="$files $2"
|
||||
;;
|
||||
esac
|
||||
if [ -n "$filt" ]; then
|
||||
$filt | $prog $flags $files
|
||||
check_suffix "$1" files filt
|
||||
check_suffix "$2" files2 filt2
|
||||
if [ -z "$filt" -a -z "$filt2" ]; then
|
||||
$prog $flags -- "$1" "$2"
|
||||
elif [ -z "$filt" -a -n "$filt2" -a "$1" != "-" ]; then
|
||||
$filt2 -- "$2" | $prog $flags -- "$1" -
|
||||
elif [ -n "$filt" -a -z "$filt2" -a "$2" != "-" ]; then
|
||||
$filt -- "$1" | $prog $flags -- - "$2"
|
||||
else
|
||||
$prog $flags $files
|
||||
tmp=`mktemp -t z$prog.XXXXXXXXXX` || exit 1
|
||||
trap "rm -f $tmp" 0 1 2 3 13 15
|
||||
${filt2:-cat} -- "$2" > $tmp || exit $?
|
||||
${filt:-cat} -- "$1" | $prog $flags -- - "$tmp"
|
||||
fi
|
||||
status=$?
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
.\" $NetBSD: zdiff.1,v 1.3 2003/12/28 12:48:03 wiz Exp $
|
||||
.\" $NetBSD: zdiff.1,v 1.5 2010/04/14 19:52:05 wiz Exp $
|
||||
.\" $OpenBSD: zdiff.1,v 1.2 2003/07/13 17:39:14 millert Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger <joerg@NetBSD.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -20,7 +21,7 @@
|
|||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd January 26, 2007
|
||||
.Dd May 23, 2011
|
||||
.Dt ZDIFF 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -45,15 +46,6 @@ are filters that invoke
|
|||
or
|
||||
.Xr diff 1
|
||||
respectively to compare compressed files.
|
||||
Such files generally have a
|
||||
.Dq Z
|
||||
or
|
||||
.Dq gz
|
||||
extension (both the
|
||||
.Xr compress 1
|
||||
and
|
||||
.Xr gzip 1
|
||||
formats are supported).
|
||||
Any
|
||||
.Ar options
|
||||
that are specified are passed to
|
||||
|
|
@ -70,6 +62,45 @@ When both
|
|||
or
|
||||
.Ar file2
|
||||
are specified, either file may be compressed.
|
||||
.Pp
|
||||
Extensions handled by
|
||||
.Xr gzip 1 :
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
z, Z,
|
||||
.It
|
||||
gz,
|
||||
.It
|
||||
taz,
|
||||
.It
|
||||
tgz.
|
||||
.El
|
||||
.Pp
|
||||
Extensions handled by
|
||||
.Xr bzip2 1 :
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
bz,
|
||||
.It
|
||||
bz2,
|
||||
.It
|
||||
tbz,
|
||||
.It
|
||||
tbz2.
|
||||
.El
|
||||
.Pp
|
||||
Extensions handled by
|
||||
.Xr xz 1 :
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
lzma,
|
||||
.It
|
||||
xz,
|
||||
.It
|
||||
tlz,
|
||||
.It
|
||||
txz.
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width "TMPDIR"
|
||||
.It Ev TMPDIR
|
||||
|
|
@ -88,9 +119,11 @@ Temporary file for
|
|||
.Nm zdiff .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr bzip2 1 ,
|
||||
.Xr cmp 1 ,
|
||||
.Xr compress 1 ,
|
||||
.Xr diff 1
|
||||
.Xr diff 1 ,
|
||||
.Xr gzip 1 ,
|
||||
.Xr xz 1
|
||||
.Sh CAVEATS
|
||||
.Nm zcmp
|
||||
and
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: zuncompress.c,v 1.7 2009/04/12 10:31:14 lukem Exp $ */
|
||||
/* $NetBSD: zuncompress.c,v 1.8 2010/11/06 21:42:32 mrg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1985, 1986, 1992, 1993
|
||||
|
|
|
|||
Loading…
Reference in a new issue