diff --git a/[refs] b/[refs] index e9ebb6ed14a2..394424032b13 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 80c72579f74fcfcd63e27c5e317091cb35bb1f12 +refs/heads/master: a710ce08585e920740ffc84c7f3c82f4081169cf diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index a606504678bd..a33583f3b0e7 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -514,7 +514,7 @@ void __init htab_initialize(void) #undef KB #undef MB -void htab_initialize_secondary(void) +void __init htab_initialize_secondary(void) { if (!platform_is_lpar()) mtspr(SPRN_SDR1, _SDR1); diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index 346c19a949fd..38938d2e63aa 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -85,9 +85,19 @@ SECTIONS } _end = . ; PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } - - STABS_DEBUG - - DWARF_DEBUG } diff --git a/trunk/arch/sparc64/kernel/vmlinux.lds.S b/trunk/arch/sparc64/kernel/vmlinux.lds.S index 467d13a0d5c1..2af0cf0a8640 100644 --- a/trunk/arch/sparc64/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc64/kernel/vmlinux.lds.S @@ -90,9 +90,19 @@ SECTIONS } _end = . ; PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } - - STABS_DEBUG - - DWARF_DEBUG } diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index 29a9e3f43763..37517d49c4ae 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -116,16 +116,16 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); if (exit_with == 2) - printf("check_ptrace : child exited with status 2. " + printk("check_ptrace : child exited with status 2. " "Serious trouble happening! Try updating your " "host skas patch!\nDisabling SYSEMU support."); - printf("check_ptrace : child exited with exitcode %d, while " + printk("check_ptrace : child exited with exitcode %d, while " "expecting %d; status 0x%x", exit_with, exitcode, status); if (mustpanic) panic("\n"); else - printf("\n"); + printk("\n"); ret = -1; } @@ -183,7 +183,7 @@ static void __init check_sysemu(void) void *stack; int pid, n, status, count=0; - printf("Checking syscall emulation patch for ptrace..."); + printk("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; pid = start_ptraced_child(&stack); @@ -207,10 +207,10 @@ static void __init check_sysemu(void) goto fail_stopped; sysemu_supported = 1; - printf("OK\n"); + printk("OK\n"); set_using_sysemu(!force_sysemu_disabled); - printf("Checking advanced syscall emulation patch for ptrace..."); + printk("Checking advanced syscall emulation patch for ptrace..."); pid = start_ptraced_child(&stack); if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, @@ -246,7 +246,7 @@ static void __init check_sysemu(void) goto fail_stopped; sysemu_supported = 2; - printf("OK\n"); + printk("OK\n"); if ( !force_sysemu_disabled ) set_using_sysemu(sysemu_supported); @@ -255,7 +255,7 @@ static void __init check_sysemu(void) fail: stop_ptraced_child(pid, stack, 1, 0); fail_stopped: - printf("missing\n"); + printk("missing\n"); } static void __init check_ptrace(void) @@ -263,7 +263,7 @@ static void __init check_ptrace(void) void *stack; int pid, syscall, n, status; - printf("Checking that ptrace can change system call numbers..."); + printk("Checking that ptrace can change system call numbers..."); pid = start_ptraced_child(&stack); if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) @@ -292,7 +292,7 @@ static void __init check_ptrace(void) } } stop_ptraced_child(pid, stack, 0, 1); - printf("OK\n"); + printk("OK\n"); check_sysemu(); } @@ -472,8 +472,6 @@ int can_do_skas(void) int have_devanon = 0; -/* Runs on boot kernel stack - already safe to use printk. */ - void check_devanon(void) { int fd; diff --git a/trunk/arch/um/os-Linux/user_syms.c b/trunk/arch/um/os-Linux/user_syms.c index 8da6ab31152a..56d3f870926b 100644 --- a/trunk/arch/um/os-Linux/user_syms.c +++ b/trunk/arch/um/os-Linux/user_syms.c @@ -34,11 +34,6 @@ EXPORT_SYMBOL(strstr); int sym(void); \ EXPORT_SYMBOL(sym); -extern void readdir64(void) __attribute__((weak)); -EXPORT_SYMBOL(readdir64); -extern void truncate64(void) __attribute__((weak)); -EXPORT_SYMBOL(truncate64); - #ifdef SUBARCH_i386 EXPORT_SYMBOL(vsyscall_ehdr); EXPORT_SYMBOL(vsyscall_end); diff --git a/trunk/arch/um/sys-i386/Makefile b/trunk/arch/um/sys-i386/Makefile index f5fd5b0156d0..150059dbee12 100644 --- a/trunk/arch/um/sys-i386/Makefile +++ b/trunk/arch/um/sys-i386/Makefile @@ -1,8 +1,6 @@ -obj-y := bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ - sys_call_table.o - -obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o +obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ + ptrace_user.o semaphore.o signal.o sigcontext.o stub.o stub_segv.o \ + syscalls.o sysrq.o sys_call_table.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_MODULES) += module.o diff --git a/trunk/arch/um/sys-x86_64/Makefile b/trunk/arch/um/sys-x86_64/Makefile index a351091fbd99..00b2025427df 100644 --- a/trunk/arch/um/sys-x86_64/Makefile +++ b/trunk/arch/um/sys-x86_64/Makefile @@ -6,9 +6,8 @@ #XXX: why into lib-y? lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \ - ptrace.o ptrace_user.o sigcontext.o signal.o syscalls.o \ - syscall_table.o sysrq.o thunk.o -lib-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o + ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \ + stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o obj-y := ksyms.o obj-$(CONFIG_MODULES) += module.o um_module.o diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index c016dfe84784..286f6a624c3a 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -348,7 +348,7 @@ size_zones(unsigned long *z, unsigned long *h, } /* Compute holes */ - w = start_pfn; + w = 0; for (i = 0; i < MAX_NR_ZONES; i++) { unsigned long s = w; w += z[i]; diff --git a/trunk/drivers/char/drm/radeon_cp.c b/trunk/drivers/char/drm/radeon_cp.c index b517ae515801..501e557cbc86 100644 --- a/trunk/drivers/char/drm/radeon_cp.c +++ b/trunk/drivers/char/drm/radeon_cp.c @@ -1312,7 +1312,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private; - unsigned int mem_size, aper_size; + unsigned int mem_size; DRM_DEBUG("\n"); @@ -1527,9 +1527,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) mem_size = RADEON_READ(RADEON_CONFIG_MEMSIZE); if (mem_size == 0) mem_size = 0x800000; - aper_size = max(RADEON_READ(RADEON_CONFIG_APER_SIZE), mem_size); - - dev_priv->gart_vm_start = dev_priv->fb_location + aper_size; + dev_priv->gart_vm_start = dev_priv->fb_location + mem_size; #if __OS_HAS_AGP if (!dev_priv->is_pci) diff --git a/trunk/drivers/char/vc_screen.c b/trunk/drivers/char/vc_screen.c index 3c1dafaa3441..f66c7ad6fd38 100644 --- a/trunk/drivers/char/vc_screen.c +++ b/trunk/drivers/char/vc_screen.c @@ -419,7 +419,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) while (this_round > 1) { unsigned short w; - w = get_unaligned(((unsigned short *)con_buf0)); + w = get_unaligned(((const unsigned short *)con_buf0)); vcs_scr_writew(vc, w, org++); con_buf0 += 2; this_round -= 2; diff --git a/trunk/drivers/input/mouse/sermouse.c b/trunk/drivers/input/mouse/sermouse.c index 2f9a04ae725f..4bf584364d28 100644 --- a/trunk/drivers/input/mouse/sermouse.c +++ b/trunk/drivers/input/mouse/sermouse.c @@ -95,7 +95,7 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data, st input_sync(dev); - if (++sermouse->count == 5) + if (++sermouse->count == (5 - ((sermouse->type == SERIO_SUN) << 1))) sermouse->count = 0; } diff --git a/trunk/drivers/media/video/saa7134/Kconfig b/trunk/drivers/media/video/saa7134/Kconfig index 86e1bb391a4e..c0f604a6fe42 100644 --- a/trunk/drivers/media/video/saa7134/Kconfig +++ b/trunk/drivers/media/video/saa7134/Kconfig @@ -14,7 +14,7 @@ config VIDEO_SAA7134 config VIDEO_SAA7134_ALSA tristate "Philips SAA7134 DMA audio support" - depends on VIDEO_SAA7134 && SND + depends on VIDEO_SAA7134 && SOUND && SND && (!VIDEO_SAA7134_OSS || VIDEO_SAA7134_OSS = m) select SND_PCM_OSS ---help--- This is a video4linux driver for direct (DMA) audio in @@ -25,7 +25,7 @@ config VIDEO_SAA7134_ALSA config VIDEO_SAA7134_OSS tristate "Philips SAA7134 DMA audio support (OSS, DEPRECATED)" - depends on VIDEO_SAA7134 && SOUND_PRIME && (!VIDEO_SAA7134_ALSA || (VIDEO_SAA7134_ALSA=m && m)) + depends on VIDEO_SAA7134 && SOUND_PRIME && (!VIDEO_SAA7134_ALSA || VIDEO_SAA7134_ALSA = m) ---help--- This is a video4linux driver for direct (DMA) audio in Philips SAA713x based TV cards using OSS diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index 1c6d328165bb..50430f79f8cf 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -524,6 +524,9 @@ static int get_filter(void __user *arg, struct sock_filter **p) if (copy_from_user(&uprog, arg, sizeof(uprog))) return -EFAULT; + if (uprog.len > BPF_MAXINSNS) + return -EINVAL; + if (!uprog.len) { *p = NULL; return 0; diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 2fc9893d69e1..cefb0c08a68d 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.47" -#define DRV_MODULE_RELDATE "Dec 28, 2005" +#define DRV_MODULE_VERSION "3.46" +#define DRV_MODULE_RELDATE "Dec 19, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -7151,13 +7151,8 @@ do { p = (u32 *)(orig_p + (reg)); \ GET_REG32_LOOP(BUFMGR_MODE, 0x58); GET_REG32_LOOP(RDMAC_MODE, 0x08); GET_REG32_LOOP(WDMAC_MODE, 0x08); - GET_REG32_1(RX_CPU_MODE); - GET_REG32_1(RX_CPU_STATE); - GET_REG32_1(RX_CPU_PGMCTR); - GET_REG32_1(RX_CPU_HWBKPT); - GET_REG32_1(TX_CPU_MODE); - GET_REG32_1(TX_CPU_STATE); - GET_REG32_1(TX_CPU_PGMCTR); + GET_REG32_LOOP(RX_CPU_BASE, 0x280); + GET_REG32_LOOP(TX_CPU_BASE, 0x280); GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110); GET_REG32_LOOP(FTQ_RESET, 0x120); GET_REG32_LOOP(MSGINT_MODE, 0x0c); diff --git a/trunk/drivers/net/tg3.h b/trunk/drivers/net/tg3.h index 890e1635996b..94dbcf3537ec 100644 --- a/trunk/drivers/net/tg3.h +++ b/trunk/drivers/net/tg3.h @@ -1124,14 +1124,7 @@ /* 0x280 --> 0x400 unused */ #define RX_CPU_BASE 0x00005000 -#define RX_CPU_MODE 0x00005000 -#define RX_CPU_STATE 0x00005004 -#define RX_CPU_PGMCTR 0x0000501c -#define RX_CPU_HWBKPT 0x00005034 #define TX_CPU_BASE 0x00005400 -#define TX_CPU_MODE 0x00005400 -#define TX_CPU_STATE 0x00005404 -#define TX_CPU_PGMCTR 0x0000541c /* Mailboxes */ #define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */ diff --git a/trunk/drivers/serial/amba-pl011.c b/trunk/drivers/serial/amba-pl011.c index 89d7bd3eaee3..d84476ee6592 100644 --- a/trunk/drivers/serial/amba-pl011.c +++ b/trunk/drivers/serial/amba-pl011.c @@ -160,7 +160,7 @@ pl011_rx_chars(struct uart_amba_port *uap) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&uap->port, ch, regs)) + if (uart_handle_sysrq_char(&uap->port, ch & 255, regs)) goto ignore_char; uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); diff --git a/trunk/drivers/usb/input/aiptek.c b/trunk/drivers/usb/input/aiptek.c index 0e2505c073db..1c3b472a3bca 100644 --- a/trunk/drivers/usb/input/aiptek.c +++ b/trunk/drivers/usb/input/aiptek.c @@ -2103,7 +2103,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) * values. */ input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0); - input_set_abs_params(inputdev, ABS_Y, 0, 2249, 0, 0); + input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0); input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0); input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); diff --git a/trunk/fs/hostfs/hostfs_kern.c b/trunk/fs/hostfs/hostfs_kern.c index b3ad0bd0312f..4684eb7d48c6 100644 --- a/trunk/fs/hostfs/hostfs_kern.c +++ b/trunk/fs/hostfs/hostfs_kern.c @@ -501,16 +501,11 @@ int hostfs_commit_write(struct file *file, struct page *page, unsigned from, long long start; int err = 0; - start = (((long long) page->index) << PAGE_CACHE_SHIFT) + from; + start = (long long) (page->index << PAGE_CACHE_SHIFT) + from; buffer = kmap(page); err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, to - from); if(err > 0) err = 0; - - /* Actually, if !err, write_file has added to-from to start, so, despite - * the appearance, we are comparing i_size against the _last_ written - * location, as we should. */ - if(!err && (start > inode->i_size)) inode->i_size = start; @@ -915,8 +910,10 @@ static struct inode_operations hostfs_dir_iops = { int hostfs_link_readpage(struct file *file, struct page *page) { char *buffer, *name; + long long start; int err; + start = page->index << PAGE_CACHE_SHIFT; buffer = kmap(page); name = inode_name(page->mapping->host, 0); if(name == NULL) return(-ENOMEM); diff --git a/trunk/include/net/if_inet6.h b/trunk/include/net/if_inet6.h index eb8afe3499a9..d8234f9bd4c4 100644 --- a/trunk/include/net/if_inet6.h +++ b/trunk/include/net/if_inet6.h @@ -83,7 +83,6 @@ struct ipv6_mc_socklist struct in6_addr addr; int ifindex; struct ipv6_mc_socklist *next; - rwlock_t sflock; unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ struct ip6_sf_socklist *sflist; }; diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index 23422bd53a5e..43a0b35dfe6f 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -369,7 +369,6 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb)) goto inhdr_error; - nf_bridge_put(skb->nf_bridge); if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) return NF_DROP; setup_pre_routing(skb); @@ -453,7 +452,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, skb->ip_summed = CHECKSUM_NONE; } - nf_bridge_put(skb->nf_bridge); if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) return NF_DROP; setup_pre_routing(skb); diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index 3a10e0bc90e8..2841bfce29d6 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -293,7 +293,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) struct sock_filter *ftest; int pc; - if (flen == 0 || flen > BPF_MAXINSNS) + if (((unsigned int)flen >= (~0U / sizeof(struct sock_filter))) || flen == 0) return -EINVAL; /* check the filter code now */ @@ -360,7 +360,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) int err; /* Make sure new filter is there and in the right amounts. */ - if (fprog->filter == NULL) + if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS) return -EINVAL; fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL); diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index a60585fd85ad..2a6439e3c91c 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -2467,9 +2467,11 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) return; } - if (!(idev->if_flags & IF_READY)) { + if (idev->if_flags & IF_READY) { + addrconf_dad_kick(ifp); + spin_unlock_bh(&ifp->lock); + } else { spin_unlock_bh(&ifp->lock); - read_unlock_bh(&idev->lock); /* * If the defice is not ready: * - keep it tentative if it is a permanent address. @@ -2477,10 +2479,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) */ in6_ifa_hold(ifp); addrconf_dad_stop(ifp); - return; } - addrconf_dad_kick(ifp); - spin_unlock_bh(&ifp->lock); out: read_unlock_bh(&idev->lock); } diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index f829a4ad3ccc..fd939da090c4 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -170,7 +170,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) -#define IPV6_MLD_MAX_MSF 64 +#define IPV6_MLD_MAX_MSF 10 int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF; @@ -224,7 +224,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) mc_lst->ifindex = dev->ifindex; mc_lst->sfmode = MCAST_EXCLUDE; - mc_lst->sflock = RW_LOCK_UNLOCKED; mc_lst->sflist = NULL; /* @@ -361,7 +360,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk, struct ip6_sf_socklist *psl; int i, j, rv; int leavegroup = 0; - int pmclocked = 0; int err; if (pgsr->gsr_group.ss_family != AF_INET6 || @@ -405,9 +403,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk, pmc->sfmode = omode; } - write_lock_bh(&pmc->sflock); - pmclocked = 1; - psl = pmc->sflist; if (!add) { if (!psl) @@ -480,8 +475,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk, /* update the interface list */ ip6_mc_add_src(idev, group, omode, 1, source, 1); done: - if (pmclocked) - write_unlock_bh(&pmc->sflock); read_unlock_bh(&ipv6_sk_mc_lock); read_unlock_bh(&idev->lock); in6_dev_put(idev); @@ -517,8 +510,6 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) dev = idev->dev; err = 0; - read_lock_bh(&ipv6_sk_mc_lock); - if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) { leavegroup = 1; goto done; @@ -558,8 +549,6 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) newpsl = NULL; (void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0); } - - write_lock_bh(&pmc->sflock); psl = pmc->sflist; if (psl) { (void) ip6_mc_del_src(idev, group, pmc->sfmode, @@ -569,10 +558,8 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); pmc->sflist = newpsl; pmc->sfmode = gsf->gf_fmode; - write_unlock_bh(&pmc->sflock); err = 0; done: - read_unlock_bh(&ipv6_sk_mc_lock); read_unlock_bh(&idev->lock); in6_dev_put(idev); dev_put(dev); @@ -605,11 +592,6 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, dev = idev->dev; err = -EADDRNOTAVAIL; - /* - * changes to the ipv6_mc_list require the socket lock and - * a read lock on ip6_sk_mc_lock. We have the socket lock, - * so reading the list is safe. - */ for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { if (pmc->ifindex != gsf->gf_interface) @@ -632,10 +614,6 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, copy_to_user(optval, gsf, GROUP_FILTER_SIZE(0))) { return -EFAULT; } - /* changes to psl require the socket lock, a read lock on - * on ipv6_sk_mc_lock and a write lock on pmc->sflock. We - * have the socket lock, so reading here is safe. - */ for (i=0; isflock); psl = mc->sflist; if (!psl) { rv = mc->sfmode == MCAST_EXCLUDE; @@ -688,7 +665,6 @@ int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) rv = 0; } - read_unlock(&mc->sflock); read_unlock(&ipv6_sk_mc_lock); return rv; @@ -1092,8 +1068,7 @@ static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime) ma->mca_flags |= MAF_TIMER_RUNNING; } -/* mark EXCLUDE-mode sources */ -static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, +static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, struct in6_addr *srcs) { struct ip6_sf_list *psf; @@ -1103,53 +1078,13 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { if (scount == nsrcs) break; - for (i=0; imca_sfcount[MCAST_INCLUDE] || - pmc->mca_sfcount[MCAST_EXCLUDE] != - psf->sf_count[MCAST_EXCLUDE]) - continue; - if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) { - scount++; - break; - } - } - } - pmc->mca_flags &= ~MAF_GSQUERY; - if (scount == nsrcs) /* all sources excluded */ - return 0; - return 1; -} - -static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, - struct in6_addr *srcs) -{ - struct ip6_sf_list *psf; - int i, scount; - - if (pmc->mca_sfmode == MCAST_EXCLUDE) - return mld_xmarksources(pmc, nsrcs, srcs); - - /* mark INCLUDE-mode sources */ - - scount = 0; - for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { - if (scount == nsrcs) - break; - for (i=0; isf_addr)) { psf->sf_gsresp = 1; scount++; break; } - } - } - if (!scount) { - pmc->mca_flags &= ~MAF_GSQUERY; - return 0; } - pmc->mca_flags |= MAF_GSQUERY; - return 1; } int igmp6_event_query(struct sk_buff *skb) @@ -1232,7 +1167,7 @@ int igmp6_event_query(struct sk_buff *skb) /* mark sources to include, if group & source-specific */ if (mlh2->nsrcs != 0) { if (!pskb_may_pull(skb, srcs_offset + - ntohs(mlh2->nsrcs) * sizeof(struct in6_addr))) { + mlh2->nsrcs * sizeof(struct in6_addr))) { in6_dev_put(idev); return -EINVAL; } @@ -1268,9 +1203,10 @@ int igmp6_event_query(struct sk_buff *skb) else ma->mca_flags &= ~MAF_GSQUERY; } - if (!(ma->mca_flags & MAF_GSQUERY) || - mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs)) - igmp6_group_queried(ma, max_delay); + if (ma->mca_flags & MAF_GSQUERY) + mld_marksources(ma, ntohs(mlh2->nsrcs), + mlh2->srcs); + igmp6_group_queried(ma, max_delay); spin_unlock_bh(&ma->mca_lock); if (group_type != IPV6_ADDR_ANY) break; @@ -1345,18 +1281,7 @@ static int is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, case MLD2_MODE_IS_EXCLUDE: if (gdeleted || sdeleted) return 0; - if (!((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp)) { - if (pmc->mca_sfmode == MCAST_INCLUDE) - return 1; - /* don't include if this source is excluded - * in all filters - */ - if (psf->sf_count[MCAST_INCLUDE]) - return 0; - return pmc->mca_sfcount[MCAST_EXCLUDE] == - psf->sf_count[MCAST_EXCLUDE]; - } - return 0; + return !((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp); case MLD2_CHANGE_TO_INCLUDE: if (gdeleted || sdeleted) return 0; @@ -1525,7 +1450,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, struct mld2_report *pmr; struct mld2_grec *pgr = NULL; struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; - int scount, stotal, first, isquery, truncate; + int scount, first, isquery, truncate; if (pmc->mca_flags & MAF_NOREPORT) return skb; @@ -1535,13 +1460,25 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, truncate = type == MLD2_MODE_IS_EXCLUDE || type == MLD2_CHANGE_TO_EXCLUDE; - stotal = scount = 0; - psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources; - if (!*psf_list) - goto empty_source; - + if (!*psf_list) { + if (type == MLD2_ALLOW_NEW_SOURCES || + type == MLD2_BLOCK_OLD_SOURCES) + return skb; + if (pmc->mca_crcount || isquery) { + /* make sure we have room for group header and at + * least one source. + */ + if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)+ + sizeof(struct in6_addr)) { + mld_sendpack(skb); + skb = NULL; /* add_grhead will get a new one */ + } + skb = add_grhead(skb, pmc, type, &pgr); + } + return skb; + } pmr = skb ? (struct mld2_report *)skb->h.raw : NULL; /* EX and TO_EX get a fresh packet, if needed */ @@ -1554,6 +1491,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, } } first = 1; + scount = 0; psf_prev = NULL; for (psf=*psf_list; psf; psf=psf_next) { struct in6_addr *psrc; @@ -1587,7 +1525,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, } psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc)); *psrc = psf->sf_addr; - scount++; stotal++; + scount++; if ((type == MLD2_ALLOW_NEW_SOURCES || type == MLD2_BLOCK_OLD_SOURCES) && psf->sf_crcount) { psf->sf_crcount--; @@ -1602,21 +1540,6 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, } psf_prev = psf; } - -empty_source: - if (!stotal) { - if (type == MLD2_ALLOW_NEW_SOURCES || - type == MLD2_BLOCK_OLD_SOURCES) - return skb; - if (pmc->mca_crcount || isquery) { - /* make sure we have room for group header */ - if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)) { - mld_sendpack(skb); - skb = NULL; /* add_grhead will get a new one */ - } - skb = add_grhead(skb, pmc, type, &pgr); - } - } if (pgr) pgr->grec_nsrcs = htons(scount); @@ -1698,11 +1621,11 @@ static void mld_send_cr(struct inet6_dev *idev) skb = add_grec(skb, pmc, dtype, 1, 1); } if (pmc->mca_crcount) { + pmc->mca_crcount--; if (pmc->mca_sfmode == MCAST_EXCLUDE) { type = MLD2_CHANGE_TO_INCLUDE; skb = add_grec(skb, pmc, type, 1, 0); } - pmc->mca_crcount--; if (pmc->mca_crcount == 0) { mld_clear_zeros(&pmc->mca_tomb); mld_clear_zeros(&pmc->mca_sources); @@ -1736,12 +1659,12 @@ static void mld_send_cr(struct inet6_dev *idev) /* filter mode changes */ if (pmc->mca_crcount) { + pmc->mca_crcount--; if (pmc->mca_sfmode == MCAST_EXCLUDE) type = MLD2_CHANGE_TO_EXCLUDE; else type = MLD2_CHANGE_TO_INCLUDE; skb = add_grec(skb, pmc, type, 0, 0); - pmc->mca_crcount--; } spin_unlock_bh(&pmc->mca_lock); } @@ -2100,9 +2023,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, { int err; - /* callers have the socket lock and a write lock on ipv6_sk_mc_lock, - * so no other readers or writers of iml or its sflist - */ if (iml->sflist == 0) { /* any-source empty exclude case */ return ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0);