lkml.org 
[lkml]   [2006]   [Jun]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: Linux 2.6.17.2
    diff --git a/Makefile b/Makefile
    index 8bafed1..7b3837f 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -1,7 +1,7 @@
    VERSION = 2
    PATCHLEVEL = 6
    SUBLEVEL = 17
    -EXTRAVERSION = .1
    +EXTRAVERSION = .2
    NAME=Crazed Snow-Weasel

    # *DOCUMENTATION*
    diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
    index 77840c8..7215849 100644
    --- a/arch/sparc/mm/iommu.c
    +++ b/arch/sparc/mm/iommu.c
    @@ -144,8 +144,9 @@ static void iommu_flush_iotlb(iopte_t *i
    unsigned long start;
    unsigned long end;

    - start = (unsigned long)iopte & PAGE_MASK;
    + start = (unsigned long)iopte;
    end = PAGE_ALIGN(start + niopte*sizeof(iopte_t));
    + start &= PAGE_MASK;
    if (viking_mxcc_present) {
    while(start < end) {
    viking_mxcc_flush_page(start);
    diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
    index 86f51d0..87cdbc5 100644
    --- a/arch/um/kernel/time_kern.c
    +++ b/arch/um/kernel/time_kern.c
    @@ -87,7 +87,7 @@ #endif

    void time_init_kern(void)
    {
    - unsigned long long nsecs;
    + long long nsecs;

    nsecs = os_nsecs();
    set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
    diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
    index c01615d..5748554 100644
    --- a/drivers/ide/ide-io.c
    +++ b/drivers/ide/ide-io.c
    @@ -932,7 +932,7 @@ #endif
    printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
    SELECT_DRIVE(drive);
    HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
    - rc = ide_wait_not_busy(HWIF(drive), 10000);
    + rc = ide_wait_not_busy(HWIF(drive), 100000);
    if (rc)
    printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
    }
    diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
    index 11f1377..8f1292c 100644
    --- a/drivers/ieee1394/ohci1394.c
    +++ b/drivers/ieee1394/ohci1394.c
    @@ -3539,6 +3539,7 @@ #ifdef CONFIG_PPC_PMAC
    }
    #endif /* CONFIG_PPC_PMAC */

    + pci_restore_state(pdev);
    pci_enable_device(pdev);

    return 0;
    @@ -3558,6 +3559,8 @@ #ifdef CONFIG_PPC_PMAC
    }
    #endif

    + pci_save_state(pdev);
    +
    return 0;
    }

    diff --git a/drivers/input/input.c b/drivers/input/input.c
    index 3038c26..b149c94 100644
    --- a/drivers/input/input.c
    +++ b/drivers/input/input.c
    @@ -629,7 +629,7 @@ static ssize_t input_dev_show_modalias(s

    len = input_print_modalias(buf, PAGE_SIZE, id, 1);

    - return max_t(int, len, PAGE_SIZE);
    + return min_t(int, len, PAGE_SIZE);
    }
    static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);

    diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
    index 7ed18ca..513fc75 100644
    --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
    +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
    @@ -1870,6 +1870,15 @@ static irqreturn_t bcm43xx_interrupt_han

    spin_lock(&bcm->_lock);

    + /* Only accept IRQs, if we are initialized properly.
    + * This avoids an RX race while initializing.
    + * We should probably not enable IRQs before we are initialized
    + * completely, but some careful work is needed to fix this. I think it
    + * is best to stay with this cheap workaround for now... .
    + */
    + if (unlikely(!bcm->initialized))
    + goto out;
    +
    reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
    if (reason == 0xffffffff) {
    /* irq not for us (shared irq) */
    @@ -1891,20 +1900,11 @@ static irqreturn_t bcm43xx_interrupt_han

    bcm43xx_interrupt_ack(bcm, reason);

    - /* Only accept IRQs, if we are initialized properly.
    - * This avoids an RX race while initializing.
    - * We should probably not enable IRQs before we are initialized
    - * completely, but some careful work is needed to fix this. I think it
    - * is best to stay with this cheap workaround for now... .
    - */
    - if (likely(bcm->initialized)) {
    - /* disable all IRQs. They are enabled again in the bottom half. */
    - bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
    - /* save the reason code and call our bottom half. */
    - bcm->irq_reason = reason;
    - tasklet_schedule(&bcm->isr_tasklet);
    - }
    -
    + /* disable all IRQs. They are enabled again in the bottom half. */
    + bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
    + /* save the reason code and call our bottom half. */
    + bcm->irq_reason = reason;
    + tasklet_schedule(&bcm->isr_tasklet);
    out:
    mmiowb();
    spin_unlock(&bcm->_lock);
    diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
    index f63c387..6c8452e 100644
    --- a/drivers/parport/Kconfig
    +++ b/drivers/parport/Kconfig
    @@ -48,7 +48,7 @@ config PARPORT_PC

    config PARPORT_SERIAL
    tristate "Multi-IO cards (parallel and serial)"
    - depends on SERIAL_8250 && PARPORT_PC && PCI
    + depends on SERIAL_8250_PCI && PARPORT_PC && PCI
    help
    This adds support for multi-IO PCI cards that have parallel and
    serial ports. You should say Y or M here. If you say M, the module
    diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
    index b046ffa..6cd197d 100644
    --- a/drivers/scsi/libata-core.c
    +++ b/drivers/scsi/libata-core.c
    @@ -1229,7 +1229,7 @@ static int ata_dev_configure(struct ata_
    id[84], id[85], id[86], id[87], id[88]);

    /* initialize to-be-configured parameters */
    - dev->flags = 0;
    + dev->flags &= ~ATA_DFLAG_CFG_MASK;
    dev->max_sectors = 0;
    dev->cdb_len = 0;
    dev->n_sectors = 0;
    diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
    index f806553..3ced09c 100644
    --- a/drivers/usb/serial/whiteheat.c
    +++ b/drivers/usb/serial/whiteheat.c
    @@ -388,7 +388,7 @@ static int whiteheat_attach (struct usb_
    if (ret) {
    err("%s: Couldn't send command [%d]", serial->type->description, ret);
    goto no_firmware;
    - } else if (alen != sizeof(command)) {
    + } else if (alen != 2) {
    err("%s: Send command incomplete [%d]", serial->type->description, alen);
    goto no_firmware;
    }
    @@ -400,7 +400,7 @@ static int whiteheat_attach (struct usb_
    if (ret) {
    err("%s: Couldn't get results [%d]", serial->type->description, ret);
    goto no_firmware;
    - } else if (alen != sizeof(result)) {
    + } else if (alen != sizeof(*hw_info) + 1) {
    err("%s: Get results incomplete [%d]", serial->type->description, alen);
    goto no_firmware;
    } else if (result[0] != command[0]) {
    diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
    index c63a83e..36e1e13 100644
    --- a/fs/ntfs/file.c
    +++ b/fs/ntfs/file.c
    @@ -1484,14 +1484,15 @@ static inline void ntfs_flush_dcache_pag
    unsigned nr_pages)
    {
    BUG_ON(!nr_pages);
    + /*
    + * Warning: Do not do the decrement at the same time as the call to
    + * flush_dcache_page() because it is a NULL macro on i386 and hence the
    + * decrement never happens so the loop never terminates.
    + */
    do {
    - /*
    - * Warning: Do not do the decrement at the same time as the
    - * call because flush_dcache_page() is a NULL macro on i386
    - * and hence the decrement never happens.
    - */
    + --nr_pages;
    flush_dcache_page(pages[nr_pages]);
    - } while (--nr_pages > 0);
    + } while (nr_pages > 0);
    }

    /**
    diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h
    index e201dec..d79e9ee 100644
    --- a/include/asm-i386/alternative.h
    +++ b/include/asm-i386/alternative.h
    @@ -3,6 +3,8 @@ #define _I386_ALTERNATIVE_H

    #ifdef __KERNEL__

    +#include <asm/types.h>
    +
    struct alt_instr {
    u8 *instr; /* original instruction */
    u8 *replacement;
    diff --git a/include/linux/libata.h b/include/linux/libata.h
    index b80d2e7..05d3fb3 100644
    --- a/include/linux/libata.h
    +++ b/include/linux/libata.h
    @@ -120,9 +120,12 @@ enum {
    ATA_SHT_USE_CLUSTERING = 1,

    /* struct ata_device stuff */
    - ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */
    - ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */
    - ATA_DFLAG_LBA = (1 << 2), /* device supports LBA */
    + ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */
    + ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */
    +
    + ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
    +
    + ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */

    ATA_DEV_UNKNOWN = 0, /* unknown device */
    ATA_DEV_ATA = 1, /* ATA device */
    diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
    index bac0fb3..d5dd471 100644
    --- a/include/linux/pfkeyv2.h
    +++ b/include/linux/pfkeyv2.h
    @@ -159,7 +159,7 @@ struct sadb_spirange {
    struct sadb_x_kmprivate {
    uint16_t sadb_x_kmprivate_len;
    uint16_t sadb_x_kmprivate_exttype;
    - u_int32_t sadb_x_kmprivate_reserved;
    + uint32_t sadb_x_kmprivate_reserved;
    } __attribute__((packed));
    /* sizeof(struct sadb_x_kmprivate) == 8 */

    diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
    index 7f4fea1..5f69158 100644
    --- a/include/net/sctp/structs.h
    +++ b/include/net/sctp/structs.h
    @@ -555,7 +555,8 @@ struct sctp_af {
    int (*to_addr_param) (const union sctp_addr *,
    union sctp_addr_param *);
    int (*addr_valid) (union sctp_addr *,
    - struct sctp_sock *);
    + struct sctp_sock *,
    + const struct sk_buff *);
    sctp_scope_t (*scope) (union sctp_addr *);
    void (*inaddr_any) (union sctp_addr *, unsigned short);
    int (*is_any) (const union sctp_addr *);
    diff --git a/kernel/exit.c b/kernel/exit.c
    index e06d0c1..ccf791b 100644
    --- a/kernel/exit.c
    +++ b/kernel/exit.c
    @@ -899,7 +899,7 @@ fastcall NORET_TYPE void do_exit(long co
    }
    if (unlikely(tsk->robust_list))
    exit_robust_list(tsk);
    -#ifdef CONFIG_COMPAT
    +#if defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT)
    if (unlikely(tsk->compat_robust_list))
    compat_exit_robust_list(tsk);
    #endif
    diff --git a/lib/idr.c b/lib/idr.c
    index d226259..de19030 100644
    --- a/lib/idr.c
    +++ b/lib/idr.c
    @@ -48,15 +48,21 @@ static struct idr_layer *alloc_layer(str
    return(p);
    }

    +/* only called when idp->lock is held */
    +static void __free_layer(struct idr *idp, struct idr_layer *p)
    +{
    + p->ary[0] = idp->id_free;
    + idp->id_free = p;
    + idp->id_free_cnt++;
    +}
    +
    static void free_layer(struct idr *idp, struct idr_layer *p)
    {
    /*
    * Depends on the return element being zeroed.
    */
    spin_lock(&idp->lock);
    - p->ary[0] = idp->id_free;
    - idp->id_free = p;
    - idp->id_free_cnt++;
    + __free_layer(idp, p);
    spin_unlock(&idp->lock);
    }

    @@ -184,12 +190,14 @@ build_up:
    * The allocation failed. If we built part of
    * the structure tear it down.
    */
    + spin_lock(&idp->lock);
    for (new = p; p && p != idp->top; new = p) {
    p = p->ary[0];
    new->ary[0] = NULL;
    new->bitmap = new->count = 0;
    - free_layer(idp, new);
    + __free_layer(idp, new);
    }
    + spin_unlock(&idp->lock);
    return -1;
    }
    new->ary[0] = p;
    diff --git a/net/core/ethtool.c b/net/core/ethtool.c
    index e6f7610..c680b7e 100644
    --- a/net/core/ethtool.c
    +++ b/net/core/ethtool.c
    @@ -591,7 +591,7 @@ static int ethtool_set_tso(struct net_de

    static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
    {
    - struct ethtool_value edata = { ETHTOOL_GTSO };
    + struct ethtool_value edata = { ETHTOOL_GUFO };

    if (!dev->ethtool_ops->get_ufo)
    return -EOPNOTSUPP;
    @@ -600,6 +600,7 @@ static int ethtool_get_ufo(struct net_de
    return -EFAULT;
    return 0;
    }
    +
    static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
    {
    struct ethtool_value edata;
    diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
    index 445006e..4da6645 100644
    --- a/net/ipv6/addrconf.c
    +++ b/net/ipv6/addrconf.c
    @@ -862,6 +862,8 @@ static int inline ipv6_saddr_label(const
    * 2002::/16 2
    * ::/96 3
    * ::ffff:0:0/96 4
    + * fc00::/7 5
    + * 2001::/32 6
    */
    if (type & IPV6_ADDR_LOOPBACK)
    return 0;
    @@ -869,8 +871,12 @@ static int inline ipv6_saddr_label(const
    return 3;
    else if (type & IPV6_ADDR_MAPPED)
    return 4;
    + else if (addr->s6_addr32[0] == htonl(0x20010000))
    + return 6;
    else if (addr->s6_addr16[0] == htons(0x2002))
    return 2;
    + else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
    + return 5;
    return 1;
    }

    @@ -1069,6 +1075,9 @@ #ifdef CONFIG_IPV6_PRIVACY
    if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
    continue;
    }
    +#else
    + if (hiscore.rule < 7)
    + hiscore.rule++;
    #endif
    /* Rule 8: Use longest matching prefix */
    if (hiscore.rule < 8) {
    @@ -2860,6 +2869,11 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
    return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
    }

    +/* Maximum length of ifa_cacheinfo attributes */
    +#define INET6_IFADDR_RTA_SPACE \
    + RTA_SPACE(16) /* IFA_ADDRESS */ + \
    + RTA_SPACE(sizeof(struct ifa_cacheinfo)) /* CACHEINFO */
    +
    static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
    u32 pid, u32 seq, int event, unsigned int flags)
    {
    @@ -3092,7 +3106,7 @@ static int inet6_dump_ifacaddr(struct sk
    static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
    {
    struct sk_buff *skb;
    - int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
    + int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE);

    skb = alloc_skb(size, GFP_ATOMIC);
    if (!skb) {
    @@ -3142,6 +3156,17 @@ #endif
    #endif
    }

    +/* Maximum length of ifinfomsg attributes */
    +#define INET6_IFINFO_RTA_SPACE \
    + RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \
    + RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ + \
    + RTA_SPACE(sizeof(u32)) /* MTU */ + \
    + RTA_SPACE(sizeof(int)) /* LINK */ + \
    + RTA_SPACE(0) /* PROTINFO */ + \
    + RTA_SPACE(sizeof(u32)) /* FLAGS */ + \
    + RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \
    + RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */
    +
    static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
    u32 pid, u32 seq, int event, unsigned int flags)
    {
    @@ -3235,8 +3260,7 @@ static int inet6_dump_ifinfo(struct sk_b
    void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
    {
    struct sk_buff *skb;
    - /* 128 bytes ?? */
    - int size = NLMSG_SPACE(sizeof(struct ifinfomsg)+128);
    + int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE);

    skb = alloc_skb(size, GFP_ATOMIC);
    if (!skb) {
    @@ -3252,6 +3276,11 @@ void inet6_ifinfo_notify(int event, stru
    netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFINFO, GFP_ATOMIC);
    }

    +/* Maximum length of prefix_cacheinfo attributes */
    +#define INET6_PREFIX_RTA_SPACE \
    + RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \
    + RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */
    +
    static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
    struct prefix_info *pinfo, u32 pid, u32 seq,
    int event, unsigned int flags)
    @@ -3296,7 +3325,7 @@ static void inet6_prefix_notify(int even
    struct prefix_info *pinfo)
    {
    struct sk_buff *skb;
    - int size = NLMSG_SPACE(sizeof(struct prefixmsg)+128);
    + int size = NLMSG_SPACE(sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE);

    skb = alloc_skb(size, GFP_ATOMIC);
    if (!skb) {
    diff --git a/net/sctp/input.c b/net/sctp/input.c
    index 1662f9c..70d6606 100644
    --- a/net/sctp/input.c
    +++ b/net/sctp/input.c
    @@ -170,7 +170,8 @@ int sctp_rcv(struct sk_buff *skb)
    * IP broadcast addresses cannot be used in an SCTP transport
    * address."
    */
    - if (!af->addr_valid(&src, NULL) || !af->addr_valid(&dest, NULL))
    + if (!af->addr_valid(&src, NULL, skb) ||
    + !af->addr_valid(&dest, NULL, skb))
    goto discard_it;

    asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
    diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
    index c20d282..8ef0807 100644
    --- a/net/sctp/ipv6.c
    +++ b/net/sctp/ipv6.c
    @@ -523,7 +523,9 @@ static int sctp_v6_available(union sctp_
    * Return 0 - If the address is a non-unicast or an illegal address.
    * Return 1 - If the address is a unicast.
    */
    -static int sctp_v6_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
    +static int sctp_v6_addr_valid(union sctp_addr *addr,
    + struct sctp_sock *sp,
    + const struct sk_buff *skb)
    {
    int ret = ipv6_addr_type(&addr->v6.sin6_addr);

    @@ -537,7 +539,7 @@ static int sctp_v6_addr_valid(union sctp
    if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
    return 0;
    sctp_v6_map_v4(addr);
    - return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp);
    + return sctp_get_af_specific(AF_INET)->addr_valid(addr, sp, skb);
    }

    /* Is this a non-unicast address */
    diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
    index f148f95..e5faa35 100644
    --- a/net/sctp/outqueue.c
    +++ b/net/sctp/outqueue.c
    @@ -1262,6 +1262,7 @@ #endif /* SCTP_DEBUG */
    if (!tchunk->tsn_gap_acked &&
    !tchunk->resent &&
    tchunk->rtt_in_progress) {
    + tchunk->rtt_in_progress = 0;
    rtt = jiffies - tchunk->sent_at;
    sctp_transport_update_rto(transport,
    rtt);
    diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
    index 2088aa9..816c033 100644
    --- a/net/sctp/protocol.c
    +++ b/net/sctp/protocol.c
    @@ -365,12 +365,18 @@ static int sctp_v4_is_any(const union sc
    * Return 0 - If the address is a non-unicast or an illegal address.
    * Return 1 - If the address is a unicast.
    */
    -static int sctp_v4_addr_valid(union sctp_addr *addr, struct sctp_sock *sp)
    +static int sctp_v4_addr_valid(union sctp_addr *addr,
    + struct sctp_sock *sp,
    + const struct sk_buff *skb)
    {
    /* Is this a non-unicast address or a unusable SCTP address? */
    if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
    return 0;

    + /* Is this a broadcast address? */
    + if (skb && ((struct rtable *)skb->dst)->rt_flags & RTCF_BROADCAST)
    + return 0;
    +
    return 1;
    }

    diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
    index 8bc2792..9e58144 100644
    --- a/net/sctp/sm_statefuns.c
    +++ b/net/sctp/sm_statefuns.c
    @@ -5293,10 +5293,18 @@ static int sctp_eat_data(const struct sc
    * seems a bit troublesome in that frag_point varies based on
    * PMTU. In cases, such as loopback, this might be a rather
    * large spill over.
    + * NOTE: If we have a full receive buffer here, we only renege if
    + * our receiver can still make progress without the tsn being
    + * received. We do this because in the event that the associations
    + * receive queue is empty we are filling a leading gap, and since
    + * reneging moves the gap to the end of the tsn stream, we are likely
    + * to stall again very shortly. Avoiding the renege when we fill a
    + * leading gap is a good heuristic for avoiding such steady state
    + * stalls.
    */
    if (!asoc->rwnd || asoc->rwnd_over ||
    (datalen > asoc->rwnd + asoc->frag_point) ||
    - rcvbuf_over) {
    + (rcvbuf_over && (!skb_queue_len(&sk->sk_receive_queue)))) {

    /* If this is the next TSN, consider reneging to make
    * room. Note: Playing nice with a confused sender. A
    diff --git a/net/sctp/socket.c b/net/sctp/socket.c
    index 174d4d3..b811691 100644
    --- a/net/sctp/socket.c
    +++ b/net/sctp/socket.c
    @@ -172,7 +172,7 @@ static inline int sctp_verify_addr(struc
    return -EINVAL;

    /* Is this a valid SCTP address? */
    - if (!af->addr_valid(addr, sctp_sk(sk)))
    + if (!af->addr_valid(addr, sctp_sk(sk), NULL))
    return -EINVAL;

    if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr)))
    @@ -2530,8 +2530,32 @@ static int sctp_setsockopt_associnfo(str

    /* Set the values to the specific association */
    if (asoc) {
    - if (assocparams.sasoc_asocmaxrxt != 0)
    + if (assocparams.sasoc_asocmaxrxt != 0) {
    + __u32 path_sum = 0;
    + int paths = 0;
    + struct list_head *pos;
    + struct sctp_transport *peer_addr;
    +
    + list_for_each(pos, &asoc->peer.transport_addr_list) {
    + peer_addr = list_entry(pos,
    + struct sctp_transport,
    + transports);
    + path_sum += peer_addr->pathmaxrxt;
    + paths++;
    + }
    +
    + /* Only validate asocmaxrxt if we have more then
    + * one path/transport. We do this because path
    + * retransmissions are only counted when we have more
    + * then one path.
    + */
    + if (paths > 1 &&
    + assocparams.sasoc_asocmaxrxt > path_sum)
    + return -EINVAL;
    +
    asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
    + }
    +
    if (assocparams.sasoc_cookie_life != 0) {
    asoc->cookie_life.tv_sec =
    assocparams.sasoc_cookie_life / 1000;
    diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
    index ba97f97..ee23678 100644
    --- a/net/sctp/ulpevent.c
    +++ b/net/sctp/ulpevent.c
    @@ -51,6 +51,8 @@ #include <net/sctp/sm.h>
    static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event,
    struct sctp_association *asoc);
    static void sctp_ulpevent_release_data(struct sctp_ulpevent *event);
    +static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event);
    +

    /* Initialize an ULP event from an given skb. */
    SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
    @@ -883,6 +885,7 @@ static void sctp_ulpevent_receive_data(s
    static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
    {
    struct sk_buff *skb, *frag;
    + unsigned int len;

    /* Current stack structures assume that the rcv buffer is
    * per socket. For UDP style sockets this is not true as
    @@ -892,7 +895,30 @@ static void sctp_ulpevent_release_data(s
    */

    skb = sctp_event2skb(event);
    - sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb));
    + len = skb->len;
    +
    + if (!skb->data_len)
    + goto done;
    +
    + /* Don't forget the fragments. */
    + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
    + /* NOTE: skb_shinfos are recursive. Although IP returns
    + * skb's with only 1 level of fragments, SCTP reassembly can
    + * increase the levels.
    + */
    + sctp_ulpevent_release_frag_data(sctp_skb2event(frag));
    + }
    +
    +done:
    + sctp_assoc_rwnd_increase(event->asoc, len);
    + sctp_ulpevent_release_owner(event);
    +}
    +
    +static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event)
    +{
    + struct sk_buff *skb, *frag;
    +
    + skb = sctp_event2skb(event);

    if (!skb->data_len)
    goto done;
    @@ -903,7 +929,7 @@ static void sctp_ulpevent_release_data(s
    * skb's with only 1 level of fragments, SCTP reassembly can
    * increase the levels.
    */
    - sctp_ulpevent_release_data(sctp_skb2event(frag));
    + sctp_ulpevent_release_frag_data(sctp_skb2event(frag));
    }

    done:
    diff --git a/usr/Makefile b/usr/Makefile
    index 19d74e6..e938242 100644
    --- a/usr/Makefile
    +++ b/usr/Makefile
    @@ -21,8 +21,7 @@ ramfs-input := $(if $(filter-out "",$(CO
    $(CONFIG_INITRAMFS_SOURCE),-d)
    ramfs-args := \
    $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
    - $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) \
    - $(ramfs-input)
    + $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))

    # .initramfs_data.cpio.gz.d is used to identify all files included
    # in initramfs and to detect if any files are added/removed.
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2006-06-30 02:51    [W:0.054 / U:31.792 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site